aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorEugene Sandulenko2018-05-26 20:34:06 +0200
committerEugene Sandulenko2019-11-13 22:07:08 +0100
commitd1af98a842f0a237a1afd184e79ae237318bb34e (patch)
tree5b65efbc4df4fdf1daa3dba689aca8a21a25b477 /engines
parent541b2e473a28eee8b591065529a4b37616317d0c (diff)
downloadscummvm-rg350-d1af98a842f0a237a1afd184e79ae237318bb34e.tar.gz
scummvm-rg350-d1af98a842f0a237a1afd184e79ae237318bb34e.tar.bz2
scummvm-rg350-d1af98a842f0a237a1afd184e79ae237318bb34e.zip
GRIFFON: Added original code from GCW0 port by Dmitry Smagin
Diffstat (limited to 'engines')
-rw-r--r--engines/griffon/config.cpp123
-rw-r--r--engines/griffon/config.h40
-rw-r--r--engines/griffon/engine.cpp8234
-rw-r--r--engines/griffon/engine.h254
-rw-r--r--engines/griffon/state.cpp256
-rw-r--r--engines/griffon/state.h27
6 files changed, 8934 insertions, 0 deletions
diff --git a/engines/griffon/config.cpp b/engines/griffon/config.cpp
new file mode 100644
index 0000000000..3cfc7918db
--- /dev/null
+++ b/engines/griffon/config.cpp
@@ -0,0 +1,123 @@
+/*
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <sys/stat.h>
+
+#include <SDL/SDL.h>
+
+#include "config.h"
+
+ CONFIG config = {
+ 320, 240, 16, 0, 0, 0, 1, 127, 1, 127
+};
+
+char config_ini[64] = "config.ini";
+
+#define PRINT(A,B) \
+do { \
+ char line[256]; \
+ sprintf(line, A "\n", B); \
+ fputs(line, fp); \
+} while(0)
+
+#define INPUT(A, B) \
+do { \
+ char line[256]; \
+ fgets(line, sizeof(line), fp); \
+ sscanf(line, A, B); \
+} while(0)
+
+void config_load(CONFIG *config)
+{
+ char line[128];
+ char arg[128];
+ FILE *fp;
+
+ fp = fopen(config_ini, "r");
+ if(fp) {
+ while(fgets(line, sizeof(line), fp) != NULL) {
+ sscanf(line, "%s", arg); // eliminate eol and eof by this
+
+ if(strcmp(arg, "SCR_WIDTH:") == 0) {
+ fgets(line, sizeof(line), fp);
+ sscanf(line, "%i", &config->scr_width);
+ } else if(strcmp(arg, "SCR_HEIGHT:") == 0) {
+ fgets(line, sizeof(line), fp);
+ sscanf(line, "%i", &config->scr_height);
+ } else if(strcmp(arg, "SCR_BITS:") == 0) {
+ fgets(line, sizeof(line), fp);
+ sscanf(line, "%i", &config->scr_bpp);
+ } else if(strcmp(arg, "HWACCEL:YES") == 0) {
+ config->hwaccel = SDL_HWACCEL;
+ } else if(strcmp(arg, "HWACCEL:NO") == 0) {
+ config->hwaccel = 0;
+ } else if(strcmp(arg, "HWSURFACE:YES") == 0) {
+ config->hwsurface = SDL_HWSURFACE;
+ } else if(strcmp(arg, "HWSURFACE:NO") == 0) {
+ config->hwsurface = 0;
+ } else if(strcmp(arg, "FULLSCREEN:YES") == 0) {
+ config->fullscreen = SDL_FULLSCREEN;
+ } else if(strcmp(arg, "FULLSCREEN:NO") == 0) {
+ config->fullscreen = 0;
+ } else if(strcmp(arg, "MUSIC:YES") == 0) {
+ config->music = 1;
+ } else if(strcmp(arg, "MUSIC:NO") == 0) {
+ config->music = 0;
+ } else if(strcmp(arg, "SNDEFFECTS:YES") == 0) {
+ config->effects = 1;
+ } else if(strcmp(arg, "SNDEFFECTS:NO") == 0) {
+ config->effects = 0;
+ } else if(strcmp(arg, "opmusicvol:") == 0) {
+ fgets(line, sizeof(line), fp);
+ sscanf(line, "%i", &config->musicvol);
+ } else if(strcmp(arg, "opeffectsvol:") == 0) {
+ fgets(line, sizeof(line), fp);
+ sscanf(line, "%i", &config->effectsvol);
+ }
+ }
+
+ fclose(fp);
+ }
+}
+
+void config_save(CONFIG *config)
+{
+ FILE *fp = fopen(config_ini, "w");
+
+ if(fp) {
+ PRINT("%s", "SCR_WIDTH:");
+ PRINT("%i", config->scr_width);
+ PRINT("%s", "SCR_HEIGHT:");
+ PRINT("%i", config->scr_height);
+ PRINT("%s", "SCR_BITS:");
+ PRINT("%i", config->scr_bpp);
+ PRINT("%s", config->hwaccel ? "HWACCEL:YES" : "HWACCEL:NO");
+ PRINT("%s", config->hwsurface ? "HWSURFACE:YES" : "HWSURFACE:NO");
+ PRINT("%s", config->fullscreen ? "FULLSCREEN:YES" : "FULLSCREEN:NO");
+ PRINT("%s", config->music ? "MUSIC:YES" : "MUSIC:NO");
+ PRINT("%s", config->effects ? "SNDEFFECTS:YES" : "SNDEFFECTS:NO");
+ PRINT("%s", "opmusicvol:");
+ PRINT("%i", config->musicvol);
+ PRINT("%s", "opeffectsvol:");
+ PRINT("%i", config->effectsvol);
+ fclose(fp);
+ }
+} \ No newline at end of file
diff --git a/engines/griffon/config.h b/engines/griffon/config.h
new file mode 100644
index 0000000000..f0af9b9ce4
--- /dev/null
+++ b/engines/griffon/config.h
@@ -0,0 +1,40 @@
+/*
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef _CONFIG_H_
+#define _CONFIG_H_
+
+typedef struct {
+ int scr_width;
+ int scr_height;
+ int scr_bpp;
+ int fullscreen;
+ int hwaccel;
+ int hwsurface;
+ int music;
+ int musicvol;
+ int effects;
+ int effectsvol;
+} CONFIG;
+
+extern CONFIG config;
+extern char config_ini[];
+
+void config_load(CONFIG *config);
+void config_save(CONFIG *config);
+
+#endif // _CONFIG_H_
diff --git a/engines/griffon/engine.cpp b/engines/griffon/engine.cpp
new file mode 100644
index 0000000000..6ced3674e4
--- /dev/null
+++ b/engines/griffon/engine.cpp
@@ -0,0 +1,8234 @@
+/*
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <sys/stat.h>
+
+#include <SDL/SDL.h>
+#include <SDL/SDL_image.h>
+#include <SDL/SDL_mixer.h>
+#include <SDL/SDL_rotozoom.h>
+
+#include "griffon.h"
+#include "config.h"
+#include "state.h"
+
+// memo
+/*
+ in game scripts
+ 2 - find master key
+ 3 - find crystal
+ 4 - find shield - obj 8
+ 5 - find sword - obj 9
+ 6 - regular key chest
+ 7 - blue flask
+ 8 - garden's master key
+ 9 - lightning bomb
+ 10 - blue flask chest
+ 11 - lightning chest
+ 12 - armour chest
+ 13 - citadel master key
+ 14 - end of game
+ 15 - get sword3
+ 16 - shield3
+ 17 - armour3
+ 20 key chest 1
+ 60-lever
+
+ monsters
+ 1 - baby dragon
+ 2 - one wing
+ 3 - boss 1
+ 4 - black knight
+ 5 - fire hydra
+ 6 - red dragon
+ 7 - priest
+ 8 - yellow fire dragon
+ 9 - two wing
+10 - dragon2
+11 - final boss
+12 - bat kitty
+
+ 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
+
+*/
+
+// system
+SDL_Surface *video, *videobuffer, *videobuffer2, *videobuffer3;
+SDL_Surface *titleimg, *titleimg2, *inventoryimg;
+SDL_Surface *logosimg, *theendimg;
+SDL_Event event;
+
+SDL_Surface *mapbg, *clipbg, *clipbg2;
+unsigned int clipsurround[4][4];
+int fullscreen;
+
+Uint8 *keys;
+float animspd;
+int rampdata[40][24];
+
+int curmap;
+SDL_Surface *fontchr[224][5]; // 256 - 32
+SDL_Surface *itemimg[21], *windowimg;
+SDL_Surface *spellimg;
+
+int itemselon, curitem, itemticks;
+float itemyloc;
+int selenemyon, curenemy, forcepause;
+int roomlock; // set to disable any room jumps while in the room
+int scriptflag[100][10], saveslot; // script, flag
+
+// timer related - move to local later
+int ticks, tickspassed, nextticks;
+float fp, fps, fpsr;
+int secsingame, secstart;
+
+extern char *story[48];
+SDL_Surface *mapimg[4];
+extern int invmap[4][7][13];
+extern char *story2[27];
+
+SDL_Rect rcSrc, rcDest;
+
+// -----------special case
+int dontdrawover; // used in map24 so that the candles dont draw over the boss, default set to 0
+
+// saveload info
+SDL_Surface *saveloadimg;
+
+
+// post info
+float postinfo[21][3];
+int nposts;
+
+// cloud info
+SDL_Surface *cloudimg;
+float clouddeg = 0;
+int cloudson;
+
+// spell info
+SPELLTYPE spellinfo[MAXSPELL];
+
+// player info
+int movingup, movingdown, movingleft, movingright;
+PLAYERTYPE player;
+int attacking;
+PLAYERTYPE playera;
+int asecstart;
+
+// tile info
+SDL_Surface *tiles[4];
+int tileinfo[3][40][24][3]; // maplayer, x, y, tiledata (tile, tilelayer)
+
+extern int elementmap[15][20];
+
+
+// animation info
+SDL_Surface *anims[100];
+ // id number 0&1 = players
+SDL_Surface *animsa[100];
+ // attack anims
+float playerattackofs[4][16][3];
+ // [dir] [frame] [x,y ofs, completed(0/1)]
+
+float floattext[MAXFLOAT][4]; // [id] [framesleft, x, y, col]
+char *floatstri[MAXFLOAT];
+float floaticon[MAXFLOAT][4]; // [id] [framesleft, x, y, ico]
+
+// special for animset2
+ANIMSET2TYPE animset2[7], animset9[7];
+
+// object info
+float objectframe[256][2];
+int lastobj;
+ // frame!, curframe
+int objectinfo[33][6];
+ // nframes,xtiles,ytiles,speed,type,script, update?
+int objecttile[33][9][3][3][2];
+ // [objnum] [frame] [x] [y] [tile/layer]
+int objmap[21][15];
+
+int objmapf[1000][21][15];
+ // [mapnum] x, y set to 1 to make this objmap spot stay at -1
+
+// trigger info
+int triggers[10000][9];
+ // [map#][index], [var]
+ // map#,x,y
+int triggerloc[320][240], ntriggers;
+
+// npc info
+NPCTYPE npcinfo[MAXNPC];
+int lastnpc;
+
+// music info
+Mix_Chunk *mgardens, *mgardens2, *mgardens3, *mgardens4, *mboss, *mmenu, *mendofgame;
+int menabled=1, musicchannel = -1, menuchannel = -1;
+int pgardens, pboss, ptown, pacademy, pcitadel;
+int loopseta = 0;
+
+Mix_Chunk *sfx[21];
+
+// room locks
+int roomlocks[201], saidlocked, canusekey, locktype, roomtounlock, saidjammed;
+// set to 1 for normal key, set to 2 for master, set to 0 if unlocked
+
+// ysort
+int ysort[2401], lasty, firsty;
+
+int pmenu;
+
+#undef main
+int main()
+{
+ sys_initialize();
+ game_showlogos();
+ game_main();
+
+ return 0;
+}
+
+// element tile locations
+int 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 }
+};
+
+char *story[48] = {
+ "The Griffon Legend",
+ "http://syn9.thehideoutgames.com/",
+ "",
+ "Programming/Graphics: Daniel Kennedy",
+ "Music/Sound effects: David Turner",
+ "",
+ "Porting to GCW-Zero: Dmitry Smagin",
+ "",
+ "",
+ "Story",
+ "Ever since I was a child",
+ "I remember being told the",
+ "Legend of the Griffon Knights,",
+ "who rid the world of the",
+ "Dragon Empire. These great",
+ "heroes inspired us to become",
+ "knights as well.",
+ " ",
+ "Now, 500 years after the war",
+ "ended, the Dragons have",
+ "returned. Cities are falling",
+ "from the lack of knights to",
+ "protect them.",
+ " ",
+ "We never saw it coming.",
+ " ",
+ "And now, here I am, making",
+ "my way into the lower town",
+ "of Fidelis, a small city on",
+ "the main continent. The rest",
+ "of my men have died over",
+ "the last couple days from",
+ "aerial attacks.",
+ " ",
+ "We believed we could find",
+ "shelter here, only to find",
+ "every last griffon dead,",
+ "the town burned to the ground,",
+ "and transformed into a garrison",
+ "for the Dragon forces.",
+ " ",
+ "In these dark times, I try to",
+ "draw strength from the stories",
+ "of those knights that risked",
+ "everything to protect their homeland,",
+ " ",
+ "and hope that I can die",
+ "with that honor as well."
+};
+
+char *story2[27] = {
+ "After the fall of Margrave Gradius,",
+ "All the dragons, struck with panic,",
+ "evacuated the city immediately.",
+ " ",
+ "It\'s funny how without a leader",
+ "everyone is so weak.",
+ " ",
+ " ",
+ "But yet another leader will rise,",
+ "and another city will fall.",
+ " ",
+ " ",
+ "I should return home to Asherton",
+ "It\'s time to leave this place",
+ "and cleanse this blood stained",
+ "life of mine.",
+ " ",
+ "No one should have to see as much",
+ "death as I have.",
+ " ",
+ " ",
+ "Before, I said that I wanted",
+ "to die an honorable death.",
+ " ",
+ "Now I say that I have lived an",
+ "honorable life,",
+ "and I am free to die as I please."
+};
+
+// map in inventory menu
+int invmap[4][7][13] = {
+ // map 0
+ {
+ {0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,43,44,45,46,0,0,0,0},
+ {0,0,0,0,0,42,0,0,0,0,0,0,0},
+ {0,0,0,0,3,2,0,0,0,0,0,0,0},
+ {0,0,0,0,4,5,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0}
+ },
+ // map 1
+ {
+ {0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,24,0,0,0,0,0,0,0,0,0},
+ {0,0,19,20,21,22,0,0,0,27,0,0,0},
+ {0,0,16,17,18,0,0,0,29,30,31,0,0},
+ {0,0,12,0,13,14,0,32,33,34,35,36,0},
+ {0,8,7,6,9,10,0,37,38,39,40,41,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0}
+ },
+ // map 2
+ {
+ {0,0,0,0,0,0,67,0,0,0,0,0,0},
+ {0,0,0,0,0,0,66,0,0,0,0,0,0},
+ {0,0,0,0,0,63,64,65,0,0,0,0,0},
+ {0,0,0,0,58,59,60,61,62,0,0,0,0},
+ {0,0,0,0,0,55,56,57,0,0,0,0,0},
+ {0,0,0,0,50,51,52,53,54,0,0,0,0},
+ {0,0,0,0,0,48,47,49,0,0,0,0,0}
+ },
+
+ // map 3
+ {
+ {0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,82,0,0,0,0,0,0,0,0,0},
+ {0,0,0,79,80,81,0,74,72,0,0,0,0},
+ {0,0,0,78,0,0,0,73,70,69,68,0,0},
+ {0,0,77,76,75,0,0,0,71,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0},
+ {0,0,0,0,0,0,0,0,0,0,0,0,0}
+ }
+};
+
+// HELPER MACRO ---------------------------------------------------------------
+#define PRINT(A,B) \
+do { \
+ char line[256]; \
+ sprintf(line, A "\n", B); \
+ fputs(line, fp); \
+} while(0)
+
+#define INPUT(A, B) \
+do { \
+ char line[256]; \
+ fgets(line, sizeof(line), fp); \
+ sscanf(line, A, B); \
+} while(0)
+
+// CODE GOES HERE -------------------------------------------------------------
+
+#ifdef OPENDINGUX
+ #define SDL_BLITVIDEO(X, Y, C, F) SDL_BlitSurface((X), (Y), (C), (F))
+#else
+ #define SDL_BLITVIDEO(X, Y, C, F) sdl_blitscale((X), (Y), (C), NULL)
+#endif
+
+void sdl_blitscale(SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect)
+{
+ if(src->w != dst->w) {
+ SDL_Surface *scale2x = NULL;
+
+ scale2x = zoomSurface(src, 2, 2, 0);
+ SDL_BlitSurface(scale2x, NULL, dst, NULL);
+ SDL_FreeSurface(scale2x);
+ } else {
+ SDL_BlitSurface(src, NULL, dst, NULL);
+ }
+
+}
+
+void game_fillrect(SDL_Surface *surface, int x, int y, int w, int h, int color)
+{
+ SDL_Rect src;
+
+ src.x = x;
+ src.y = y;
+ src.w = w;
+ src.h = h;
+
+ SDL_FillRect(surface, &src, color);
+}
+
+// copypaste from hRnd_CRT()
+static float RND()
+{
+ /* return between 0 and 1 (but never 1) */
+ return (float)rand() * (1.0 / ((float)RAND_MAX + 1.0));
+}
+
+void game_addFloatIcon(int ico, float xloc, float yloc)
+{
+ for(int i = 0; i < MAXFLOAT; i++) {
+ if(floaticon[i][0] == 0) {
+ floaticon[i][0] = 32;
+ floaticon[i][1] = xloc;
+ floaticon[i][2] = yloc;
+ floaticon[i][3] = ico;
+ return;
+ }
+ }
+}
+
+void game_addFloatText(char *stri, float xloc, float yloc, int col)
+{
+ for(int i = 0; i < MAXFLOAT; i++) {
+ if(floattext[i][0] == 0) {
+ floattext[i][0] = 32;
+ floattext[i][1] = xloc;
+ floattext[i][2] = yloc;
+ floattext[i][3] = col;
+ strcpy(floatstri[i], stri);
+ return;
+ }
+ }
+}
+
+void game_attack()
+{
+ float npx, npy;
+
+ npx = player.px + 12;
+ npy = player.py + 20;
+
+ int lx = (int)npx / 16;
+ int ly = (int)npy / 16;
+
+ // if facing up
+ if(player.walkdir == 0) {
+ if(ly > 0) {
+ int o2 = 0; // ??
+ int o = objmap[lx][ly - 1];
+ if(ly > 1 && curmap == 58) o2 = objmap[lx][ly - 2];
+ if(ly > 1 && curmap == 54) o2 = objmap[lx][ly - 2];
+
+ // cst
+ if((objectinfo[o][4] == 1 && (o == 0 || o > 4)) || (objectinfo[o2][4] == 0 && o2 == 10)) {
+ if(o2 == 10) o = 10;
+
+ int oscript = objectinfo[o][5];
+ if(oscript == 0 && player.inventory[INV_FLASK] < 9) {
+ player.inventory[INV_FLASK]++;
+ game_addFloatIcon(6, lx * 16, (ly - 1) * 16);
+
+ objmapf[curmap][lx][ly - 1] = 1;
+
+ if(menabled == 1 && config.effects == 1) {
+ int snd = Mix_PlayChannel(-1, sfx[sndpowerup], 0);
+ Mix_Volume(snd, config.effectsvol);
+ }
+
+ if(objectinfo[o][4] == 1) objmap[lx][ly - 1] = 3;
+
+ game_eventtext("Found Flask!");
+ itemticks = ticks + 215;
+ return;
+ }
+
+ if(oscript == 0 && player.inventory[INV_FLASK] == 9) {
+ if(menabled == 1 && config.effects == 1) {
+ int snd = Mix_PlayChannel(-1, sfx[sndchest], 0);
+ Mix_Volume(snd, config.effectsvol);
+ }
+
+ game_eventtext("Cannot Carry any more Flasks!");
+ itemticks = ticks + 215;
+ return;
+ }
+
+ if(oscript == 2) {
+ player.inventory[INV_MASTERKEY]++;
+
+ game_addFloatIcon(14, lx * 16, (ly - 1) * 16);
+
+ itemticks = ticks + 215;
+
+ if(curmap == 34) scriptflag[2][0] = 2;
+ if(curmap == 62) scriptflag[8][0] = 2;
+ if(curmap == 81) scriptflag[13][0] = 2;
+
+ if(menabled == 1 && config.effects == 1) {
+ int snd = Mix_PlayChannel(-1, sfx[sndpowerup], 0);
+ Mix_Volume(snd, config.effectsvol);
+ }
+
+ if(objectinfo[o][4] == 1) objmap[lx][ly - 1] = 3;
+ game_eventtext("Found the Temple Key!");
+ return;
+ }
+
+ if(oscript == 3) {
+ player.foundspell[0] = 1;
+ player.spellcharge[0] = 0;
+
+ game_addFloatIcon(7, lx * 16, (ly - 1) * 16);
+
+ if(menabled == 1 && config.effects == 1) {
+ int snd = Mix_PlayChannel(-1, sfx[sndpowerup], 0);
+ Mix_Volume(snd, config.effectsvol);
+ }
+
+ if(objectinfo[o][4] == 1) objmap[lx][ly - 1] = 3;
+
+ game_eventtext("Found the Infinite Crystal!");
+ itemticks = ticks + 215;
+ return;
+ }
+
+ if(oscript == 4 && player.shield == 1) {
+ player.shield = 2;
+
+ game_addFloatIcon(4, lx * 16, (ly - 1) * 16);
+
+ itemticks = ticks + 215;
+
+ if(menabled == 1 && config.effects == 1) {
+ int snd = Mix_PlayChannel(-1, sfx[sndpowerup], 0);
+ Mix_Volume(snd, config.effectsvol);
+ }
+
+ if(objectinfo[o][4] == 1) objmap[lx][ly - 1] = 3;
+
+ game_eventtext("Found the Obsidian Shield!");
+ objmapf[4][1][2] = 1;
+ return;
+ }
+
+ if(oscript == 5 && player.sword == 1) {
+ player.sword = 2;
+
+ game_addFloatIcon(3, lx * 16, (ly - 1) * 16);
+
+ itemticks = ticks + 215;
+
+ if(menabled == 1 && config.effects == 1) {
+ int snd = Mix_PlayChannel(-1, sfx[sndpowerup], 0);
+ Mix_Volume(snd, config.effectsvol);
+ }
+
+ if(objectinfo[o][4] == 1) objmap[lx][ly - 1] = 3;
+ game_eventtext("Found the Fidelis Sword!");
+ return;
+ }
+
+ if(oscript == 6) {
+ if(player.inventory[INV_NORMALKEY] < 9) {
+ player.inventory[INV_NORMALKEY]++;
+
+ for(int s = 20; s <= 23; s++) {
+ if(scriptflag[s][0] == 1) {
+ scriptflag[s][0] = 2;
+ }
+ }
+
+ if(menabled == 1 && config.effects == 1) {
+ int snd = Mix_PlayChannel(-1, sfx[sndpowerup], 0);
+ Mix_Volume(snd, config.effectsvol);
+ }
+
+ objmapf[curmap][lx][ly - 1] = 1;
+
+ if(objectinfo[o][4] == 1) objmap[lx][ly - 1] = 3;
+
+ game_eventtext("Found Key");
+ game_addFloatIcon(16, lx * 16, (ly - 1) * 16);
+ } else {
+ if(menabled == 1 && config.effects == 1) {
+ int snd = Mix_PlayChannel(-1, sfx[sndchest], 0);
+ Mix_Volume(snd, config.effectsvol);
+ }
+
+ game_eventtext("Cannot Carry Any More Keys");
+ }
+ }
+
+ if(oscript == 7 && player.inventory[INV_DOUBLEFLASK] < 9) {
+ player.inventory[INV_DOUBLEFLASK]++;
+ game_addFloatIcon(12, lx * 16, (ly - 1) * 16);
+
+ objmapf[curmap][lx][ly - 1] = 1;
+
+ if(menabled == 1 && config.effects == 1) {
+ int snd = Mix_PlayChannel(-1, sfx[sndpowerup], 0);
+ Mix_Volume(snd, config.effectsvol);
+ }
+
+ if(objectinfo[o][4] == 1) objmap[lx][ly - 1] = 3;
+
+ game_eventtext("Found Mega Flask!");
+ itemticks = ticks + 215;
+ return;
+ }
+
+ if(oscript == 7 && player.inventory[INV_DOUBLEFLASK] == 9) {
+ if(menabled == 1 && config.effects == 1) {
+ int snd = Mix_PlayChannel(-1, sfx[sndchest], 0);
+ Mix_Volume(snd, config.effectsvol);
+ }
+
+ game_eventtext("Cannot Carry any more Mega Flasks!");
+ itemticks = ticks + 215;
+ return;
+ }
+
+ if(oscript == 10 && player.inventory[INV_DOUBLEFLASK] < 9) {
+ player.inventory[INV_DOUBLEFLASK]++;
+ game_addFloatIcon(12, lx * 16, (ly - 1) * 16);
+
+ objmapf[curmap][lx][ly - 1] = 1;
+
+ if(menabled == 1 && config.effects == 1) {
+ int snd = Mix_PlayChannel(-1, sfx[sndpowerup], 0);
+ Mix_Volume(snd, config.effectsvol);
+ }
+
+ if(objectinfo[o][4] == 1) objmap[lx][ly - 1] = 3;
+
+ game_eventtext("Found Mega Flask!");
+ itemticks = ticks + 215;
+ return;
+ }
+
+ if(oscript == 10 && player.inventory[INV_DOUBLEFLASK] == 9) {
+ if(menabled == 1 && config.effects == 1) {
+ int snd = Mix_PlayChannel(-1, sfx[sndchest], 0);
+ Mix_Volume(snd, config.effectsvol);
+ }
+
+ game_eventtext("Cannot Carry any more Mega Flasks!");
+ itemticks = ticks + 215;
+ return;
+ }
+
+ if(oscript == 11 && player.inventory[INV_SHOCK] < 9) {
+ player.inventory[INV_SHOCK]++;
+ game_addFloatIcon(17, lx * 16, (ly - 1) * 16);
+
+ objmapf[curmap][lx][ly - 1] = 1;
+
+ if(menabled == 1 && config.effects == 1) {
+ int snd = Mix_PlayChannel(-1, sfx[sndpowerup], 0);
+ Mix_Volume(snd, config.effectsvol);
+ }
+
+ if(objectinfo[o][4] == 1) objmap[lx][ly - 1] = 3;
+
+ game_eventtext("Found Lightning Bomb!");
+ itemticks = ticks + 215;
+ return;
+ }
+
+ if(oscript == 11 && player.inventory[INV_SHOCK] == 9) {
+ if(menabled == 1 && config.effects == 1) {
+ int snd = Mix_PlayChannel(-1, sfx[sndchest], 0);
+ Mix_Volume(snd, config.effectsvol);
+ }
+
+ game_eventtext("Cannot Carry any more Lightning Bombs!");
+ itemticks = ticks + 215;
+ return;
+ }
+
+ if(oscript == 12 && player.armour == 1) {
+ player.armour = 2;
+
+ game_addFloatIcon(5, lx * 16, (ly - 1) * 16);
+
+ if(menabled == 1 && config.effects == 1) {
+ int snd = Mix_PlayChannel(-1, sfx[sndpowerup], 0);
+ Mix_Volume(snd, config.effectsvol);
+ }
+
+ if(objectinfo[o][4] == 1) objmap[lx][ly - 1] = 3;
+
+ game_eventtext("Found the Fidelis Mail!");
+ itemticks = ticks + 215;
+ return;
+ }
+
+ if(oscript == 60) {
+ if(curmap == 58 && scriptflag[60][0] == 0) {
+ scriptflag[60][0] = 1;
+
+ if(menabled == 1 && config.effects == 1) {
+ int snd = Mix_PlayChannel(-1, sfx[sndlever], 0);
+ Mix_Volume(snd, config.effectsvol);
+ }
+
+ } else if(curmap == 58 && scriptflag[60][0] > 0) {
+ if(menabled == 1 && config.effects == 1) {
+ int snd = Mix_PlayChannel(-1, sfx[snddoor], 0);
+ Mix_Volume(snd, config.effectsvol);
+ }
+
+ game_eventtext("It's stuck!");
+ }
+
+ if(curmap == 54 && scriptflag[60][0] == 1) {
+ if(menabled == 1 && config.effects == 1) {
+ int snd = Mix_PlayChannel(-1, sfx[sndlever], 0);
+ Mix_Volume(snd, config.effectsvol);
+ }
+
+ scriptflag[60][0] = 2;
+ } else if(curmap == 54 && scriptflag[60][0] > 1) {
+ if(menabled == 1 && config.effects == 1) {
+ int snd = Mix_PlayChannel(-1, sfx[snddoor], 0);
+ Mix_Volume(snd, config.effectsvol);
+ }
+
+ game_eventtext("It's stuck!");
+ }
+
+ }
+
+ if(oscript == 15 && player.sword < 3) {
+ player.sword = 3;
+
+ game_addFloatIcon(18, lx * 16, (ly - 1) * 16);
+
+ itemticks = ticks + 215;
+
+ if(menabled == 1 && config.effects == 1) {
+ int snd = Mix_PlayChannel(-1, sfx[sndpowerup], 0);
+ Mix_Volume(snd, config.effectsvol);
+ }
+
+ if(objectinfo[o][4] == 1) objmap[lx][ly - 1] = 3;
+ game_eventtext("Found the Blood Sword!");
+ objmapf[4][1][2] = 1;
+ return;
+ }
+
+ if(oscript == 16 && player.shield < 3) {
+ player.shield = 3;
+ game_addFloatIcon(19, lx * 16, (ly - 1) * 16);
+ itemticks = ticks + 215;
+
+ if(menabled == 1 && config.effects == 1) {
+ int snd = Mix_PlayChannel(-1, sfx[sndpowerup], 0);
+ Mix_Volume(snd, config.effectsvol);
+ }
+
+ if(objectinfo[o][4] == 1) objmap[lx][ly - 1] = 3;
+ game_eventtext("Found the Entropy Shield!");
+ objmapf[4][1][2] = 1;
+ return;
+ }
+
+ if(oscript == 17 && player.armour < 3) {
+ player.armour = 3;
+ game_addFloatIcon(20, lx * 16, (ly - 1) * 16);
+ itemticks = ticks + 215;
+
+ if(menabled == 1 && config.effects == 1) {
+ int snd = Mix_PlayChannel(-1, sfx[sndpowerup], 0);
+ Mix_Volume(snd, config.effectsvol);
+ }
+
+ if(objectinfo[o][4] == 1) objmap[lx][ly - 1] = 3;
+ game_eventtext("Found the Rubyscale Armour!");
+ objmapf[4][1][2] = 1;
+ return;
+ }
+
+ }
+ }
+ }
+
+ attacking = 1;
+ player.attackframe = 0;
+ movingup = 0;
+ movingdown = 0;
+ movingleft = 0;
+ movingright = 0;
+
+ for(int i = 0; i <= 15; i++) {
+ for(int a = 0; a <= 3; a++) {
+ playerattackofs[a][i][2] = 0;
+ }
+ }
+}
+
+void game_castspell(int spellnum, float homex, float homey, float enemyx, float enemyy, int damagewho)
+{
+ // spellnum 7 = sprite 6 spitfire
+
+ for(int i = 0; i < MAXSPELL; i++) {
+ if(spellinfo[i].frame == 0) {
+ spellinfo[i].homex = homex;
+ spellinfo[i].homey = homey;
+ spellinfo[i].enemyx = enemyx;
+ spellinfo[i].enemyy = enemyy;
+ spellinfo[i].spellnum = spellnum;
+ int dw = 0;
+ int npc = 0;
+ if(damagewho > 0) {
+ dw = 1;
+ npc = damagewho;
+ }
+
+ spellinfo[i].damagewho = dw;
+ spellinfo[i].npc = npc;
+
+ spellinfo[i].frame = 32;
+ if(damagewho == 0) {
+ spellinfo[i].strength = player.spellstrength / 100;
+ if(player.spellstrength == 100) spellinfo[i].strength = 1.5;
+ }
+
+ // set earthslide vars
+ if(spellnum == 2) {
+ for(int f = 0; f <= 8; f++) {
+ spellinfo[i].rocky[f] = 0;
+ spellinfo[i].rockimg[f] = (int)(RND() * 4);
+ spellinfo[i].rockdeflect[f] = ((int)(RND() * 128) - 64) * 1.5;
+ }
+ }
+
+ // set fire vars
+ if(spellnum == 3) {
+ for(int f = 0; f <= 4; f++) {
+ spellinfo[i].legalive[f] = 32;
+ }
+ }
+
+
+ // room fireball vars
+ if(spellnum == 6) {
+ int nballs = 0;
+ for(int x = 0; x <= 19; x++) {
+ for(int y = 0; y <= 14; y++) {
+ if((objmap[x][y] == 1 || objmap[x][y] == 2) && nballs < 5 && (int)(RND() * 4) == 0) {
+ int ax = x * 16;
+ int ay = y * 16;
+
+ spellinfo[i].fireballs[nballs][0] = ax;
+ spellinfo[i].fireballs[nballs][1] = ay;
+ spellinfo[i].fireballs[nballs][2] = 0;
+ spellinfo[i].fireballs[nballs][3] = 0;
+
+ spellinfo[i].ballon[nballs] = 1;
+ nballs = nballs + 1;
+ }
+ }
+ }
+ spellinfo[i].nfballs = nballs;
+ }
+
+ if(menabled == 1 && config.effects == 1) {
+ if(spellnum == 1) {
+ int snd = Mix_PlayChannel(-1, sfx[sndthrow], 0);
+ Mix_Volume(snd, config.effectsvol);
+ } else if(spellnum == 5) {
+ int snd = Mix_PlayChannel(-1, sfx[sndcrystal], 0);
+ Mix_Volume(snd, config.effectsvol);
+ } else if(spellnum == 8 || spellnum == 9) {
+ int snd = Mix_PlayChannel(-1, sfx[sndlightning], 0);
+ Mix_Volume(snd, config.effectsvol);
+ }
+ }
+
+ return;
+ }
+ }
+}
+
+void game_checkhit()
+{
+ float npx, npy;
+ float damage;
+
+ if(attacking == 1) {
+ for(int i = 1; i <= lastnpc; i++) {
+ if(npcinfo[i].hp > 0 && npcinfo[i].pause < ticks && (int)(RND() * 2) == 0) {
+ npx = npcinfo[i].x;
+ npy = npcinfo[i].y;
+
+ float xdif = player.px - npx;
+ float ydif = player.py - npy;
+
+ float ps = player.sword;
+ if(ps > 1) ps = ps * 0.75;
+ damage = (float)player.sworddamage * (1.0 + RND() * 1.0) * player.attackstrength / 100.0 * ps;
+ if(player.attackstrength == 100) damage = damage * 1.5;
+
+ int hit = 0;
+ if(player.walkdir == 0) {
+ if(abs(xdif) <= 8 && ydif >= 0 && ydif < 8) hit = 1;
+ } else if(player.walkdir == 1) {
+ if(abs(xdif) <= 8 && ydif <= 0 && ydif > -8) hit = 1;
+ } else if(player.walkdir == 2) {
+ if(abs(ydif) <= 8 && xdif >= -8 && xdif < 8) hit = 1;
+ } else if(player.walkdir == 3) {
+ if(abs(ydif) <= 8 && xdif <= 8 && xdif > -8) hit = 1;
+ }
+
+ if(hit == 1) {
+ if(menabled == 1 && config.effects == 1) {
+ int snd = Mix_PlayChannel(-1, sfx[sndswordhit], 0);
+ Mix_Volume(snd, config.effectsvol);
+ }
+
+ game_damagenpc(i, damage, 0);
+ }
+ }
+ }
+ }
+}
+
+void game_checkinputs()
+{
+ int ntickdelay;
+
+ ntickdelay = 175;
+
+ SDL_PollEvent(&event);
+ keys = SDL_GetKeyState(NULL);
+
+ nposts = 0;
+
+ for(int i = 0; i <= 20; i++) {
+ postinfo[i][0] = 0;
+ postinfo[i][1] = 0;
+ }
+
+ for(int x = 0; x <= 19; x++) {
+ for(int y = 0; y <= 14; y++) {
+ int o = objmap[x][y];
+ if(objectinfo[o][4] == 3) {
+ postinfo[nposts][0] = x * 16;
+ postinfo[nposts][1] = y * 16;
+ nposts = nposts + 1;
+ }
+ }
+ }
+
+ if(attacking == 1 || (forcepause == 1 && itemselon == 0)) return;
+
+ if(event.type == SDL_KEYDOWN) {
+ switch(event.key.keysym.sym) {
+ case SDLK_ESCAPE:
+ if(itemticks < ticks) game_title(1);
+ break;
+ case SDLK_RETURN:
+ if(keys[SDLK_LALT] || keys[SDLK_RALT]) {
+ if(fullscreen & SDL_FULLSCREEN) {
+ fullscreen = config.hwaccel | config.hwsurface;
+ } else {
+ fullscreen = SDL_FULLSCREEN | config.hwaccel | config.hwsurface;
+ }
+
+ config.fullscreen = fullscreen & SDL_FULLSCREEN;
+
+ video = SDL_SetVideoMode(config.scr_width, config.scr_height, config.scr_bpp, fullscreen);
+ SDL_UpdateRect(video, 0, 0, config.scr_width, config.scr_height);
+ }
+ break;
+
+ case SDLK_LCTRL:
+ if(itemselon == 0 && itemticks < ticks) game_attack();
+
+ if(itemselon == 1 && itemticks < ticks) {
+ if(curitem == 0 && player.inventory[INV_FLASK] > 0) {
+ itemticks = ticks + ntickdelay;
+
+ int heal = 50;
+ int maxh = player.maxhp - player.hp;
+
+ if(heal > maxh) heal = maxh;
+
+ player.hp = player.hp + heal;
+
+ char text[256];
+ sprintf(text, "+%i", heal);
+ game_addFloatText(text, player.px + 16 - 4 * strlen(text), player.py + 16, 5);
+
+ player.inventory[INV_FLASK]--;
+
+ if(menabled == 1 && config.effects == 1) {
+ int snd = Mix_PlayChannel(-1, sfx[sndpowerup], 0);
+ Mix_Volume(snd, config.effectsvol);
+ }
+
+ itemselon = 0;
+ forcepause = 0;
+ }
+
+ if(curitem == 1 && player.inventory[INV_DOUBLEFLASK] > 0) {
+ itemticks = ticks + ntickdelay;
+
+ int heal = 200;
+ int maxh = player.maxhp - player.hp;
+
+ if(heal > maxh) heal = maxh;
+
+ player.hp = player.hp + heal;
+
+ char text[256];
+ sprintf(text, "+%i", heal);
+ game_addFloatText(text, player.px + 16 - 4 * strlen(text), player.py + 16, 5);
+
+ player.inventory[INV_DOUBLEFLASK]--;
+
+ if(menabled == 1 && config.effects == 1) {
+ int snd = Mix_PlayChannel(-1, sfx[sndpowerup], 0);
+ Mix_Volume(snd, config.effectsvol);
+ }
+
+ itemselon = 0;
+ forcepause = 0;
+
+ }
+
+ if(curitem == 2 && player.inventory[INV_SHOCK] > 0) {
+ game_castspell(8, player.px, player.py, npcinfo[curenemy].x, npcinfo[curenemy].y, 0);
+
+ forcepause = 1;
+
+ player.inventory[INV_SHOCK]--;
+
+ itemticks = ticks + ntickdelay;
+ selenemyon = 0;
+ itemselon = 0;
+
+ }
+
+ if(curitem == 3 && player.inventory[INV_NORMALKEY] > 0 && canusekey == 1 && locktype == 1) {
+ roomlocks[roomtounlock] = 0;
+ game_eventtext("UnLocked!");
+
+ player.inventory[INV_NORMALKEY]--;
+
+ itemticks = ticks + ntickdelay;
+ selenemyon = 0;
+ itemselon = 0;
+ return;
+ }
+
+ if(curitem == 4 && player.inventory[INV_MASTERKEY] > 0 && canusekey == 1 && locktype == 2) {
+ roomlocks[roomtounlock] = 0;
+ game_eventtext("UnLocked!");
+
+ player.inventory[INV_MASTERKEY]--;
+
+ itemticks = ticks + ntickdelay;
+ selenemyon = 0;
+ itemselon = 0;
+ return;
+ }
+
+ if(curitem == 5 && player.spellcharge[0] == 100) {
+ game_castspell(5, player.px, player.py, npcinfo[curenemy].x, npcinfo[curenemy].y, 0);
+
+ player.spellcharge[0] = 0;
+
+ forcepause = 1;
+
+ itemticks = ticks + ntickdelay;
+ selenemyon = 0;
+ itemselon = 0;
+ }
+
+ if(curitem > 5 && selenemyon == 1) {
+ if(curenemy <= lastnpc) {
+ game_castspell(curitem - 6, player.px, player.py, npcinfo[curenemy].x, npcinfo[curenemy].y, 0);
+ } else {
+ int pst = curenemy - lastnpc - 1;
+ game_castspell(curitem - 6, player.px, player.py, postinfo[pst][0], postinfo[pst][1], 0);
+ }
+
+ player.spellcharge[curitem - 5] = 0;
+
+ player.spellstrength = 0;
+
+ itemticks = ticks + ntickdelay;
+ selenemyon = 0;
+ itemselon = 0;
+ forcepause = 0;
+ }
+
+ if(curitem > 5 && selenemyon == 0 && itemselon == 1) {
+ if(player.spellcharge[curitem - 5] == 100) {
+ itemticks = ticks + ntickdelay;
+
+ selenemyon = 1;
+
+ int i = 0;
+ do {
+ if(npcinfo[i].hp > 0) {
+ curenemy = i;
+ goto __exit_do;
+ }
+ i = i + 1;
+ if(i == lastnpc + 1) {
+ selenemyon = 0;
+ goto __exit_do;
+ }
+ } while(1);
+ __exit_do:
+
+ if(nposts > 0 && selenemyon == 0) {
+ selenemyon = 1;
+ curenemy = lastnpc + 1;
+ }
+ }
+
+ }
+ }
+ break;
+
+ case SDLK_LALT:
+ if(itemticks < ticks) {
+ selenemyon = 0;
+ if(itemselon == 1) {
+ itemselon = 0;
+ itemticks = ticks + 220;
+ forcepause = 0;
+ } else {
+ itemselon = 1;
+ itemticks = ticks + 220;
+ forcepause = 1;
+ player.itemselshade = 0;
+ }
+ }
+ break;
+
+ default:
+ ;
+ }
+ }
+
+ if(itemselon == 0) {
+ movingup = 0;
+ movingdown = 0;
+ movingleft = 0;
+ movingright = 0;
+ if(keys[SDLK_UP]) movingup = 1;
+ if(keys[SDLK_DOWN]) movingdown = 1;
+ if(keys[SDLK_LEFT]) movingleft = 1;
+ if(keys[SDLK_RIGHT]) movingright = 1;
+ } else {
+ movingup = 0;
+ movingdown = 0;
+ movingleft = 0;
+ movingright = 0;
+
+ if(selenemyon == 1) {
+ if(itemticks < ticks) {
+ if(keys[SDLK_LEFT]) {
+ int origin = curenemy;
+ do {
+ curenemy = curenemy - 1;
+ if(curenemy < 1) curenemy = lastnpc + nposts;
+ if(curenemy == origin) break;
+ if(curenemy <= lastnpc && npcinfo[curenemy].hp > 0) break;
+ if(curenemy > lastnpc) break;
+ } while(1);
+ itemticks = ticks + ntickdelay;
+ }
+ if(keys[SDLK_RIGHT]) {
+ int origin = curenemy;
+ do {
+ curenemy = curenemy + 1;
+ if(curenemy > lastnpc + nposts) curenemy = 1;
+ if(curenemy == origin) break;
+ if(curenemy <= lastnpc && npcinfo[curenemy].hp > 0) break;
+ if(curenemy > lastnpc) break;
+ } while(1);
+ itemticks = ticks + ntickdelay;
+ }
+
+
+ if(curenemy > lastnpc + nposts) curenemy = 1;
+ if(curenemy < 1) curenemy = lastnpc + nposts;
+ }
+ } else {
+ if(itemticks < ticks) {
+ if(keys[SDLK_UP]) {
+ curitem = curitem - 1;
+ itemticks = ticks + ntickdelay;
+ if(curitem == 4) curitem = 9;
+ if(curitem == -1) curitem = 4;
+ }
+ if(keys[SDLK_DOWN]) {
+ curitem = curitem + 1;
+ itemticks = ticks + ntickdelay;
+ if(curitem == 5) curitem = 0;
+ if(curitem == 10) curitem = 5;
+ }
+ if(keys[SDLK_LEFT]) {
+ curitem = curitem - 5;
+ itemticks = ticks + ntickdelay;
+ }
+ if(keys[SDLK_RIGHT]) {
+ curitem = curitem + 5;
+ itemticks = ticks + ntickdelay;
+ }
+
+ if(curitem > 9) curitem = curitem - 10;
+ if(curitem < 0) curitem = curitem + 10;
+ }
+ }
+ }
+}
+
+void game_checktrigger()
+{
+ int npx, npy, lx, ly;
+
+ npx = player.px + 12;
+ npy = player.py + 20;
+
+ lx = (int)npx / 16;
+ ly = (int)npy / 16;
+
+ canusekey = 0;
+
+ if(triggerloc[lx][ly] > -1) game_processtrigger(triggerloc[lx][ly]);
+}
+
+#ifdef OPENDINGUX
+ #define MINCURSEL 7
+ #define MAXCURSEL 14
+ #define SY 22
+#else
+ #define MINCURSEL 0
+ #define MAXCURSEL 14
+ #define SY (38 + (240 - 38) / 2 - 88)
+#endif
+
+void game_configmenu()
+{
+ SDL_Surface *configwindow;
+ SDL_Rect rc;
+ int cursel, curselt, ofullscreen;
+ int tickwait, keypause, ticks1;
+
+ cursel = MINCURSEL;
+
+ ticks = SDL_GetTicks();
+ tickwait = 100;
+ keypause = ticks + tickwait;
+
+ configwindow = SDL_DisplayFormat(videobuffer);
+
+ configwindow = IMG_Load("art/configwindow.bmp");
+ SDL_SetColorKey(configwindow, SDL_SRCCOLORKEY, SDL_MapRGB(configwindow->format, 255, 0, 255));
+ SDL_SetAlpha(configwindow, SDL_SRCALPHA, 160);
+
+ ticks1 = ticks;
+ do {
+ SDL_FillRect(videobuffer, NULL, 0);
+
+ rcDest.x = 256 + 256 * cos(3.141592 / 180 * clouddeg * 40);
+ rcDest.y = 192 + 192 * sin(3.141592 / 180 * clouddeg * 40);
+ rcDest.w = 320;
+ rcDest.h = 240;
+
+ SDL_SetAlpha(cloudimg, SDL_SRCALPHA, 128);
+ SDL_BlitSurface(cloudimg, &rcDest, videobuffer, NULL);
+ SDL_SetAlpha(cloudimg, SDL_SRCALPHA, 64);
+
+ rcDest.x = 256;
+ rcDest.y = 192;
+ rcDest.w = 320;
+ rcDest.h = 240;
+
+ SDL_SetAlpha(cloudimg, SDL_SRCALPHA, 128);
+ SDL_BlitSurface(cloudimg, &rcDest, videobuffer, NULL);
+ SDL_SetAlpha(cloudimg, SDL_SRCALPHA, 64);
+
+ SDL_BlitSurface(configwindow, NULL, videobuffer, NULL);
+
+ int sy = SY;
+
+ for(int i = 0; i <= 21; i++) {
+ static char *vr[22] = {
+#ifdef OPENDINGUX
+ "", "",
+ "", "", "", "",
+ "", "", "",
+#else
+ "Resolution:", "",
+ "Bit Depth:", "", "", "",
+ "Start Fullscreen:", "", "",
+#endif
+ "Music:", "", "",
+ "Sound Effects:", "", "",
+ "Music Volume:", "",
+ "Effects Volume:", "", "", "", ""
+ };
+ static char *vl[22] = {
+#ifdef OPENDINGUX
+ "", "",
+ "", "", "", "",
+ "", "", "",
+#else
+ "320x240", "640x480",
+ "16", "24", "32", "",
+ "Yes", "No", "",
+#endif
+ "On", "Off", "",
+ "On", "Off", "",
+ "[----------]", "",
+ "[----------]", "",
+ "Exit + Save", "",
+ "Exit"
+ };
+ static char line[24];
+
+ if(i == 15 || i == 17) {
+ int vol = (i == 15 ? config.musicvol : config.effectsvol) * 9 / 255;
+ if(vol < 0) vol = 0;
+ if(vol > 9) vol = 9;
+
+ strcpy(line, "[----------]");
+ line[vol+1] = 'X';
+ vl[i] = line;
+ }
+
+ int cl = 3;
+ if(i == 0 && config.scr_width == 320) cl = 0;
+ if(i == 1 && config.scr_width == 640) cl = 0;
+ if(i == 2 && config.scr_bpp == 16) cl = 0;
+ if(i == 3 && config.scr_bpp == 24) cl = 0;
+ if(i == 4 && config.scr_bpp == 32) cl = 0;
+ if(i == 6 && config.fullscreen != 0) cl = 0;
+ if(i == 7 && config.fullscreen == 0) cl = 0;
+ if(i == 9 && config.music == 1) cl = 0;
+ if(i == 10 && config.music == 0) cl = 0;
+ if(i == 12 && config.effects == 1) cl = 0;
+ if(i == 13 && config.effects == 0) cl = 0;
+
+ if(i > 18) cl = 0;
+
+ sys_print(videobuffer, vr[i], 156 - 8 * strlen(vr[i]), sy + i * 8, 0);
+ sys_print(videobuffer, vl[i], 164, sy + i * 8, cl);
+ }
+
+ curselt = cursel;
+ if(cursel > 4) curselt = curselt + 1;
+ if(cursel > 6) curselt = curselt + 1;
+ if(cursel > 8) curselt = curselt + 1;
+ if(cursel > 10) curselt = curselt + 1;
+ if(cursel > 11) curselt = curselt + 1;
+ if(cursel > 12) curselt = curselt + 1;
+ if(cursel > 13) curselt = curselt + 1;
+
+ rc.x = 148 + 3 * cos(3.14159 * 2 * itemyloc / 16.0);
+ rc.y = sy + 8 * curselt - 4;
+
+ SDL_BlitSurface(itemimg[15], NULL, videobuffer, &rc);
+
+ float yy = 255.0;
+ if(ticks < ticks1 + 1000) {
+ yy = 255.0 * ((float)(ticks - ticks1) / 1000.0);
+ if(yy < 0.0) yy = 0.0;
+ if(yy > 255.0) yy = 255.0;
+ }
+
+ SDL_SetAlpha(videobuffer, SDL_SRCALPHA, (int)yy);
+ SDL_BLITVIDEO(videobuffer, NULL, video, NULL);
+ SDL_SetAlpha(videobuffer, SDL_SRCALPHA, 255);
+
+ SDL_Flip(video);
+ SDL_PumpEvents();
+
+ tickspassed = ticks;
+ ticks = SDL_GetTicks();
+
+ tickspassed = ticks - tickspassed;
+ fpsr = (float)tickspassed / 24;
+
+ fp++;
+ if(ticks > nextticks) {
+ nextticks = ticks + 1000;
+ fps = fp;
+ fp = 0;
+ }
+
+ itemyloc += 0.75 * fpsr;
+ while(itemyloc >= 16) itemyloc -= 16;
+
+ if(keypause < ticks) {
+ SDL_PollEvent(&event);
+ keys = SDL_GetKeyState(NULL);
+
+ if(event.type == SDL_KEYDOWN) {
+ keypause = ticks + tickwait;
+
+ if(keys[SDLK_ESCAPE] || keys[SDLK_LALT]) break;
+
+ if(keys[SDLK_LEFT]) {
+ if(cursel == 11) {
+ config.musicvol = config.musicvol - 25;
+ if(config.musicvol < 0) config.musicvol = 0;
+
+ Mix_Volume(musicchannel, config.musicvol);
+ Mix_Volume(menuchannel, config.musicvol);
+ } else if(cursel == 12) {
+ config.effectsvol = config.effectsvol - 25;
+ if(config.effectsvol < 0) config.effectsvol = 0;
+
+ Mix_Volume(-1, config.effectsvol);
+ Mix_Volume(musicchannel, config.musicvol);
+ Mix_Volume(menuchannel, config.musicvol);
+
+ if(menabled == 1 && config.effects == 1) {
+ int snd = Mix_PlayChannel(-1, sfx[snddoor], 0);
+ Mix_Volume(snd, config.effectsvol);
+ }
+ }
+ }
+ if(keys[SDLK_RIGHT]) {
+ if(cursel == 11) {
+ config.musicvol = config.musicvol + 25;
+ if(config.musicvol > 255) config.musicvol = 255;
+
+ Mix_Volume(musicchannel, config.musicvol);
+ Mix_Volume(menuchannel, config.musicvol);
+ } else if(cursel == 12) {
+ config.effectsvol = config.effectsvol + 25;
+ if(config.effectsvol > 255) config.effectsvol = 255;
+
+ Mix_Volume(-1, config.effectsvol);
+ Mix_Volume(musicchannel, config.musicvol);
+ Mix_Volume(menuchannel, config.musicvol);
+
+ if(menabled == 1 && config.effects == 1) {
+ int snd = Mix_PlayChannel(-1, sfx[snddoor], 0);
+ Mix_Volume(snd, config.effectsvol);
+ }
+ }
+ }
+
+ if(keys[SDLK_UP]) {
+ cursel--;
+ if(cursel < MINCURSEL) cursel = 14;
+ }
+ if(keys[SDLK_DOWN]) {
+ cursel++;
+ if(cursel > 14) cursel = MINCURSEL;
+ }
+
+ if(keys[SDLK_LCTRL] || keys[SDLK_RETURN]) {
+ if(cursel == 0) {
+ fullscreen = config.fullscreen | config.hwaccel | config.hwsurface;
+
+ video = SDL_SetVideoMode(320, 240, config.scr_bpp, fullscreen);
+ if(video == 0) {
+ video = SDL_SetVideoMode(config.scr_width, config.scr_height, config.scr_bpp, fullscreen);
+ } else {
+ config.scr_width = 320;
+ config.scr_height = 240;
+ }
+
+ SDL_UpdateRect(video, 0, 0, config.scr_width, config.scr_height);
+ }
+ if(cursel == 1) {
+ fullscreen = config.fullscreen | config.hwaccel | config.hwsurface;
+
+ video = SDL_SetVideoMode(640, 480, config.scr_bpp, fullscreen);
+ if(video == 0) {
+ video = SDL_SetVideoMode(config.scr_width, config.scr_height, config.scr_bpp, fullscreen);
+ } else {
+ config.scr_width = 640;
+ config.scr_height = 480;
+ }
+
+ SDL_UpdateRect(video, 0, 0, config.scr_width, config.scr_height);
+ }
+ if(cursel == 2 || cursel == 3 || cursel == 4) {
+ fullscreen = config.fullscreen | config.hwaccel | config.hwsurface;
+
+ int b = 16;
+ if(cursel == 3) b = 24;
+ if(cursel == 4) b = 32;
+ video = SDL_SetVideoMode(config.scr_width, config.scr_height, b, fullscreen);
+ if(video == 0) {
+ video = SDL_SetVideoMode(config.scr_width, config.scr_height, config.scr_bpp, fullscreen);
+ } else {
+ config.scr_bpp = b;
+ }
+
+ SDL_UpdateRect(video, 0, 0, config.scr_width, config.scr_height);
+ }
+ if(cursel == 5) {
+ ofullscreen = config.fullscreen | config.hwaccel | config.hwsurface;
+ fullscreen = SDL_FULLSCREEN | config.hwaccel | config.hwsurface;
+
+ video = SDL_SetVideoMode(config.scr_width, config.scr_height, config.scr_bpp, fullscreen);
+ if(video == 0) {
+ video = SDL_SetVideoMode(config.scr_width, config.scr_height, config.scr_bpp, ofullscreen);
+ } else {
+ config.fullscreen = SDL_FULLSCREEN;
+ }
+
+ SDL_UpdateRect(video, 0, 0, config.scr_width, config.scr_height);
+ }
+ if(cursel == 6) {
+ ofullscreen = config.fullscreen | config.hwaccel | config.hwsurface;
+ fullscreen = 0 | config.hwaccel | config.hwsurface;
+
+ video = SDL_SetVideoMode(config.scr_width, config.scr_height, config.scr_bpp, fullscreen);
+ if(video == 0) {
+ video = SDL_SetVideoMode(config.scr_width, config.scr_height, config.scr_bpp, ofullscreen);
+ } else {
+ config.fullscreen = 0;
+ }
+
+ SDL_UpdateRect(video, 0, 0, config.scr_width, config.scr_height);
+ }
+ if(cursel == 7 && config.music == 0) {
+ config.music = 1;
+ if(menabled == 1) {
+ menuchannel = Mix_PlayChannel(-1, mmenu, -1);
+ Mix_Volume(menuchannel, config.musicvol);
+ }
+ }
+ if(cursel == 8 && config.music == 1) {
+ config.music = 0;
+ Mix_HaltChannel(musicchannel);
+ Mix_HaltChannel(menuchannel);
+ }
+ if(cursel == 9 && config.effects == 0) {
+ config.effects = 1;
+ if(menabled == 1) {
+ int snd = Mix_PlayChannel(-1, sfx[snddoor], 0);
+ Mix_Volume(snd, config.effectsvol);
+ }
+ }
+
+ if(cursel == 10 && config.effects == 1) config.effects = 0;
+
+ if(cursel == 13) {
+ config_save(&config);
+ break;
+ }
+
+ if(cursel == 14) {
+ // reset keys to avoid returning
+ keys[SDLK_SPACE] = keys[SDLK_RETURN] = 0;
+ break;
+ }
+ }
+ }
+ }
+
+ clouddeg += 0.01 * fpsr;
+ while(clouddeg >= 360) clouddeg = clouddeg - 360;
+
+ SDL_Delay(10);
+ } while(1);
+
+ SDL_FreeSurface(configwindow);
+ itemticks = ticks + 210;
+
+ SDL_SetAlpha(cloudimg, SDL_SRCALPHA, 64);
+}
+
+void game_damagenpc(int npcnum, int damage, int spell)
+{
+ float npx, npy;
+ int lx, ly, cx, cy, alive;
+ char line[256];
+ int ratio;
+ int fcol, heal, ff;
+
+ if(damage == 0) {
+ strcpy(line, "miss!");
+ fcol = 2;
+ } else {
+ ratio = 0;
+ heal = 0;
+ if(damage < 0) heal = 1;
+ damage = abs(damage);
+
+ if(heal == 0) {
+ if(damage > npcinfo[npcnum].hp) {
+ ratio = (damage - npcinfo[npcnum].hp) * 100 / damage;
+ damage = npcinfo[npcnum].hp;
+ }
+
+ npcinfo[npcnum].hp -= damage;
+ if(npcinfo[npcnum].hp < 0) npcinfo[npcnum].hp = 0;
+
+ sprintf(line, "-%i", damage);
+ fcol = 1;
+ } else {
+ npcinfo[npcnum].hp += damage;
+ if(npcinfo[npcnum].hp > npcinfo[npcnum].maxhp) npcinfo[npcnum].hp = npcinfo[npcnum].maxhp;
+
+ sprintf(line, "+%i", damage);
+ fcol = 5;
+ }
+
+ npcinfo[npcnum].pause = ticks + 900;
+
+ if(spell == 0) player.attackstrength = ratio;
+ }
+
+ game_addFloatText(line, npcinfo[npcnum].x + 12 - 4 * strlen(line), npcinfo[npcnum].y + 16, fcol);
+
+ if(npcinfo[npcnum].spriteset == 12) game_castspell(9, npcinfo[npcnum].x, npcinfo[npcnum].y, player.px, player.py, npcnum);
+
+ // if enemy is killed
+ if(npcinfo[npcnum].hp == 0) {
+ player.exp = player.exp + npcinfo[npcnum].maxhp;
+
+ if(npcinfo[npcnum].spriteset == 1 || npcinfo[npcnum].spriteset == 7 || npcinfo[npcnum].spriteset == 6) {
+ ff = (int)(RND() * player.level * 3);
+ if(ff == 0) {
+ npx = npcinfo[npcnum].x + 12;
+ npy = npcinfo[npcnum].y + 20;
+
+ lx = (int)npx / 16;
+ ly = (int)npy / 16;
+
+ if(objmap[lx][ly] == -1) objmap[lx][ly] = 4;
+ }
+ }
+
+ if(npcinfo[npcnum].spriteset == 2 || npcinfo[npcnum].spriteset == 9 || npcinfo[npcnum].spriteset == 4 || npcinfo[npcnum].spriteset == 5) {
+ ff = (int)(RND() * player.level);
+ if(ff == 0) {
+ npx = npcinfo[npcnum].x + 12;
+ npy = npcinfo[npcnum].y + 20;
+
+ lx = (int)npx / 16;
+ ly = (int)npy / 16;
+
+ if(objmap[lx][ly] == -1) objmap[lx][ly] = 12;
+ }
+ }
+
+ if(npcinfo[npcnum].spriteset == 9 || npcinfo[npcnum].spriteset == 10 || npcinfo[npcnum].spriteset == 5) {
+ ff = (int)(RND() * player.level * 2);
+ if(ff == 0) {
+ npx = npcinfo[npcnum].x + 12;
+ npy = npcinfo[npcnum].y + 20;
+
+ lx = (int)npx / 16;
+ ly = (int)npy / 16;
+
+ if(objmap[lx][ly] == -1) objmap[lx][ly] = 13;
+ }
+ }
+
+ // academy master key chest script
+ if(npcinfo[npcnum].script == 2) {
+ cx = 9;
+ cy = 7;
+
+ alive = 0;
+ for(int i = 1; i <= lastnpc; i++) {
+ if(npcinfo[i].hp > 0) alive = 1;
+ }
+
+ if(alive == 0) {
+ objmap[cx][cy] = 5;
+
+ rcDest.x = cx * 8;
+ rcDest.y = cy * 8;
+ rcDest.w = 8;
+ rcDest.h = 8;
+
+ npx = player.px + 12;
+ npy = player.py + 20;
+
+ lx = (int)npx / 16;
+ ly = (int)npy / 16;
+
+ if(lx == cx && ly == cy) player.py = player.py + 16;
+ SDL_FillRect(clipbg2, &rcDest, SDL_MapRGB(clipbg->format, 255,255,255));
+ scriptflag[2][0] = 1;
+ }
+ }
+
+ // academy crystal chest script
+ if(npcinfo[npcnum].script == 3) {
+ cx = 9;
+ cy = 7;
+
+ alive = 0;
+ for(int i = 1; i <= lastnpc; i++) {
+ if(npcinfo[i].hp > 0) alive = 1;
+ }
+
+ if(alive == 0) {
+ objmap[cx][cy] = 6;
+
+ rcDest.x = cx * 8;
+ rcDest.y = cy * 8;
+ rcDest.w = 8;
+ rcDest.h = 8;
+
+ npx = player.px + 12;
+ npy = player.py + 20;
+
+ lx = (int)npx / 16;
+ ly = (int)npy / 16;
+
+ if(lx == cx && ly == cy) player.py = player.py + 16;
+ scriptflag[3][0] = 1;
+ SDL_FillRect(clipbg2, &rcDest, SDL_MapRGB(clipbg->format, 255,255,255));
+ }
+ }
+
+ // tower shield chest script
+ if(npcinfo[npcnum].script == 4 && scriptflag[4][0] == 0) {
+ triggerloc[9][7] = 5004;
+
+ int curtile = 40;
+ int curtilel = 0;
+ int curtilex = curtile % 20;
+ int curtiley = (curtile - curtilex) / 20;
+
+ int l = 0; // ?? not defined in original code
+ tileinfo[l][9][7][0] = curtile + 1;
+ tileinfo[l][9][7][1] = 0;
+
+ rcSrc.x = curtilex * 16;
+ rcSrc.y = curtiley * 16;
+ rcSrc.w = 16;
+ rcSrc.h = 16;
+
+ rcDest.x = 9 * 16;
+ rcDest.y = 7 * 16;
+ rcDest.w = 16;
+ rcDest.h = 16;
+
+ SDL_BlitSurface(tiles[curtilel], &rcSrc, mapbg, &rcDest);
+ }
+
+ // firehydra sword chest
+ if(npcinfo[npcnum].script == 5) {
+ cx = 9;
+ cy = 6;
+
+ alive = 0;
+ for(int i = 1; i <= lastnpc; i++) {
+ if(npcinfo[i].hp > 0) alive = 1;
+ }
+
+ if(alive == 0) {
+ objmap[cx][cy] = 9;
+
+ rcDest.x = cx * 8;
+ rcDest.y = cy * 8;
+ rcDest.w = 8;
+ rcDest.h = 8;
+
+ npx = player.px + 12;
+ npy = player.py + 20;
+
+ lx = (int)npx / 16;
+ ly = (int)npy / 16;
+
+ if(lx == cx && ly == cy) player.py = player.py + 16;
+ scriptflag[5][0] = 1;
+ SDL_FillRect(clipbg2, &rcDest, SDL_MapRGB(clipbg->format, 255,255,255));
+ }
+
+ }
+
+ // gardens master key script
+ if(npcinfo[npcnum].script == 8 && scriptflag[6][0] == 0) {
+ cx = 13;
+ cy = 7;
+
+ alive = 0;
+ for(int i = 1; i <= lastnpc; i++) {
+ if(npcinfo[i].hp > 0) alive = 1;
+ }
+
+ if(alive == 0) {
+ objmap[cx][cy] = 5;
+
+ rcDest.x = cx * 8;
+ rcDest.y = cy * 8;
+ rcDest.w = 8;
+ rcDest.h = 8;
+
+ npx = player.px + 12;
+ npy = player.py + 20;
+
+ lx = (int)npx / 16;
+ ly = (int)npy / 16;
+
+ if(lx == cx && ly == cy) player.py = player.py + 16;
+ SDL_FillRect(clipbg2, &rcDest, SDL_MapRGB(clipbg->format, 255,255,255));
+ scriptflag[8][0] = 1;
+ }
+ }
+
+ // regular key chest 1
+ for(int s = 20; s <= 23; s++) {
+ if(npcinfo[npcnum].script == s && scriptflag[s][0] < 2) {
+ cx = 9;
+ cy = 7;
+
+ alive = 0;
+ for(int i = 1; i <= lastnpc; i++) {
+ if(npcinfo[i].hp > 0) alive = 1;
+ }
+
+ if(alive == 0) {
+ objmap[cx][cy] = 11;
+
+ rcDest.x = cx * 8;
+ rcDest.y = cy * 8;
+ rcDest.w = 8;
+ rcDest.h = 8;
+
+ npx = player.px + 12;
+ npy = player.py + 20;
+
+ lx = (int)npx / 16;
+ ly = (int)npy / 16;
+
+ if(lx == cx && ly == cy) player.py = player.py + 16;
+ scriptflag[s][0] = 1;
+ SDL_FillRect(clipbg2, &rcDest, SDL_MapRGB(clipbg->format, 255,255,255));
+ }
+ }
+ }
+
+ // pickup lightning bomb
+ if(npcinfo[npcnum].script == 9 && (curmap == 41 && scriptflag[9][1] == 0)) {
+ cx = 9;
+ cy = 7;
+
+ alive = 0;
+ for(int i = 1; i <= lastnpc; i++) {
+ if(npcinfo[i].hp > 0) alive = 1;
+ }
+
+ if(alive == 0) {
+ objmap[cx][cy] = 13;
+
+ rcDest.x = cx * 8;
+ rcDest.y = cy * 8;
+ rcDest.w = 8;
+ rcDest.h = 8;
+
+ npx = player.px + 12;
+ npy = player.py + 20;
+
+ lx = (int)npx / 16;
+ ly = (int)npy / 16;
+
+ if(lx == cx && ly == cy) player.py = player.py + 16;
+ }
+ }
+
+ // citadel armour chest
+ if(npcinfo[npcnum].script == 12) {
+ cx = 8;
+ cy = 7;
+
+ alive = 0;
+ for(int i = 1; i <= lastnpc; i++) {
+ if(npcinfo[i].hp > 0) alive = 1;
+ }
+
+ if(alive == 0) {
+ objmap[cx][cy] = 16;
+
+ rcDest.x = cx * 8;
+ rcDest.y = cy * 8;
+ rcDest.w = 8;
+ rcDest.h = 8;
+
+ npx = player.px + 12;
+ npy = player.py + 20;
+
+ lx = (int)npx / 16;
+ ly = (int)npy / 16;
+
+ if(lx == cx && ly == cy) player.py = player.py + 16;
+ scriptflag[12][0] = 1;
+ SDL_FillRect(clipbg2, &rcDest, SDL_MapRGB(clipbg->format, 255,255,255));
+ }
+ }
+
+ // citadel master key script
+ if(npcinfo[npcnum].script == 13 && scriptflag[13][0] == 0) {
+ cx = 11;
+ cy = 10;
+
+ alive = 0;
+ for(int i = 1; i <= lastnpc; i++) {
+ if(npcinfo[i].hp > 0) alive = 1;
+ }
+
+ if(alive == 0) {
+ objmap[cx][cy] = 5;
+
+ rcDest.x = cx * 8;
+ rcDest.y = cy * 8;
+ rcDest.w = 8;
+ rcDest.h = 8;
+
+ npx = player.px + 12;
+ npy = player.py + 20;
+
+ lx = (int)npx / 16;
+ ly = (int)npy / 16;
+
+ if(lx == cx && ly == cy) player.py = player.py + 16;
+ SDL_FillRect(clipbg2, &rcDest, SDL_MapRGB(clipbg->format, 255,255,255));
+ scriptflag[13][0] = 1;
+ }
+ }
+
+ // max ups
+ if(npcinfo[npcnum].script == 15 && scriptflag[15][0] == 0) {
+ alive = 0;
+ for(int i = 1; i <= lastnpc; i++) {
+ if(npcinfo[i].hp > 0) alive = 1;
+ }
+
+ if(alive == 0) {
+ cx = 6;
+ cy = 8;
+
+ objmap[cx][cy] = 18;
+
+ rcDest.x = cx * 8;
+ rcDest.y = cy * 8;
+ rcDest.w = 8;
+ rcDest.h = 8;
+
+ npx = player.px + 12;
+ npy = player.py + 20;
+
+ lx = (int)npx / 16;
+ ly = (int)npy / 16;
+
+ if(lx == cx && ly == cy) player.py = player.py + 16;
+ SDL_FillRect(clipbg2, &rcDest, SDL_MapRGB(clipbg->format, 255,255,255));
+ scriptflag[15][0] = 1;
+
+ cx = 9;
+ cy = 8;
+
+ objmap[cx][cy] = 19;
+
+ rcDest.x = cx * 8;
+ rcDest.y = cy * 8;
+ rcDest.w = 8;
+ rcDest.h = 8;
+
+ npx = player.px + 12;
+ npy = player.py + 20;
+
+ lx = (int)npx / 16;
+ ly = (int)npy / 16;
+
+ if(lx == cx && ly == cy) player.py = player.py + 16;
+ SDL_FillRect(clipbg2, &rcDest, SDL_MapRGB(clipbg->format, 255,255,255));
+
+ scriptflag[16][0] = 1;
+
+ cx = 12;
+ cy = 8;
+
+ objmap[cx][cy] = 20;
+
+ rcDest.x = cx * 8;
+ rcDest.y = cy * 8;
+ rcDest.w = 8;
+ rcDest.h = 8;
+
+ npx = player.px + 12;
+ npy = player.py + 20;
+
+ lx = (int)npx / 16;
+ ly = (int)npy / 16;
+
+ if(lx == cx && ly == cy) player.py = player.py + 16;
+ SDL_FillRect(clipbg2, &rcDest, SDL_MapRGB(clipbg->format, 255,255,255));
+ scriptflag[17][0] = 1;
+ }
+ }
+
+ if(npcinfo[npcnum].script == 14) game_endofgame();
+ }
+}
+
+void game_damageplayer(int damage)
+{
+ char line[256];
+
+ player.hp -= damage;
+ if(player.hp < 0) player.hp = 0;
+
+ sprintf(line, "-%i", damage);
+ if(damage == 0) strcpy(line, "miss!");
+
+ game_addFloatText(line, player.px + 12 - 4 * strlen(line), player.py + 16, 4);
+
+ player.pause = ticks + 1000;
+}
+
+void game_drawanims(int Layer)
+{
+ for(int sx = 0; sx <= 19; sx++) {
+ for(int sy = 0; sy <= 14; sy++) {
+ int o = objmap[sx][sy];
+
+ if(o > -1) {
+ int xtiles = objectinfo[o][1];
+ int ytiles = objectinfo[o][2];
+ int cframe = objectframe[o][1];
+
+ for(int x = 0; x <= xtiles - 1; x++) {
+ for(int y = 0; y <= ytiles - 1; y++) {
+ int x1 = (sx + x) * 16;
+ int y1 = (sy + y) * 16;
+
+ if(objecttile[o][cframe][x][y][1] == Layer) {
+ int c = objecttile[o][cframe][x][y][0];
+ c = c - 1;
+ int curtilel = 3;
+ int curtilex = c % 20;
+ int curtiley = (c - curtilex) / 20;
+
+ if(curmap == 58 && scriptflag[60][0] > 0) curtilex = 1;
+ if(curmap == 54 && scriptflag[60][0] > 1) curtilex = 1;
+ rcSrc.x = curtilex * 16;
+ rcSrc.y = curtiley * 16;
+ rcSrc.w = 16;
+ rcSrc.h = 16;
+
+ rcDest.x = x1;
+ rcDest.y = y1;
+ rcDest.w = 16;
+ rcDest.h = 16;
+
+ SDL_BlitSurface(tiles[curtilel], &rcSrc, videobuffer, &rcDest);
+ }
+
+ if(Layer == 1) {
+ for(int l = 1; l <= 2; l++) {
+ int c = tileinfo[l][sx + x][sy + y][0];
+ if(c > 0) {
+ int cl = tileinfo[l][sx + x][sy + y][1];
+
+ c = c - 1;
+ int curtile = c;
+ int curtilel = cl;
+ int curtilex = c % 20;
+ int curtiley = (c - curtilex) / 20;
+
+ rcSrc.x = curtilex * 16;
+ rcSrc.y = curtiley * 16;
+ rcSrc.w = 16;
+ rcSrc.h = 16;
+
+ rcDest.x = (sx + x) * 16;
+ rcDest.y = (sy + y) * 16;
+ rcDest.w = 16;
+ rcDest.h = 16;
+
+ int pass = 1;
+ if(curtilel == 1) {
+ for(int ff = 0; ff <= 5; ff++) {
+ int ffa = 20 * 5 - 1 + ff * 20;
+ int ffb = 20 * 5 + 4 + ff * 20;
+ if(curtile > ffa && curtile < ffb) pass = 0;
+ }
+ }
+
+ if(pass == 1) SDL_BlitSurface(tiles[curtilel], &rcSrc, videobuffer, &rcDest);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+int hud_recalc(int a, int b, int c)
+{
+ int result = a * b / c;
+
+ return result > b ? b : result;
+}
+
+#define RGB(R, G, B) (SDL_MapRGB(videobuffer->format, (R), (G), (B)))
+
+void game_drawhud()
+{
+ char line[128];
+ //sprintf(line, "fps: %i, map: %i, exp: %i/%i", (int)fps, curmap, player.exp, player.nextlevel);
+ //sys_print(videobuffer, line, 0, 0, 0);
+
+ long ccc;
+
+ game_fillrect(videobuffer2, 0, 0, 320, 240, 0);
+
+ for(int i = 0; i < MAXFLOAT; i++) {
+ if(floattext[i][0] > 0) {
+ int fc = (int)floattext[i][3];
+ int c = fc, c2 = 3;
+
+ if(fc == 4) c = 1; else if(fc == 5) c = 0;
+
+ if(fc == 1 || fc == 3) c2 = 2;
+
+ if(fc != 0) {
+ sys_print(videobuffer, floatstri[i], (int)(floattext[i][1]) + 0, (int)(floattext[i][2]) - 1, c2);
+ sys_print(videobuffer, floatstri[i], (int)(floattext[i][1]) + 0, (int)(floattext[i][2]) + 1, c2);
+ sys_print(videobuffer, floatstri[i], (int)(floattext[i][1]) - 1, (int)(floattext[i][2]) + 0, c2);
+ sys_print(videobuffer, floatstri[i], (int)(floattext[i][1]) + 1, (int)(floattext[i][2]) + 0, c2);
+ }
+
+ sys_print(videobuffer, floatstri[i], (int)(floattext[i][1]), (int)(floattext[i][2]), c);
+ }
+
+ if(floaticon[i][0] > 0) {
+ int ico = floaticon[i][3];
+ int ix = floaticon[i][1];
+ int iy = floaticon[i][2];
+
+ rcDest.x = ix;
+ rcDest.y = iy;
+
+ if(ico != 99) SDL_BlitSurface(itemimg[ico], NULL, videobuffer, &rcDest);
+ if(ico == 99) {
+ SDL_SetAlpha(spellimg, SDL_SRCALPHA, (int)(RND() * 96) + 96);
+
+ rcSrc.x = 16 * (int)(RND() * 2);
+ rcSrc.y = 80;
+ rcSrc.w = 16;
+ rcSrc.h = 16;
+
+ rcDest.x = ix;
+ rcDest.y = iy;
+
+ SDL_BlitSurface(spellimg, &rcSrc, videobuffer, &rcDest);
+
+ SDL_SetAlpha(spellimg, SDL_SRCALPHA, 255);
+ }
+ }
+ }
+
+ if(itemselon == 0) {
+ int sy = 211;
+
+
+ int nx = 19 * 8 + 13;
+ rcSrc.x = nx - 17 + 48;
+ rcSrc.y = sy;
+
+ // spells in game
+ if(player.foundspell[0] == 1) {
+ for(int i = 0; i < 5; i++) {
+ rcSrc.x = rcSrc.x + 17;
+
+ if(player.foundspell[i] == 1) {
+ SDL_BlitSurface(itemimg[7 + i], NULL, videobuffer, &rcSrc);
+
+ game_fillrect(videobuffer, rcSrc.x, sy + 16, 16, 4, RGB(0, 32, 32));
+ game_fillrect(videobuffer, rcSrc.x + 1, sy + 17,
+ hud_recalc(player.spellcharge[i], 14, 100), 2,
+ player.spellcharge[i] == 100 ? RGB(255, 128, 32) : RGB(0, 224, 64));
+ }
+ }
+ }
+ return;
+ }
+
+ if(selenemyon == 0) {
+ rcDest.x = 0;
+ rcDest.y = 0;
+ rcDest.w = 320;
+ rcDest.h = 240;
+ SDL_SetAlpha(videobuffer2, SDL_SRCALPHA, (int)(player.itemselshade * 4));
+ SDL_FillRect(videobuffer2, &rcDest, 0);
+ SDL_BlitSurface(videobuffer2, NULL, videobuffer, NULL);
+
+ int sy = 202;
+ rcSrc.x = 46;
+ rcSrc.y = 46;
+
+ SDL_SetAlpha(inventoryimg, SDL_SRCALPHA, 160); // 128
+ SDL_BlitSurface(inventoryimg, NULL, videobuffer, &rcSrc);
+ SDL_SetAlpha(inventoryimg, SDL_SRCALPHA, 255);
+
+ int sx = 54;
+ sy = 55;
+
+ // draw map 9,77
+ rcDest.x = 46 + 9;
+ rcDest.y = 46 + 77;
+
+ int amap = 0;
+ if(curmap > 46) amap = 2;
+ if(curmap > 67) amap = 3;
+ if(curmap > 5 && curmap < 42) amap = 1;
+ SDL_BlitSurface(mapimg[amap], NULL, videobuffer, &rcDest);
+
+ ccc = SDL_MapRGB(videobuffer->format, 128 + 127 * sin(3.141592 * 2 * itemyloc / 16), 0, 0);
+
+ for(int b = 0; b <= 6; b++) {
+ for(int a = 0; a <= 12; a++) {
+ if(invmap[amap][b][a] == curmap) {
+ game_fillrect(videobuffer, 46 + 9 + a * 9 + 2, 46 + 77 + b * 9 + 1, 6, 6, ccc);
+ }
+ }
+ }
+
+ if(amap == 1) {
+ sys_print(videobuffer, "L1", 46 + 9, 46 + 77, 0);
+ sys_print(videobuffer, "L2", 46 + 9 + 7 * 9, 46 + 77, 0);
+ }
+
+ sprintf(line, "Health: %i/%i", player.hp, player.maxhp);
+ sys_print(videobuffer, line, sx, sy, player.hp <= player.maxhp * 0.25 ? (int)player.hpflash : 0);
+
+ sprintf(line, "Level : %i", player.level);
+ if(player.level == player.maxlevel) strcpy(line, "Level : MAX");
+ sys_print(videobuffer, line, sx, sy + 8, 0);
+
+ // experience
+ game_fillrect(videobuffer, sx + 64, sy + 16, 16, 4, RGB(0, 32, 32));
+ game_fillrect(videobuffer, sx + 65, sy + 17,
+ hud_recalc(player.exp, 14, player.nextlevel), 2, RGB(0, 224, 64));
+
+ // attack strength
+ game_fillrect(videobuffer, sx + 1, sy + 16, 56, 6, RGB(0, 32, 32));
+ game_fillrect(videobuffer, sx + 1, sy + 17,
+ hud_recalc(player.attackstrength, 54, 100), 2,
+ player.attackstrength == 100 ? RGB(255, 128, 32) : RGB(0, 64, 224));
+
+ // spell strength
+ game_fillrect(videobuffer, sx + 1, sy + 19,
+ hud_recalc(player.spellstrength, 54, 100), 2,
+ player.spellstrength == 100 ? RGB(224, 0, 0) : RGB(128, 0, 224));
+
+ // time
+ int ase = secstart + secsingame;
+ int h = ((ase - (ase % 3600)) / 3600);
+ ase = (ase - h * 3600);
+ int m = ((ase - (ase % 60)) / 60);
+ int s = (ase - m * 60);
+
+ sprintf(line, "%02i:%02i:%02i", h, m, s);
+ sys_print(videobuffer, line, 46 + 38 - strlen(line) * 4, 46 + 49, 0);
+
+ sys_print(videobuffer, "Use", 193, 55, 0);
+ sys_print(videobuffer, "Cast", 236, 55, 0);
+
+ rcSrc.x = 128;
+ rcSrc.y = 91;
+
+ int ss = (player.sword - 1) * 3;
+ if(player.sword == 3) ss = 18;
+ SDL_BlitSurface(itemimg[ss], NULL, videobuffer, &rcSrc);
+
+ rcSrc.x = rcSrc.x + 16;
+ ss = (player.shield - 1) * 3 + 1;
+ if(player.shield == 3) ss = 19;
+ SDL_BlitSurface(itemimg[ss], NULL, videobuffer, &rcSrc);
+
+ rcSrc.x = rcSrc.x + 16;
+ ss = (player.armour - 1) * 3 + 2;
+ if(player.armour == 3) ss = 20;
+ SDL_BlitSurface(itemimg[ss], NULL, videobuffer, &rcSrc);
+
+ for(int i = 0; i <= 4; i++) {
+ sx = 188;
+ sy = 70 + i * 24;
+ rcSrc.x = sx;
+ rcSrc.y = sy;
+ if(i == 0) SDL_BlitSurface(itemimg[6], NULL, videobuffer, &rcSrc);
+ if(i == 1) SDL_BlitSurface(itemimg[12], NULL, videobuffer, &rcSrc);
+ if(i == 2) SDL_BlitSurface(itemimg[17], NULL, videobuffer, &rcSrc);
+ if(i == 3) SDL_BlitSurface(itemimg[16], NULL, videobuffer, &rcSrc);
+ if(i == 4) SDL_BlitSurface(itemimg[14], NULL, videobuffer, &rcSrc);
+
+ sprintf(line, "x%i", player.inventory[i]);
+ sys_print(videobuffer, line, sx + 17, sy + 7, 0);
+ }
+
+ // spells in menu
+ if(player.foundspell[0] == 1) {
+ for(int i = 0; i < 5; i++) {
+ rcSrc.x = 243;
+ rcSrc.y = 67 + i * 24;
+ sy = rcSrc.y;
+
+ if(player.foundspell[i] == 1) {
+ SDL_BlitSurface(itemimg[7 + i], NULL, videobuffer, &rcSrc);
+
+ game_fillrect(videobuffer, rcSrc.x, sy + 16, 16, 4, RGB(0, 32, 32));
+ game_fillrect(videobuffer, rcSrc.x + 1, sy + 17,
+ hud_recalc(player.spellcharge[i], 14, 100), 2,
+ player.spellcharge[i] == 100 ? RGB(255, 128, 32) : RGB(0, 224, 64));
+ }
+ }
+ }
+
+ if(itemselon == 1) {
+ for(int i = 0; i <= 4; i++) {
+ if(curitem == 5 + i) {
+ rcDest.x = (float)(243 - 12 + 3 * sin(3.141592 * 2 * itemyloc / 16));
+ rcDest.y = 67 + 24 * i;
+ SDL_BlitSurface(itemimg[15], NULL, videobuffer, &rcDest);
+ }
+
+ if(curitem == i) {
+ rcDest.x = (float)(189 - 12 + 3 * sin(3.141592 * 2 * itemyloc / 16));
+ rcDest.y = 70 + 24 * i;
+ SDL_BlitSurface(itemimg[15], NULL, videobuffer, &rcDest);
+ }
+ }
+ }
+ }
+
+ if(selenemyon == 1) {
+ if(curenemy > lastnpc) {
+ int pst = curenemy - lastnpc - 1;
+ rcDest.x = postinfo[pst][0];
+ rcDest.y = (float)(postinfo[pst][1] - 4 - sin(3.141592 / 8 * itemyloc));
+ } else {
+ rcDest.x = npcinfo[curenemy].x + 4;
+ rcDest.y = (float)(npcinfo[curenemy].y + 4 - 16 - sin(3.141592 / 8 * itemyloc));
+ }
+
+ SDL_BlitSurface(itemimg[13], NULL, videobuffer, &rcDest);
+ }
+}
+
+void game_drawnpcs(int mode)
+{
+ unsigned int ccc;
+
+ ccc = SDL_MapRGB(videobuffer->format, 255, 128, 32);
+
+ int fst = firsty;
+ int lst = lasty;
+
+ if(mode == 0) lst = player.ysort;
+ if(mode == 1) fst = player.ysort;
+
+ for(int yy = fst; yy <= lst; yy++) {
+
+ if(ysort[yy] > 0) {
+ int i = ysort[yy];
+
+ if(npcinfo[i].hp > 0) {
+ int npx = (int)(npcinfo[i].x);
+ int npy = (int)(npcinfo[i].y);
+
+ int sprite = npcinfo[i].spriteset;
+
+ int wdir = npcinfo[i].walkdir;
+
+ // spriteset1 specific
+ if(npcinfo[i].spriteset == 1) {
+
+ if(npcinfo[i].attacking == 0) {
+
+ int cframe = npcinfo[i].cframe;
+
+ rcSrc.x = (int)(cframe / 4) * 24;
+ rcSrc.y = wdir * 24;
+ rcSrc.w = 24;
+ rcSrc.h = 24;
+
+ rcDest.x = npx;
+ rcDest.y = npy;
+ rcDest.w = 24;
+ rcDest.h = 24;
+
+ if(npcinfo[i].pause > ticks && npcinfo[i].shake < ticks) {
+ npcinfo[i].shake = ticks + 50;
+ rcDest.x = rcDest.x + (int)(RND() * 3) - 1;
+ rcDest.y = rcDest.y + (int)(RND() * 3) - 1;
+ }
+
+ SDL_BlitSurface(anims[sprite], &rcSrc, videobuffer, &rcDest);
+ } else {
+ int cframe = npcinfo[i].cattackframe;
+
+ rcSrc.x = (int)(cframe / 4) * 24;
+ rcSrc.y = wdir * 24;
+ rcSrc.w = 24;
+ rcSrc.h = 24;
+
+ rcDest.x = npx;
+ rcDest.y = npy;
+ rcDest.w = 24;
+ rcDest.h = 24;
+
+ SDL_BlitSurface(animsa[sprite], &rcSrc, videobuffer, &rcDest);
+ }
+
+ }
+
+ // onewing
+ if(npcinfo[i].spriteset == 2) {
+ for(int f = 0; f <= 7; f++) {
+ int s = npcinfo[i].bodysection[f].sprite;
+ rcSrc.x = animset2[s].x;
+ rcSrc.y = animset2[s].y;
+ rcSrc.w = animset2[s].w;
+ rcSrc.h = animset2[s].h;
+
+ rcDest.x = npcinfo[i].bodysection[f].x - animset2[s].xofs;
+ rcDest.y = npcinfo[i].bodysection[f].y - animset2[s].yofs + 2;
+
+ SDL_BlitSurface(anims[2], &rcSrc, videobuffer, &rcDest);
+ }
+
+ }
+
+ // twowing
+ if(npcinfo[i].spriteset == 9) {
+ for(int f = 0; f <= 7; f++) {
+ int yp = 0;
+
+ if(f == 0 && (curmap == 53 || curmap == 57 || curmap == 61 || curmap == 65 || curmap == 56 || curmap > 66) && scriptflag[60][0] > 0) yp = 16;
+ int s = npcinfo[i].bodysection[f].sprite;
+ rcSrc.x = animset9[s].x;
+ rcSrc.y = animset9[s].y + yp;
+ rcSrc.w = animset9[s].w;
+ rcSrc.h = animset9[s].h;
+
+ rcDest.x = npcinfo[i].bodysection[f].x - animset9[s].xofs;
+ rcDest.y = npcinfo[i].bodysection[f].y - animset9[s].yofs + 2;
+
+ SDL_BlitSurface(anims[9], &rcSrc, videobuffer, &rcDest);
+ }
+
+ }
+
+
+ // boss 1
+ if(npcinfo[i].spriteset == 3) {
+ if(npcinfo[i].attacking == 0) {
+ int cframe = npcinfo[i].cframe;
+
+ rcSrc.x = (int)(cframe / 4) * 24;
+ rcSrc.y = 0;
+ rcSrc.w = 24;
+ rcSrc.h = 48;
+
+ rcDest.x = npx - 2;
+ rcDest.y = npy - 24;
+
+ SDL_BlitSurface(anims[3], &rcSrc, videobuffer, &rcDest);
+ } else {
+ rcSrc.x = 4 * 24;
+ rcSrc.y = 0;
+ rcSrc.w = 24;
+ rcSrc.h = 48;
+
+ rcDest.x = npx - 2;
+ rcDest.y = npy - 24;
+
+ SDL_BlitSurface(anims[3], &rcSrc, videobuffer, &rcDest);
+ }
+
+ }
+
+ // black knight
+ if(npcinfo[i].spriteset == 4) {
+ if(npcinfo[i].attacking == 0) {
+ int cframe = npcinfo[i].cframe;
+
+ rcSrc.x = (int)(cframe / 4) * 24;
+ rcSrc.y = 0;
+ rcSrc.w = 24;
+ rcSrc.h = 48;
+
+ rcDest.x = npx - 2;
+ rcDest.y = npy - 24;
+
+ SDL_BlitSurface(anims[4], &rcSrc, videobuffer, &rcDest);
+ } else {
+ rcSrc.x = 4 * 24;
+ rcSrc.y = 0;
+ rcSrc.w = 24;
+ rcSrc.h = 48;
+
+ rcDest.x = npx - 2;
+ rcDest.y = npy - 24;
+
+ SDL_BlitSurface(anims[4], &rcSrc, videobuffer, &rcDest);
+ }
+ }
+
+
+ // firehydra
+ if(npcinfo[i].spriteset == 5) {
+ for(int ff = 0; ff <= 2; ff++) {
+ if(npcinfo[i].hp > 10 * ff * 20) {
+ rcSrc.x = 16 * (int)(RND() * 2);
+ rcSrc.y = 80;
+ rcSrc.w = 16;
+ rcSrc.h = 16;
+
+ rcDest.x = npcinfo[i].bodysection[10 * ff].x - 8;
+ rcDest.y = npcinfo[i].bodysection[10 * ff].y - 8;
+
+ int x = 192 + ((int)(itemyloc + ff * 5) % 3) * 64;
+ if(x > 255) x = 255;
+ SDL_SetAlpha(spellimg, SDL_SRCALPHA, x);
+ SDL_BlitSurface(spellimg, &rcSrc, videobuffer, &rcDest);
+ SDL_SetAlpha(spellimg, SDL_SRCALPHA, 255);
+
+ for(int f = 1; f <= 8; f++) {
+ rcSrc.x = 16 * (int)(RND() * 2);
+ rcSrc.y = 80;
+ rcSrc.w = 16;
+ rcSrc.h = 16;
+
+ rcDest.x = npcinfo[i].bodysection[ff * 10 + f].x - 8 + (int)(RND() * 3) - 1;
+ rcDest.y = npcinfo[i].bodysection[ff * 10 + f].y - 8 + (int)(RND() * 3) - 1;
+
+ x = 192 + f % 3 * 64;
+ if(x > 255) x = 255;
+ SDL_SetAlpha(spellimg, SDL_SRCALPHA, x);
+ SDL_BlitSurface(spellimg, &rcSrc, videobuffer, &rcDest);
+ SDL_SetAlpha(spellimg, SDL_SRCALPHA, 255);
+ }
+
+ rcSrc.x = 0;
+ rcSrc.y = 0;
+ rcSrc.w = 42;
+ rcSrc.h = 36;
+
+ rcDest.x = npcinfo[i].bodysection[10 * ff + 9].x - 21;
+ rcDest.y = npcinfo[i].bodysection[10 * ff + 9].y - 21;
+
+ SDL_SetAlpha(spellimg, SDL_SRCALPHA, 192);
+ SDL_BlitSurface(anims[5], &rcSrc, videobuffer, &rcDest);
+ SDL_SetAlpha(spellimg, SDL_SRCALPHA, 255);
+
+ }
+
+ }
+
+ }
+
+ // red dragon
+ if(npcinfo[i].spriteset == 6) {
+ int cframe = npcinfo[i].cframe;
+
+ rcSrc.x = (int)(cframe / 4) * 24;
+ rcSrc.y = wdir * 24;
+ rcSrc.w = 24;
+ rcSrc.h = 24;
+
+ rcDest.x = npx;
+ rcDest.y = npy;
+ rcDest.w = 24;
+ rcDest.h = 24;
+
+ if(npcinfo[i].pause > ticks && npcinfo[i].shake < ticks) {
+ npcinfo[i].shake = ticks + 50;
+ rcDest.x = rcDest.x + (int)(RND() * 3) - 1;
+ rcDest.y = rcDest.y + (int)(RND() * 3) - 1;
+ }
+
+ SDL_BlitSurface(anims[sprite], &rcSrc, videobuffer, &rcDest);
+ }
+
+ // wizard
+ if(npcinfo[i].spriteset == 7) {
+ // if(npcinfo[i].attacking == 0) {
+ int cframe = npcinfo[i].cframe;
+
+ rcSrc.x = (int)(cframe / 4) * 24;
+ rcSrc.y = wdir * 24;
+ rcSrc.w = 24;
+ rcSrc.h = 24;
+
+ rcDest.x = npx;
+ rcDest.y = npy;
+ rcDest.w = 24;
+ rcDest.h = 24;
+
+ if(npcinfo[i].pause > ticks && npcinfo[i].shake < ticks) {
+ npcinfo[i].shake = ticks + 50;
+ rcDest.x = rcDest.x + (int)(RND() * 3) - 1;
+ rcDest.y = rcDest.y + (int)(RND() * 3) - 1;
+ }
+ SDL_BlitSurface(anims[sprite], &rcSrc, videobuffer, &rcDest);
+ // } else {
+ //cframe = npcinfo[i].cattackframe;
+
+ //rcSrc.x = (int)(cframe / 4) * 24;
+ //rcSrc.y = wdir * 24;
+ //rcSrc.w = 24;
+ //rcSrc.h = 24;
+
+ //rcDest.x = npx;
+ //rcDest.y = npy;
+ //rcDest.w = 24;
+ //rcDest.h = 24;
+ // SDL_BlitSurface(animsa(sprite), &rcSrc, videobuffer, &rcDest);
+ // }
+ }
+
+
+ // yellow dragon
+ if(npcinfo[i].spriteset == 8) {
+ int cframe = npcinfo[i].cframe;
+
+ rcSrc.x = (int)(cframe / 4) * 24;
+ rcSrc.y = wdir * 24;
+ rcSrc.w = 24;
+ rcSrc.h = 24;
+
+ rcDest.x = npx;
+ rcDest.y = npy;
+ rcDest.w = 24;
+ rcDest.h = 24;
+
+ if(npcinfo[i].pause > ticks && npcinfo[i].shake < ticks) {
+ npcinfo[i].shake = ticks + 50;
+ rcDest.x = rcDest.x + (int)(RND() * 3) - 1;
+ rcDest.y = rcDest.y + (int)(RND() * 3) - 1;
+ }
+ SDL_BlitSurface(anims[sprite], &rcSrc, videobuffer, &rcDest);
+ }
+
+
+ // dragon2
+ if(npcinfo[i].spriteset == 10) {
+ if(npcinfo[i].attacking == 0) {
+ npcinfo[i].floating = npcinfo[i].floating + 0.25 * fpsr;
+ while(npcinfo[i].floating >= 16) npcinfo[i].floating = npcinfo[i].floating - 16;
+
+ float frame = npcinfo[i].frame;
+ int cframe = npcinfo[i].cframe;
+
+ frame = frame + 0.5 * fpsr;
+ while(frame >= 16)
+ frame = frame - 16;
+
+ cframe = (int)(frame);
+ if(cframe > 16) cframe = 16 - 1;
+ if(cframe < 0) cframe = 0;
+
+ npcinfo[i].frame = frame;
+ npcinfo[i].cframe = cframe;
+
+ cframe = npcinfo[i].cframe;
+
+ rcSrc.x = 74 * wdir;
+ rcSrc.y = (int)(cframe / 4) * 48;
+ rcSrc.w = 74;
+ rcSrc.h = 48;
+
+ rcDest.x = npx + 12 - 37;
+ rcDest.y = (float)(npy + 12 - 32 - 3 * sin(3.141592 * 2 * npcinfo[i].floating / 16));
+ rcDest.w = 24;
+ rcDest.h = 24;
+
+ if(npcinfo[i].pause > ticks && npcinfo[i].shake < ticks) {
+ npcinfo[i].shake = ticks + 50;
+ rcDest.x = rcDest.x + (int)(RND() * 3) - 1;
+ rcDest.y = rcDest.y + (int)(RND() * 3) - 1;
+ }
+
+ SDL_BlitSurface(anims[sprite], &rcSrc, videobuffer, &rcDest);
+ } else {
+ npcinfo[i].floating = npcinfo[i].floating + 0.25 * fpsr;
+ while(npcinfo[i].floating >= 16) npcinfo[i].floating = npcinfo[i].floating - 16;
+
+ int cframe = npcinfo[i].cattackframe;
+
+ rcSrc.x = 74 * wdir;
+ rcSrc.y = (int)(cframe / 4) * 48;
+ rcSrc.w = 74;
+ rcSrc.h = 48;
+
+ rcDest.x = npx + 12 - 37;
+ rcDest.y = (float)(npy + 12 - 32 - 3 * sin(3.141592 * 2 * npcinfo[i].floating / 16));
+ rcDest.w = 24;
+ rcDest.h = 24;
+
+ SDL_BlitSurface(animsa[sprite], &rcSrc, videobuffer, &rcDest);
+ }
+ }
+
+ // end boss
+ if(npcinfo[i].spriteset == 11) {
+
+ npcinfo[i].floating = npcinfo[i].floating + .3 * fpsr;
+ while(npcinfo[i].floating >= 16) npcinfo[i].floating = npcinfo[i].floating - 16;
+
+
+ float frame = npcinfo[i].frame2;
+
+ frame = frame + 0.5 * fpsr;
+ while(frame >= 16)
+ frame = frame - 16;
+
+ npcinfo[i].frame2 = frame;
+
+ int sx = npx + 12 - 40;
+ int sy = (float)(npy + 12 - 50 - 3 * sin(3.141592 * 2 * npcinfo[i].floating / 16));
+
+ for(int fr = 0; fr <= 3; fr++) {
+ SDL_SetAlpha(spellimg, SDL_SRCALPHA, 128 + (int)(RND() * 96));
+
+ rcSrc.x = 16 * (int)(RND() * 2);
+ rcSrc.y = 80;
+ rcSrc.w = 16;
+ rcSrc.h = 16;
+
+ rcDest.x = sx + 32 + (int)(RND() * 3) - 1;
+ rcDest.y = sy - (int)(RND() * 6);
+
+ SDL_BlitSurface(spellimg, &rcSrc, videobuffer, &rcDest);
+ }
+
+ for(int ii = 0; ii <= 8; ii++) {
+ for(int i2 = 0; i2 <= 3; i2++) {
+ rcSrc.x = 16 * (int)(RND() * 2);
+ rcSrc.y = 80;
+ rcSrc.w = 16;
+ rcSrc.h = 16;
+
+ float fr3 = frame - 3 + i2;
+ if(fr3 < 0) fr3 = fr3 + 16;
+
+ rcDest.x = (float)(sx + 36 + ii * 8 - ii * cos(3.14159 * 2 * (fr3 - ii) / 16) * 2);
+ rcDest.y = (float)(sy + 16 + ii * sin(3.14159 * 2 * (fr3 - ii) / 16) * 3 - ii); // * 4
+
+ SDL_SetAlpha(spellimg, SDL_SRCALPHA, i2 / 3 * 224);
+
+ SDL_BlitSurface(spellimg, &rcSrc, videobuffer, &rcDest);
+
+ int xloc = rcDest.x;
+ int yloc = rcDest.y;
+ int xdif = (xloc + 8) - (player.px + 12);
+ int ydif = (yloc + 8) - (player.py + 12);
+
+ if((abs(xdif) < 8 && abs(ydif) < 8) && player.pause < ticks) {
+ float damage = (float)npcinfo[i].spelldamage * (1.0 + RND() * 0.5);
+
+ if(player.hp > 0) {
+ game_damageplayer(damage);
+ if(menabled == 1 && config.effects == 1) {
+ int snd = Mix_PlayChannel(-1, sfx[sndfire], 0);
+ Mix_Volume(snd, config.effectsvol);
+ }
+ }
+
+ }
+
+
+ rcDest.x = (float)(sx + 36 - ii * 8 + ii * cos(3.14159 * 2 * (fr3 - ii) / 16) * 2);
+ rcDest.y = (float)(sy + 16 + ii * sin(3.14159 * 2 * (fr3 - ii) / 16) * 3 - ii); // * 4
+
+ SDL_SetAlpha(spellimg, SDL_SRCALPHA, i2 / 3 * 224);
+
+ SDL_BlitSurface(spellimg, &rcSrc, videobuffer, &rcDest);
+
+ xloc = rcDest.x;
+ yloc = rcDest.y;
+ xdif = (xloc + 8) - (player.px + 12);
+ ydif = (yloc + 8) - (player.py + 12);
+
+ if((abs(xdif) < 8 && abs(ydif) < 8) && player.pause < ticks) {
+ float damage = (float)npcinfo[i].spelldamage * (1.0 + RND() * 0.5);
+
+ if(player.hp > 0) {
+ game_damageplayer(damage);
+ if(menabled == 1 && config.effects == 1) {
+ int snd = Mix_PlayChannel(-1, sfx[sndfire], 0);
+ Mix_Volume(snd, config.effectsvol);
+ }
+ }
+ }
+ }
+ }
+
+ SDL_SetAlpha(spellimg, SDL_SRCALPHA, 255);
+
+ if(npcinfo[i].attacking == 0) {
+ int cframe = (int)(frame);
+ rcSrc.x = 0;
+ rcSrc.y = 72 * (int)(cframe / 4);
+ rcSrc.w = 80;
+ rcSrc.h = 72;
+
+ rcDest.x = sx;
+ rcDest.y = sy;
+
+ if(npcinfo[i].pause > ticks && npcinfo[i].shake < ticks) {
+ npcinfo[i].shake = ticks + 50;
+ rcDest.x = rcDest.x + (int)(RND() * 3) - 1;
+ rcDest.y = rcDest.y + (int)(RND() * 3) - 1;
+ }
+
+ SDL_BlitSurface(anims[sprite], &rcSrc, videobuffer, &rcDest);
+ } else {
+ int cframe = (int)(npcinfo[i].cattackframe);
+
+ rcSrc.x = 0;
+ rcSrc.y = 72 * (int)(cframe / 4);
+ rcSrc.w = 80;
+ rcSrc.h = 72;
+
+ rcDest.x = sx;
+ rcDest.y = sy;
+
+ SDL_BlitSurface(animsa[sprite], &rcSrc, videobuffer, &rcDest);
+ }
+ }
+
+ // bat kitty
+ if(npcinfo[i].spriteset == 12) {
+ npcinfo[i].floating = npcinfo[i].floating + 1 * fpsr;
+ while(npcinfo[i].floating >= 16) npcinfo[i].floating = npcinfo[i].floating - 16;
+
+ float frame = npcinfo[i].frame;
+ int cframe = npcinfo[i].cframe;
+
+ frame = frame + 0.5 * fpsr;
+ while(frame >= 16)
+ frame = frame - 16;
+
+ cframe = (int)(frame);
+ if(cframe > 16) cframe = 16 - 1;
+ if(cframe < 0) cframe = 0;
+
+ npcinfo[i].frame = frame;
+ npcinfo[i].cframe = cframe;
+
+ cframe = npcinfo[i].cframe;
+
+ rcSrc.x = 0;
+ rcSrc.y = 0;
+ rcSrc.w = 99;
+ rcSrc.h = 80;
+
+ rcDest.x = npx + 12 - 50;
+ rcDest.y = (float)(npy + 12 - 64 + 2 * sin(3.141592 * 2 * npcinfo[i].floating / 16));
+ rcDest.w = 99;
+ rcDest.h = 80;
+
+ if(npcinfo[i].pause > ticks && npcinfo[i].shake < ticks) {
+ npcinfo[i].shake = ticks + 50;
+ rcDest.x = rcDest.x + (int)(RND() * 3) - 1;
+ rcDest.y = rcDest.y + (int)(RND() * 3) - 1;
+ }
+
+ SDL_BlitSurface(anims[sprite], &rcSrc, videobuffer, &rcDest);
+ }
+
+ rcDest.x = npx + 4;
+ rcDest.y = npy + 22;
+ rcDest.w = 16;
+ rcDest.h = 4;
+
+ SDL_FillRect(videobuffer, &rcDest, 0);
+
+ rcDest.x = npx + 5;
+ rcDest.y = npy + 23;
+
+
+ int ww = 14 * npcinfo[i].hp / npcinfo[i].maxhp;
+ if(ww > 14) ww = 14;
+ if(ww < 1) ww = 1;
+
+ rcDest.w = ww;
+ rcDest.h = 2;
+
+
+ SDL_FillRect(videobuffer, &rcDest, ccc);
+
+ int pass = 1;
+
+ if(npcinfo[i].spriteset == 3) pass = 0;
+ if(pass == 1) game_drawover(npx, npy);
+
+ }
+ }
+ }
+}
+
+void game_drawover(int modx, int mody)
+{
+ int npx = modx + 12;
+ int npy = mody + 20;
+
+ int lx = (int)npx / 16;
+ int ly = (int)npy / 16;
+
+ for(int xo = -1; xo <= 1; xo++) {
+ for(int yo = -1; yo <= 1; yo++) {
+
+ int sx = lx + xo;
+ int sy = ly + yo;
+
+ int sx2 = sx * 16;
+ int sy2 = sy * 16;
+
+ if(sx > -1 && sx < 40 && sy > -1 && sy < 24) {
+
+ int curtile = tileinfo[2][sx][sy][0];
+ int curtilel = tileinfo[2][sx][sy][1];
+
+ if(curtile > 0) {
+ curtile = curtile - 1;
+ int curtilex = curtile % 20;
+ int curtiley = (curtile - curtilex) / 20;
+
+ rcSrc.x = curtilex * 16;
+ rcSrc.y = curtiley * 16;
+ rcSrc.w = 16;
+ rcSrc.h = 16;
+
+ rcDest.x = sx2;
+ rcDest.y = sy2;
+ rcDest.w = 16;
+ rcDest.h = 16;
+
+ int pass = 1;
+ if(curtilel == 1) {
+ for(int ff = 0; ff <= 5; ff++) {
+ int ffa = 20 * 5 - 1 + ff * 20;
+ int ffb = 20 * 5 + 4 + ff * 20;
+ if(curtile > ffa && curtile < ffb) pass = 0;
+ }
+ }
+
+ if(pass == 1) SDL_BlitSurface(tiles[curtilel], &rcSrc, videobuffer, &rcDest);
+ }
+ }
+ }
+ }
+}
+
+void game_drawplayer()
+{
+ long ccc;
+
+ int f = 0;
+ if(player.armour == 3) f = 13;
+
+ if(attacking == 0) {
+ rcSrc.x = (int)(player.walkframe / 4) * 24;
+ rcSrc.y = player.walkdir * 24;
+ rcSrc.w = 24;
+ rcSrc.h = 24;
+
+ rcDest.x = (int)(player.px);
+ rcDest.y = (int)(player.py);
+ rcDest.w = 24;
+ rcDest.h = 24;
+
+ SDL_BlitSurface(anims[f], &rcSrc, videobuffer, &rcDest);
+ } else {
+ rcSrc.x = (int)(player.attackframe / 4) * 24;
+ rcSrc.y = player.walkdir * 24;
+ rcSrc.w = 24;
+ rcSrc.h = 24;
+
+ rcDest.x = (int)(player.px);
+ rcDest.y = (int)(player.py);
+ rcDest.w = 24;
+ rcDest.h = 24;
+
+ SDL_BlitSurface(animsa[f], &rcSrc, videobuffer, &rcDest);
+
+ }
+
+ ccc = SDL_MapRGB(videobuffer->format, 224, 224, 64);
+
+ int pass = 0;
+ if(player.hp <= player.maxhp * 0.25) pass = 1;
+
+ if(pass == 1) {
+ ccc = SDL_MapRGB(videobuffer->format, 255, 255, 255);
+ if((int)(player.hpflash) == 1) ccc = SDL_MapRGB(videobuffer->format, 255, 0, 0);
+ }
+
+ int sss = 6;
+ if(player.foundspell[0]) sss = 8;
+ int npx = player.px;
+ int npy = player.py;
+ rcDest.x = npx + 4;
+ rcDest.y = npy + 22;
+ rcDest.w = 16;
+ rcDest.h = sss;
+
+ SDL_FillRect(videobuffer, &rcDest, 0);
+
+ rcDest.x = npx + 5;
+ rcDest.y = npy + 23;
+
+
+ int ww = 14 * player.hp / player.maxhp;
+ if(ww > 14) ww = 14;
+ if(ww < 1) ww = 1;
+
+ rcDest.w = ww;
+ rcDest.h = 2;
+
+ SDL_FillRect(videobuffer, &rcDest, ccc);
+
+ ccc = SDL_MapRGB(videobuffer->format, 0, 224, 64);
+ if(player.attackstrength == 100) ccc = SDL_MapRGB(videobuffer->format, 255, 128, 32);
+
+ ww = 14 * player.attackstrength / 100;
+ if(ww > 14) ww = 14;
+
+ int ww2 = 14 * player.spellstrength / 100;
+ if(ww2 > 14) ww2 = 14;
+
+ rcDest.w = ww;
+ rcDest.h = 2;
+ rcDest.y = rcDest.y + 2;
+
+ SDL_FillRect(videobuffer, &rcDest, ccc);
+
+ ccc = SDL_MapRGB(videobuffer->format, 128, 0, 224);
+ if(player.spellstrength == 100) ccc = SDL_MapRGB(videobuffer->format, 224, 0, 0);
+
+ rcDest.w = ww2;
+ rcDest.h = 2;
+ rcDest.y = rcDest.y + 2;
+
+ SDL_FillRect(videobuffer, &rcDest, ccc);
+}
+
+void game_drawview()
+{
+ SDL_Rect rc;
+
+ SDL_BlitSurface(mapbg, NULL, videobuffer, NULL);
+
+ game_updspellsunder();
+
+ game_drawanims(0);
+
+ // ------dontdrawover = special case to make boss work right in room 24
+ if(dontdrawover == 1) game_drawanims(1);
+ game_drawnpcs(0);
+
+ game_drawplayer();
+
+ game_drawnpcs(1);
+ if(dontdrawover == 0) game_drawanims(1);
+
+ game_drawover((int)player.px, (int)player.py);
+
+ game_updspells();
+
+ if(cloudson == 1) {
+ rc.x = (float)(256 + 256 * cos(3.141592 / 180 * clouddeg));
+ rc.y = (float)(192 + 192 * sin(3.141592 / 180 * clouddeg));
+ rc.w = 320;
+ rc.h = 240;
+
+ SDL_BlitSurface(cloudimg, &rc, videobuffer, NULL);
+ }
+
+ game_drawhud();
+
+ SDL_BLITVIDEO(videobuffer, NULL, video, NULL);
+}
+
+void game_endofgame()
+{
+ float xofs = 0;
+ int ticks1;
+
+ ticks = SDL_GetTicks();
+
+ float spd = 0.2;
+
+ if(menabled == 1 && config.music == 1) {
+ Mix_HaltChannel(-1);
+ musicchannel = Mix_PlayChannel(-1, mendofgame, -1);
+ Mix_Volume(musicchannel, 0);
+ }
+
+ ticks1 = ticks;
+ int ya = 0;
+
+ SDL_FillRect(videobuffer2, NULL, 0);
+ SDL_FillRect(videobuffer3, NULL, 0);
+ SDL_BlitSurface(videobuffer, NULL, videobuffer2, NULL);
+
+ float ld = 0;
+ int ldstop = 0;
+
+ do {
+ ld = ld + 4 * fpsr;
+ if(ld > config.musicvol) ld = config.musicvol;
+ if(menabled == 1 && ldstop == 0) {
+ Mix_Volume(musicchannel, (int)ld);
+ if((int)ld == config.musicvol) ldstop = 1;
+ }
+
+ ya = 0;
+ if(ticks < ticks1 + 1500) {
+ ya = (255 * (ticks - ticks1)) / 1500;
+ if(ya < 0) ya = 0;
+ if(ya > 255) ya = 255;
+ } else {
+ break;
+ }
+
+ SDL_FillRect(videobuffer, NULL, 0);
+
+ SDL_SetAlpha(videobuffer, SDL_SRCALPHA, ya);
+ SDL_BlitSurface(videobuffer2, NULL, videobuffer3, NULL);
+ SDL_BlitSurface(videobuffer, NULL, videobuffer3, NULL);
+ SDL_BlitSurface(videobuffer3, NULL, video, NULL);
+ SDL_SetAlpha(videobuffer, SDL_SRCALPHA, 255);
+
+ SDL_Flip(video);
+ SDL_PumpEvents();
+
+ tickspassed = ticks;
+ ticks = SDL_GetTicks();
+
+ tickspassed = ticks - tickspassed;
+ fpsr = (float)tickspassed / 24;
+
+ fp++;
+ if(ticks > nextticks) {
+ nextticks = ticks + 1000;
+ fps = fp;
+ fp = 0;
+ }
+ } while(1);
+
+ ticks1 = ticks;
+ ya = 0;
+ float y = 140;
+
+ do {
+ SDL_Rect rc;
+
+ rc.x = -xofs;
+ rc.y = 0;
+
+ SDL_BlitSurface(titleimg, NULL, videobuffer, &rc);
+
+ rc.x = -xofs + 320;
+ rc.y = 0;
+
+ SDL_BlitSurface(titleimg, NULL, videobuffer, &rc);
+
+ y = y - spd * fpsr;
+ for(int i = 0; i <= 26; i++) {
+ int yy = y + i * 10;
+ if(yy > -8 && yy < 240) {
+ int x = 160 - strlen(story2[i]) * 4;
+ sys_print(videobuffer, story2[i], x, yy, 4);
+ }
+
+ if(yy < 10 && i == 25) break;
+ }
+
+ int ya = 255;
+ if(ticks < ticks1 + 1000) {
+ ya = 255 * (ticks - ticks1) / 1000;
+ if(ya < 0) ya = 0;
+ if(ya > 255) ya = 255;
+ }
+
+ SDL_SetAlpha(videobuffer, SDL_SRCALPHA, ya);
+ SDL_BLITVIDEO(videobuffer, NULL, video, NULL);
+ SDL_SetAlpha(videobuffer, SDL_SRCALPHA, 255);
+
+ SDL_Flip(video);
+ SDL_PumpEvents();
+
+ tickspassed = ticks;
+ ticks = SDL_GetTicks();
+
+ tickspassed = ticks - tickspassed;
+ fpsr = (float)tickspassed / 24;
+
+ fp++;
+ if(ticks > nextticks) {
+ nextticks = ticks + 1000;
+ fps = fp;
+ fp = 0;
+ }
+
+ float add = 0.5 * fpsr;
+ if(add > 1) add = 1;
+ xofs = xofs + add;
+ if(xofs >= 320) xofs = xofs - 320;
+
+ SDL_PollEvent(&event);
+ keys = SDL_GetKeyState(NULL);
+
+ if(event.type == SDL_KEYDOWN) spd = 1;
+ if(event.type == SDL_KEYUP) spd = 0.2;
+
+ if(keys[SDLK_ESCAPE] || keys[SDLK_LALT]) break;
+ } while(1);
+
+
+ ticks1 = ticks;
+ y = 0;
+
+ SDL_BlitSurface(videobuffer, NULL, videobuffer2, NULL);
+
+ do {
+ if(ticks < ticks1 + 1500) {
+ int y = 255 * (ticks - ticks1) / 1500;
+ if(y < 0) y = 0;
+ if(y > 255) y = 255;
+ else
+ break;
+ }
+
+ SDL_FillRect(videobuffer, NULL, 0);
+
+ SDL_SetAlpha(videobuffer, SDL_SRCALPHA, y);
+ SDL_BlitSurface(videobuffer2, NULL, videobuffer3, NULL);
+ SDL_BlitSurface(videobuffer, NULL, videobuffer3, NULL);
+ SDL_BlitSurface(videobuffer3, NULL, video, NULL);
+ SDL_SetAlpha(videobuffer, SDL_SRCALPHA, 255);
+
+ SDL_Flip(video);
+ SDL_PumpEvents();
+
+ tickspassed = ticks;
+ ticks = SDL_GetTicks();
+
+ tickspassed = ticks - tickspassed;
+ fpsr = (float)tickspassed / 24;
+
+ fp++;
+ if(ticks > nextticks) {
+ nextticks = ticks + 1000;
+ fps = fp;
+ fp = 0;
+ }
+ } while(1);
+
+
+ int keywait = 2000 + ticks;
+
+ ticks1 = ticks;
+ y = 0;
+ do {
+
+ SDL_BlitSurface(theendimg, NULL, videobuffer, NULL);
+
+ y = 255;
+ if(ticks < ticks1 + 1000) {
+ y = 255 * (ticks - ticks1) / 1000;
+ if(y < 0) y = 0;
+ if(y > 255) y = 255;
+ }
+
+ SDL_SetAlpha(videobuffer, SDL_SRCALPHA, y);
+ SDL_BLITVIDEO(videobuffer, NULL, video, NULL);
+ SDL_SetAlpha(videobuffer, SDL_SRCALPHA, 255);
+
+ SDL_Flip(video);
+ SDL_PumpEvents();
+
+ tickspassed = ticks;
+ ticks = SDL_GetTicks();
+
+ tickspassed = ticks - tickspassed;
+ fpsr = (float)tickspassed / 24;
+
+ fp++;
+ if(ticks > nextticks) {
+ nextticks = ticks + 1000;
+ fps = fp;
+ fp = 0;
+ }
+
+ SDL_PollEvent(&event);
+ keys = SDL_GetKeyState(NULL);
+
+ if(event.type == SDL_KEYDOWN && keywait < ticks) break;
+
+ } while(1);
+
+ SDL_FillRect(videobuffer2, NULL, 0);
+ SDL_FillRect(videobuffer3, NULL, 0);
+
+ game_theend();
+
+}
+
+void game_eventtext(char *stri)
+{
+ int x, fr, pauseticks, bticks;
+
+ SDL_FillRect(videobuffer2, NULL, 0);
+ SDL_FillRect(videobuffer3, NULL, 0);
+
+ x = 160 - 4 * strlen(stri);
+
+ ticks = SDL_GetTicks();
+ pauseticks = ticks + 500;
+ bticks = ticks;
+
+ SDL_BlitSurface(videobuffer, NULL, videobuffer3, NULL);
+ SDL_BlitSurface(videobuffer, NULL, videobuffer2, NULL);
+
+ do {
+ SDL_PollEvent(&event);
+ keys = SDL_GetKeyState(NULL);
+
+ if(event.type == SDL_KEYDOWN && pauseticks < ticks) break;
+ SDL_BlitSurface(videobuffer2, NULL, videobuffer, NULL);
+
+ fr = 192;
+
+ if(pauseticks > ticks) fr = 192 * (ticks - bticks) / 500;
+ if(fr > 192) fr = 192;
+
+ SDL_SetAlpha(windowimg, SDL_SRCALPHA, fr);
+
+ SDL_BlitSurface(windowimg, NULL, videobuffer, NULL);
+ if(pauseticks < ticks) sys_print(videobuffer, stri, x, 15, 0);
+
+ SDL_SetAlpha(windowimg, SDL_SRCALPHA, 255);
+ SDL_BLITVIDEO(videobuffer, NULL, video, NULL);
+
+ SDL_Flip(video);
+ SDL_PumpEvents();
+
+ tickspassed = ticks;
+ ticks = SDL_GetTicks();
+
+ tickspassed = ticks - tickspassed;
+ fpsr = (float)tickspassed / 24.0;
+
+ fp++;
+ if(ticks > nextticks) {
+ nextticks = ticks + 1000;
+ fps = fp;
+ fp = 0;
+ }
+
+ SDL_Delay(10);
+ } while(1);
+
+ SDL_BlitSurface(videobuffer3, NULL, videobuffer, NULL);
+
+ itemticks = ticks + 210;
+}
+
+
+void game_handlewalking()
+{
+ unsigned int *temp/*, c*/, bgc;
+ float spd, /*ppx, ppy,*/ px, py, opx, opy;
+ float nx, ny, npx, npy;
+
+ int xmax = 20 * 16 - 25;
+ int ymax = 15 * 16 - 25;
+
+ px = player.px;
+ py = player.py;
+ opx = px;
+ opy = py;
+
+ spd = player.walkspd * fpsr;
+
+ nx = (px / 2 + 6);
+ ny = (py / 2 + 10);
+
+ npx = px + 12;
+ npy = py + 20;
+ int lx = (int)npx / 16;
+ int ly = (int)npy / 16;
+
+ int ramp = rampdata[lx][ly];
+ if(ramp == 1 && movingup) spd = spd * 2;
+ if(ramp == 1 && movingdown) spd = spd * 2;
+
+ if(ramp == 2 && movingleft) movingup = 1;
+ if(ramp == 2 && movingright) movingdown = 1;
+
+ if(ramp == 3 && movingright) movingup = 1;
+ if(ramp == 3 && movingleft) movingdown = 1;
+
+ for(int x = -1; x <= 1; x++) {
+ for(int y = -1; y <= 1; y++) {
+ int sx = nx + x;
+ int sy = ny + y;
+
+ clipsurround[x + 1][y + 1] = 0;
+ if(sx > -1 && sx < 320 && sy > -1 && sy < 192) {
+ temp = clipbg->pixels + sy * clipbg->pitch + sx * clipbg->format->BytesPerPixel;
+ clipsurround[x + 1][y + 1] = *temp;
+ }
+ }
+ }
+
+ if(movingup) player.walkdir = 0;
+ if(movingdown) player.walkdir = 1;
+ if(movingleft) player.walkdir = 2;
+ if(movingright) player.walkdir = 3;
+
+ if(movingup && clipsurround[1][0] == 0) {
+ py = py - spd;
+ player.walkdir = 0;
+ } else if(movingup && clipsurround[1][0] > 0) {
+ // move upleft
+ if(movingright == 0 && clipsurround[0][0] == 0) {
+ py = py - spd;
+ px = px - spd;
+ }
+
+ // move upright
+ if(movingleft == 0 && clipsurround[2][0] == 0) {
+ py = py - spd;
+ px = px + spd;
+ }
+ }
+ if(movingdown && clipsurround[1][2] == 0) {
+ py = py + spd;
+ player.walkdir = 1;
+ } else if(movingdown && clipsurround[1][2] > 0) {
+ // move downleft
+ if(movingright == 0 && clipsurround[0][2] == 0) {
+ py = py + spd;
+ px = px - spd;
+ }
+
+ // move downright
+ if(movingleft == 0 && clipsurround[2][2] == 0) {
+ py = py + spd;
+ px = px + spd;
+ }
+ }
+ if(movingleft && clipsurround[0][1] == 0) {
+ px = px - spd;
+ player.walkdir = 2;
+ } else if(movingleft && clipsurround[0][1] > 0) {
+ // move leftup
+ if(movingdown == 0 && clipsurround[0][0] == 0) {
+ py = py - spd;
+ px = px - spd;
+ }
+
+ // move leftdown
+ if(movingup == 0 && clipsurround[0][2] == 0) {
+ py = py + spd;
+ px = px - spd;
+ }
+ }
+ if(movingright && clipsurround[2][1] == 0) {
+ px = px + spd;
+ player.walkdir = 3;
+ } else if(movingright && clipsurround[2][1] > 0) {
+ // move rightup
+ if(movingdown == 0 && clipsurround[2][0] == 0) {
+ px = px + spd;
+ py = py - spd;
+ }
+
+ // move rightdown
+ if(movingup == 0 && clipsurround[2][2] == 0) {
+ py = py + spd;
+ px = px + spd;
+ }
+ }
+
+ if(px < -8) px = -8;
+ if(px > xmax) px = xmax;
+ if(py < -8) py = -8;
+ if(py > ymax) py = ymax;
+
+ int pass = 1;
+
+ int sx = (px / 2 + 6);
+ int sy = (py / 2 + 10);
+ temp = clipbg->pixels + sy * clipbg->pitch + sx * clipbg->format->BytesPerPixel;
+ bgc = *temp;
+ if(bgc > 0 && bgc != 1000) {
+ px = opx;
+ py = opy;
+ pass = 0;
+ }
+
+ // push npc
+ if(pass == 1) {
+ for(int i = 1; i <= lastnpc; i++) {
+ if(npcinfo[i].hp > 0) {
+ npx = npcinfo[i].x;
+ npy = npcinfo[i].y;
+
+ opx = npx;
+ opy = npy;
+
+ int xdif = player.px - npx;
+ int ydif = player.py - npy;
+
+ if(player.walkdir == 0) {
+ if(abs(xdif) <= 8 && ydif > 0 && ydif < 8) npcinfo[i].y = npcinfo[i].y - spd;
+ } else if(player.walkdir == 1) {
+ if(abs(xdif) <= 8 && ydif < 0 && ydif > -8) npcinfo[i].y = npcinfo[i].y + spd;
+ } else if(player.walkdir == 2) {
+ if(abs(ydif) <= 8 && xdif > 0 && xdif < 8) npcinfo[i].x = npcinfo[i].x - spd;
+ } else if(player.walkdir == 3) {
+ if(abs(ydif) <= 8 && xdif < 0 && xdif > -8) npcinfo[i].x = npcinfo[i].x + spd;
+ }
+
+ npx = npcinfo[i].x;
+ npy = npcinfo[i].y;
+
+ sx = (int)(npx / 2 + 6);
+ sy = (int)(npy / 2 + 10);
+ temp = clipbg->pixels + sy * clipbg->pitch + sx * clipbg->format->BytesPerPixel;
+ bgc = *temp;
+
+ if(bgc > 0) {
+ npcinfo[i].x = opx;
+ npcinfo[i].y = opy;
+ }
+ }
+ }
+ }
+
+ player.opx = player.px;
+ player.opy = player.py;
+ player.px = px;
+ player.py = py;
+
+ if(player.px != player.opx || player.py != player.opy) player.walkframe = player.walkframe + animspd * fpsr;
+ if(player.walkframe >= 16) player.walkframe = player.walkframe - 16;
+
+ // walking over items to pickup :::
+ int o = objmap[lx][ly];
+
+ if(o > -1) {
+ // fsk
+ if(objectinfo[o][4] == 2 && player.inventory[INV_FLASK] < 9) {
+ objmap[lx][ly] = -1;
+
+ player.inventory[INV_FLASK]++;
+ game_addFloatIcon(6, lx * 16, ly * 16);
+
+ objmapf[curmap][lx][ly] = 1;
+
+ if(menabled == 1 && config.effects == 1) {
+ int snd = Mix_PlayChannel(-1, sfx[sndpowerup], 0);
+ Mix_Volume(snd, config.effectsvol);
+ }
+ }
+
+ if(objectinfo[o][5] == 7 && player.inventory[INV_DOUBLEFLASK] < 9) {
+ objmap[lx][ly] = -1;
+
+ player.inventory[INV_DOUBLEFLASK]++;
+ game_addFloatIcon(12, lx * 16, ly * 16);
+
+ objmapf[curmap][lx][ly] = 1;
+
+ if(menabled == 1 && config.effects == 1) {
+ int snd = Mix_PlayChannel(-1, sfx[sndpowerup], 0);
+ Mix_Volume(snd, config.effectsvol);
+ }
+ }
+
+ if(objectinfo[o][5] == 9 && player.inventory[INV_SHOCK] < 9 && (curmap == 41 && scriptflag[9][1] == 0)) {
+ objmap[lx][ly] = -1;
+
+ player.inventory[INV_SHOCK]++;
+ game_addFloatIcon(17, lx * 16, ly * 16);
+
+ objmapf[curmap][lx][ly] = 1;
+ if(curmap == 41) scriptflag[9][1] = 1;
+
+ if(menabled == 1 && config.effects == 1) {
+ int snd = Mix_PlayChannel(-1, sfx[sndpowerup], 0);
+ Mix_Volume(snd, config.effectsvol);
+ }
+
+ }
+
+ if(objectinfo[o][5] == 9 && player.inventory[INV_SHOCK] < 9) {
+ objmap[lx][ly] = -1;
+
+ player.inventory[INV_SHOCK]++;
+ game_addFloatIcon(17, lx * 16, ly * 16);
+
+ objmapf[curmap][lx][ly] = 1;
+
+ if(menabled == 1 && config.effects == 1) {
+ int snd = Mix_PlayChannel(-1, sfx[sndpowerup], 0);
+ Mix_Volume(snd, config.effectsvol);
+ }
+
+ }
+ }
+}
+
+void game_loadmap(int mapnum)
+{
+ unsigned int ccc;
+ SDL_Rect trect;
+ FILE *fp;
+ char name[256];
+ int tempmap[320][200];
+
+ ccc = SDL_MapRGB(clipbg->format, 255,255,255);
+
+ curmap = mapnum;
+
+ trect.x = 0;
+ trect.y = 0;
+ trect.w = 320;
+ trect.h = 240;
+ SDL_FillRect(mapbg, &trect, 0);
+ SDL_FillRect(clipbg, &trect, ccc);
+ SDL_FillRect(clipbg2, &trect, ccc);
+
+ forcepause = 0;
+ cloudson = 0;
+ if(mapnum < 6) cloudson = 1;
+ if(mapnum > 41) cloudson = 1;
+ if(mapnum > 47) cloudson = 0;
+ if(mapnum == 52) cloudson = 1;
+ if(mapnum == 60) cloudson = 1;
+ if(mapnum == 50) cloudson = 1;
+ if(mapnum == 54) cloudson = 1;
+ if(mapnum == 58) cloudson = 1;
+ if(mapnum == 62) cloudson = 1;
+ if(mapnum == 83) cloudson = 1;
+
+ // -----------special case
+ dontdrawover = 0;
+ if(mapnum == 24) dontdrawover = 1;
+
+ if((mapnum == 53 || mapnum == 57 || mapnum == 61 || mapnum == 65 || mapnum == 62) && scriptflag[60][0] > 0) mapnum = mapnum + 100;
+ if((mapnum == 161 || mapnum == 162) && scriptflag[60][0] == 2) mapnum = mapnum + 100;
+
+ for(int i = 0; i < MAXSPELL; i++)
+ spellinfo[i].frame = 0;
+
+ roomlock = 0;
+
+ // read *.map file
+ sprintf(name, "mapdb/%04i.map", mapnum); printf("Reading %s\n", name);
+ fp = fopen(name, "r");
+ for(int x = 0; x <= 319; x++)
+ for(int y = 0; y <= 199; y++) {
+ INPUT("%i", &tempmap[x][y]);
+ }
+ fclose(fp);
+
+ for(int x = 0; x <= 319; x++)
+ for(int y = 0; y <= 239; y++) {
+ triggerloc[x][y] = -1;
+ }
+
+ // read *.trg file
+ sprintf(name, "mapdb/%04i.trg", mapnum); printf("Reading %s\n", name);
+ fp = fopen(name, "r");
+
+ INPUT("%i", &ntriggers);
+
+ for(int i = 0; i < ntriggers; i++) {
+ int mapx, mapy, trig;
+
+ INPUT("%i", &mapx);
+ INPUT("%i", &mapy);
+ INPUT("%i", &trig);
+
+ triggerloc[mapx][mapy] = trig;
+ }
+ fclose(fp);
+
+
+ for(int y = 0; y <= 23; y++)
+ for(int x = 0; x <= 39; x++)
+ rampdata[x][y] = tempmap[3 * 40 + x][y + 40];
+
+
+ for(int y = 0; y <= 23; y++)
+ for(int x = 0; x <= 39; x++)
+ for(int l = 0; l <= 2; l++)
+ for(int a = 0; a <= 2; a++)
+ tileinfo[l][x][y][a] = 0;
+
+ if(scriptflag[4][0] == 1 && curmap == 4) {
+ triggerloc[9][7] = 5004;
+ tempmap[9][7] = 41;
+ tempmap[9][7 + 40] = 0;
+ }
+
+ for(int y = 0; y <= 23; y++) {
+ for(int x = 0; x <= 39; x++) {
+ for(int l = 0; l <= 2; l++) {
+ int lx, ly, curtile, curtilelayer;
+ int curtilel, curtilex, curtiley;
+ int ffa, ffb;
+
+ ly = y;
+ lx = x + l * 40;
+
+ // tile
+ curtile = tempmap[lx][ly];
+ curtilelayer = tempmap[lx][ly + 40];
+
+ if(curtile > 0) {
+ curtile = curtile - 1;
+ curtilel = curtilelayer;
+ curtilex = curtile % 20;
+ curtiley = (curtile - curtilex) / 20;
+
+ tileinfo[l][x][y][0] = curtile + 1;
+ tileinfo[l][x][y][1] = curtilelayer;
+
+ rcSrc.x = curtilex * 16;
+ rcSrc.y = curtiley * 16;
+ rcSrc.w = 16;
+ rcSrc.h = 16;
+
+ rcDest.x = x * 16;
+ rcDest.y = y * 16;
+ rcDest.w = 16;
+ rcDest.h = 16;
+
+ if(l == 2 && curtilel == 1) {
+ for(int ff = 0; ff <= 5; ff++) {
+ ffa = 20 * 5 - 1 + ff * 20;
+ ffb = 20 * 5 + 4 + ff * 20;
+ if(curtile > ffa && curtile < ffb) {
+ SDL_SetAlpha(tiles[curtilel], SDL_SRCALPHA, 128);
+ }
+ }
+ }
+ if(l == 1 && curtilel == 2) {
+ for(int ff = 0; ff <= 4; ff++) {
+ ffa = 20 * (5 + ff) + 3;
+ if(curtile == ffa) {
+ SDL_SetAlpha(tiles[curtilel], SDL_SRCALPHA, 192);
+ }
+ }
+ }
+
+ SDL_BlitSurface(tiles[curtilel], &rcSrc, mapbg, &rcDest);
+ SDL_SetAlpha(tiles[curtilel], SDL_SRCALPHA, 255);
+
+ rcDest.x = x * 8;
+ rcDest.y = y * 8;
+ rcDest.w = 8;
+ rcDest.h = 8;
+
+ SDL_FillRect(clipbg, &rcDest, 0);
+ }
+
+ }
+ }
+ }
+
+
+ for(int x = 0; x <= 39; x++) {
+ for(int y = 0; y <= 23; y++) {
+
+ int d = tempmap[3 * 40 + x][y];
+
+ int clip = 0;
+ int npc = 0;
+
+ if(scriptflag[4][0] == 1 && x == 9 && y == 7) d = 99;
+
+ if(d > 0) {
+ clip = d % 2;
+ d = (d - clip) / 2;
+ npc = d % 2;
+ d = (d - npc) / 2;
+
+ if(d == 99 && x == 9 && y == 7) clip = 1;
+
+ if(clip) {
+ if(d != 99) d = tempmap[6 * 40 + x][y];
+ if(d == 99) d = 1;
+
+ int x1 = x * 8;
+ int y1 = y * 8;
+
+ if(d == 1) {
+ for(int i = 0; i <= 7; i++) {
+ sys_line(clipbg, x1, y1 + i, x1 + 7 - i, y1 + i, ccc);
+ }
+ } else if(d == 2) {
+ sys_line(clipbg, x1, y1, x1 + 7, y1, ccc);
+ sys_line(clipbg, x1, y1 + 1, x1 + 7, y1 + 1, ccc);
+ } else if(d == 3) {
+ for(int i = 0; i <= 7; i++) {
+ sys_line(clipbg, x1 + i, y1 + i, x1 + 7, y1 + i, ccc);
+ }
+ } else if(d == 4) {
+ sys_line(clipbg, x1, y1, x1, y1 + 7, ccc);
+ sys_line(clipbg, x1 + 1, y1, x1 + 1, y1 + 7, ccc);
+ } else if(d == 5) {
+ rcDest.x = x1;
+ rcDest.y = y1;
+ rcDest.w = 8;
+ rcDest.h = 8;
+ SDL_FillRect(clipbg, &rcDest, SDL_MapRGB(clipbg->format, 255,255,255));
+ } else if(d == 6) {
+ sys_line(clipbg, x1 + 7, y1, x1 + 7, y1 + 7, ccc);
+ sys_line(clipbg, x1 + 6, y1, x1 + 6, y1 + 7, ccc);
+ } else if(d == 7) {
+ for(int i = 0; i <= 7; i++) {
+ sys_line(clipbg, x1, y1 + i, x1 + i, y1 + i, ccc);
+ }
+ } else if(d == 8) {
+ sys_line(clipbg, x1, y1 + 7, x1 + 7, y1 + 7, ccc);
+ sys_line(clipbg, x1, y1 + 7, x1 + 6, y1 + 6, ccc);
+ } else if(d == 9) {
+ for(int i = 0; i <= 7; i++) {
+ sys_line(clipbg, x1 + 7 - i, y1 + i, x1 + 7, y1 + i, ccc);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ lastobj = 0;
+ lastnpc = 0;
+
+ for(int i = 0; i < MAXNPC; i++)
+ npcinfo[i].onmap = 0;
+
+ for(int x = 0; x <= 19; x++) {
+ for(int y = 0; y <= 19; y++) {
+ int d = tempmap[3 * 40 + x][y];
+
+ int clip = 0;
+ int npc = 0;
+ int obj = 0;
+ if(d > 0) {
+ clip = d % 2;
+ d = (d - clip) / 2;
+ npc = d % 2;
+ d = (d - npc) / 2;
+ obj = d % 2;
+ }
+
+ objmap[x][y] = -1;
+
+ if(obj == 1) {
+
+ int o = tempmap[5 * 40 + x][y];
+
+ if(objmapf[curmap][x][y] == 0) {
+ objmap[x][y] = o;
+
+ if(objectinfo[o][0] > 1) {
+ if(o > lastobj) lastobj = o;
+ }
+
+ int x1 = x * 8;
+ int y1 = y * 8;
+
+ rcDest.x = x1;
+ rcDest.y = y1;
+ rcDest.w = 8;
+ rcDest.h = 8;
+
+ if(objectinfo[o][4] == 1) SDL_FillRect(clipbg, &rcDest, SDL_MapRGB(clipbg->format, 255,255,255));
+ if(objectinfo[o][4] == 3) SDL_FillRect(clipbg, &rcDest, SDL_MapRGB(clipbg->format, 255,255,255));
+ }
+ }
+ if(npc == 1) {
+ int o = tempmap[4 * 40 + x][y];
+
+ if(o > lastnpc) lastnpc = o;
+
+ npcinfo[o].x = x * 16 - 4;
+ npcinfo[o].y = y * 16 - 5;
+
+ npcinfo[o].walkdir = 1;
+ npcinfo[o].onmap = 1;
+ }
+ }
+ }
+
+
+ if(curmap == 62 && scriptflag[8][0] > 0) lastnpc = 0;
+ if(curmap == 73 && scriptflag[12][0] > 0) lastnpc = 0;
+ if(curmap == 81 && scriptflag[13][0] > 0) lastnpc = 0;
+
+ if(curmap == 73 && scriptflag[12][0] == 0) roomlock = 1;
+ if(curmap == 81 && scriptflag[13][0] == 0) roomlock = 1;
+ if(curmap == 83 && scriptflag[15][0] == 0) roomlock = 1;
+ if(curmap == 82) roomlock = 1;
+
+ // read *.npc file
+ sprintf(name, "mapdb/%04i.npc", mapnum); printf("Reading %s\n", name);
+ fp = fopen(name, "r");
+
+ for(int i = 0; i < MAXNPC; i++) {
+ INPUT("%i", &npcinfo[i].spriteset);
+ INPUT("%i", &npcinfo[i].x1);
+ INPUT("%i", &npcinfo[i].y1);
+ INPUT("%i", &npcinfo[i].x2);
+ INPUT("%i", &npcinfo[i].y2);
+ INPUT("%i", &npcinfo[i].movementmode);
+ INPUT("%i", &npcinfo[i].hp);
+ INPUT("%i", &npcinfo[i].item1);
+ INPUT("%i", &npcinfo[i].item2);
+ INPUT("%i", &npcinfo[i].item3);
+ INPUT("%i", &npcinfo[i].script);
+
+ // baby dragon
+ if(npcinfo[i].spriteset == 1) {
+ npcinfo[i].hp = 12;
+ npcinfo[i].attackdelay = 2000;
+
+ npcinfo[i].attackdamage = 2;
+ npcinfo[i].spelldamage = 0;
+
+ npcinfo[i].walkspd = 1;
+
+ if(RND() * 5 == 0) npcinfo[i].hp = 0;
+ }
+
+ // onewing
+ if(npcinfo[i].spriteset == 2) {
+ npcinfo[i].hp = 200;
+ npcinfo[i].attackdelay = 2000;
+ npcinfo[i].swayspd = 1;
+
+ npcinfo[i].attackdamage = 24;
+ npcinfo[i].spelldamage = 30;
+
+ npcinfo[i].walkspd = 1.4;
+ npcinfo[i].castpause = ticks;
+ }
+
+ // boss1
+ if(npcinfo[i].spriteset == 3) {
+ npcinfo[i].hp = 300;
+ npcinfo[i].attackdelay = 2200;
+
+ npcinfo[i].attackdamage = 0;
+ npcinfo[i].spelldamage = 30;
+
+ npcinfo[i].walkspd = 1.2;
+ }
+
+ // black knights
+ if(npcinfo[i].spriteset == 4) {
+ npcinfo[i].hp = 200;
+ npcinfo[i].attackdelay = 2800;
+
+ npcinfo[i].attackdamage = 0;
+ npcinfo[i].spelldamage = 30;
+
+ npcinfo[i].walkspd = 1;
+ }
+
+ // boss2 firehydra
+ if(npcinfo[i].spriteset == 5) {
+ npcinfo[i].hp = 600;
+ npcinfo[i].attackdelay = 2200;
+
+ npcinfo[i].attackdamage = 50;
+ npcinfo[i].spelldamage = 30;
+
+ npcinfo[i].walkspd = 1.3;
+
+ npcinfo[i].swayangle = 0;
+ }
+
+ // baby fire dragon
+ if(npcinfo[i].spriteset == 6) {
+ npcinfo[i].hp = 20;
+ npcinfo[i].attackdelay = 1500;
+
+ npcinfo[i].attackdamage = 0;
+ npcinfo[i].spelldamage = 12;
+
+ npcinfo[i].walkspd = 1;
+
+ if(RND() * 5 == 0) npcinfo[i].hp = 0;
+ }
+
+ // priest1
+ if(npcinfo[i].spriteset == 7) {
+ npcinfo[i].hp = 40;
+ npcinfo[i].attackdelay = 5000;
+
+ npcinfo[i].attackdamage = 0;
+ npcinfo[i].spelldamage = 8;
+
+ npcinfo[i].walkspd = 1;
+
+ if(RND() * 8 == 0) npcinfo[i].hp = 0;
+ }
+
+ // yellow fire dragon
+ if(npcinfo[i].spriteset == 8) {
+ npcinfo[i].hp = 100;
+ npcinfo[i].attackdelay = 1500;
+
+ npcinfo[i].attackdamage = 0;
+ npcinfo[i].spelldamage = 24;
+
+ npcinfo[i].walkspd = 1;
+
+ if(RND() * 5 == 0) npcinfo[i].hp = 0;
+ }
+
+ // twowing
+ if(npcinfo[i].spriteset == 9) {
+ npcinfo[i].hp = 140;
+ npcinfo[i].attackdelay = 2000;
+ npcinfo[i].swayspd = 1;
+
+ npcinfo[i].attackdamage = 30;
+ npcinfo[i].spelldamage = 0;
+
+ npcinfo[i].walkspd = 1;
+
+ npcinfo[i].castpause = 0;
+ }
+
+ // dragon2
+ if(npcinfo[i].spriteset == 10) {
+ npcinfo[i].hp = 80;
+ npcinfo[i].attackdelay = 1500;
+
+ npcinfo[i].attackdamage = 24;
+ npcinfo[i].spelldamage = 0;
+
+ npcinfo[i].walkspd = 1;
+
+ npcinfo[i].floating = RND() * 16;
+ }
+
+ // end boss
+ if(npcinfo[i].spriteset == 11) {
+ npcinfo[i].hp = 1200;
+ npcinfo[i].attackdelay = 2000;
+
+ npcinfo[i].attackdamage = 100;
+ npcinfo[i].spelldamage = 60;
+
+ npcinfo[i].walkspd = 1;
+
+ npcinfo[i].floating = RND() * 16;
+ }
+
+ // bat kitty
+ if(npcinfo[i].spriteset == 12) {
+ npcinfo[i].hp = 800;
+ npcinfo[i].attackdelay = 2000;
+
+ npcinfo[i].attackdamage = 100;
+ npcinfo[i].spelldamage = 50;
+
+ npcinfo[i].walkspd = 1;
+
+ npcinfo[i].floating = RND() * 16;
+ }
+
+ if(npcinfo[i].onmap == 0) npcinfo[i].hp = 0;
+
+ npcinfo[i].maxhp = npcinfo[i].hp;
+
+ npcinfo[i].attacking = 0;
+ npcinfo[i].attackframe = 0;
+ npcinfo[i].cattackframe = 0;
+ npcinfo[i].attackspd = 1.5;
+ npcinfo[i].attacknext = ticks + npcinfo[i].attackdelay * (1 + RND() * 2);
+
+ if(npcinfo[i].spriteset == 2 || npcinfo[i].spriteset == 9) {
+ npcinfo[i].bodysection[0].sprite = 0;
+ npcinfo[i].bodysection[1].sprite = 1;
+ npcinfo[i].bodysection[2].sprite = 2;
+ npcinfo[i].bodysection[3].sprite = 3;
+ npcinfo[i].bodysection[4].sprite = 4;
+ npcinfo[i].bodysection[5].sprite = 3;
+ npcinfo[i].bodysection[6].sprite = 3;
+ npcinfo[i].bodysection[7].sprite = 5;
+
+ npcinfo[i].bodysection[0].bonelength = 8;
+ npcinfo[i].bodysection[1].bonelength = 7;
+ npcinfo[i].bodysection[2].bonelength = 6;
+ npcinfo[i].bodysection[3].bonelength = 4;
+ npcinfo[i].bodysection[4].bonelength = 4;
+ npcinfo[i].bodysection[5].bonelength = 4;
+ npcinfo[i].bodysection[6].bonelength = 4;
+
+ for(int f = 0; f <= 7; f++) {
+ npcinfo[i].bodysection[f].x = npcinfo[i].x + 12;
+ npcinfo[i].bodysection[f].y = npcinfo[i].y + 14;
+ }
+
+ npcinfo[i].headtargetx[0] = npcinfo[i].x + 12;
+ npcinfo[i].headtargety[0] = npcinfo[i].y + 14;
+
+ }
+
+ if(npcinfo[i].spriteset == 5) {
+ for(int f = 0; f <= 29; f++) {
+ npcinfo[i].bodysection[f].x = npcinfo[i].x + 12;
+ npcinfo[i].bodysection[f].y = npcinfo[i].y + 14;
+ }
+
+ for(int f = 0; f <= 2; f++) {
+ npcinfo[i].headtargetx[f] = npcinfo[i].x + 12;
+ npcinfo[i].headtargety[f] = npcinfo[i].y + 14;
+
+ npcinfo[i].attacking2[f] = 0;
+ npcinfo[i].attackframe2[f] = 0;
+ }
+ }
+
+ if(npcinfo[i].script == 2) {
+ roomlock = 1;
+ if(scriptflag[2][0] > 0) {
+ roomlock = 0;
+ npcinfo[i].hp = 0;
+ }
+ }
+
+ if(npcinfo[i].script == 3) {
+ roomlock = 1;
+ if(scriptflag[3][0] > 0) {
+ roomlock = 0;
+ npcinfo[i].hp = 0;
+ }
+ }
+
+ if(npcinfo[i].script == 5) {
+ roomlock = 1;
+ if(scriptflag[5][0] > 0) {
+ roomlock = 0;
+ npcinfo[i].hp = 0;
+ }
+ }
+
+ if(npcinfo[i].script == 15) {
+ roomlock = 1;
+ if(scriptflag[15][0] > 0) {
+ roomlock = 0;
+ npcinfo[i].hp = 0;
+ }
+ }
+
+ npcinfo[i].pause = ticks;
+ }
+
+ fclose(fp);
+
+
+ int cx, cy, npx, npy, lx, ly;
+
+ // academy master key
+ if(curmap == 34 && scriptflag[2][0] == 1) {
+ cx = 9;
+ cy = 7;
+
+ objmap[cx][cy] = 5;
+
+ rcDest.x = cx * 8;
+ rcDest.y = cy * 8;
+ rcDest.w = 8;
+ rcDest.h = 8;
+
+ npx = player.px + 12;
+ npy = player.py + 20;
+
+ lx = (int)npx / 16;
+ ly = (int)npy / 16;
+
+ if(lx == cx && ly == cy) player.py = player.py + 16;
+
+ SDL_FillRect(clipbg, &rcDest, SDL_MapRGB(clipbg->format, 255,255,255));
+ }
+
+ // academy crystal
+ if(curmap == 24 && player.foundspell[0] == 0 && scriptflag[3][0] == 1) {
+ cx = 9;
+ cy = 7;
+
+ objmap[cx][cy] = 6;
+
+ rcDest.x = cx * 8;
+ rcDest.y = cy * 8;
+ rcDest.w = 8;
+ rcDest.h = 8;
+
+ npx = player.px + 12;
+ npy = player.py + 20;
+
+ lx = (int)npx / 16;
+ ly = (int)npy / 16;
+
+ if(lx == cx && ly == cy) player.py = player.py + 16;
+
+ SDL_FillRect(clipbg, &rcDest, SDL_MapRGB(clipbg->format, 255,255,255));
+ }
+
+ // gardens master key
+ if(curmap == 62 && scriptflag[8][0] == 1) {
+ cx = 13;
+ cy = 7;
+
+ objmap[cx][cy] = 5;
+
+ rcDest.x = cx * 8;
+ rcDest.y = cy * 8;
+ rcDest.w = 8;
+ rcDest.h = 8;
+
+ npx = player.px + 12;
+ npy = player.py + 20;
+
+ lx = (int)npx / 16;
+ ly = (int)npy / 16;
+
+ if(lx == cx && ly == cy) player.py = player.py + 16;
+
+ SDL_FillRect(clipbg, &rcDest, SDL_MapRGB(clipbg->format, 255,255,255));
+ }
+
+ // gardens fidelis sword
+ if(curmap == 66 && scriptflag[5][0] == 1 && player.sword == 1) {
+ cx = 9;
+ cy = 6;
+
+ objmap[cx][cy] = 9;
+
+ rcDest.x = cx * 8;
+ rcDest.y = cy * 8;
+ rcDest.w = 8;
+ rcDest.h = 8;
+
+ npx = player.px + 12;
+ npy = player.py + 20;
+
+ lx = (int)npx / 16;
+ ly = (int)npy / 16;
+
+ if(lx == cx && ly == cy) player.py = player.py + 16;
+
+ SDL_FillRect(clipbg, &rcDest, SDL_MapRGB(clipbg->format, 255,255,255));
+ }
+
+ // citadel armour
+ if(curmap == 73 && scriptflag[12][0] == 1 && player.armour == 1) {
+ cx = 8;
+ cy = 7;
+
+ objmap[cx][cy] = 16;
+
+ rcDest.x = cx * 8;
+ rcDest.y = cy * 8;
+ rcDest.w = 8;
+ rcDest.h = 8;
+
+ npx = player.px + 12;
+ npy = player.py + 20;
+
+ lx = (int)npx / 16;
+ ly = (int)npy / 16;
+
+ if(lx == cx && ly == cy) player.py = player.py + 16;
+
+ SDL_FillRect(clipbg, &rcDest, SDL_MapRGB(clipbg->format, 255,255,255));
+ }
+
+ // citadel master key
+ if(curmap == 81 && scriptflag[13][0] == 1) {
+ cx = 11;
+ cy = 10;
+
+ objmap[cx][cy] = 5;
+
+ rcDest.x = cx * 8;
+ rcDest.y = cy * 8;
+ rcDest.w = 8;
+ rcDest.h = 8;
+
+ npx = player.px + 12;
+ npy = player.py + 20;
+
+ lx = (int)npx / 16;
+ ly = (int)npy / 16;
+
+ if(lx == cx && ly == cy) player.py = player.py + 16;
+
+ SDL_FillRect(clipbg, &rcDest, SDL_MapRGB(clipbg->format, 255,255,255));
+ }
+
+
+ // max ups
+ if(curmap == 83 && scriptflag[15][0] == 1 && player.sword < 3) {
+ cx = 6;
+ cy = 8;
+
+ objmap[cx][cy] = 18;
+
+ rcDest.x = cx * 8;
+ rcDest.y = cy * 8;
+ rcDest.w = 8;
+ rcDest.h = 8;
+
+ npx = player.px + 12;
+ npy = player.py + 20;
+
+ lx = (int)npx / 16;
+ ly = (int)npy / 16;
+
+ if(lx == cx && ly == cy) player.py = player.py + 16;
+
+ SDL_FillRect(clipbg, &rcDest, SDL_MapRGB(clipbg->format, 255,255,255));
+ }
+
+ if(curmap == 83 && scriptflag[16][0] == 1 && player.shield < 3) {
+ cx = 9;
+ cy = 8;
+
+ objmap[cx][cy] = 19;
+
+ rcDest.x = cx * 8;
+ rcDest.y = cy * 8;
+ rcDest.w = 8;
+ rcDest.h = 8;
+
+ npx = player.px + 12;
+ npy = player.py + 20;
+
+ lx = (int)npx / 16;
+ ly = (int)npy / 16;
+
+ if(lx == cx && ly == cy) player.py = player.py + 16;
+
+ SDL_FillRect(clipbg, &rcDest, SDL_MapRGB(clipbg->format, 255,255,255));
+ }
+
+ if(curmap == 83 && scriptflag[17][0] == 1 && player.armour < 3) {
+ cx = 12;
+ cy = 8;
+
+ objmap[cx][cy] = 20;
+
+ rcDest.x = cx * 8;
+ rcDest.y = cy * 8;
+ rcDest.w = 8;
+ rcDest.h = 8;
+
+ npx = player.px + 12;
+ npy = player.py + 20;
+
+ lx = (int)npx / 16;
+ ly = (int)npy / 16;
+
+ if(lx == cx && ly == cy) player.py = player.py + 16;
+
+ SDL_FillRect(clipbg, &rcDest, SDL_MapRGB(clipbg->format, 255,255,255));
+ }
+
+ SDL_BlitSurface(clipbg, NULL, clipbg2, NULL);
+}
+
+void game_main()
+{
+ game_title(0);
+ game_saveloadnew();
+}
+
+void game_newgame()
+{
+ float xofs = 0;
+ float ld = 0, add;
+ int ticks, cnt = 0;
+
+ SDL_FillRect(videobuffer2, NULL, 0);
+ SDL_FillRect(videobuffer3, NULL, 0);
+
+ ticks = SDL_GetTicks();
+
+ SDL_BlitSurface(videobuffer, NULL, videobuffer3, NULL);
+ SDL_BlitSurface(videobuffer, NULL, videobuffer2, NULL);
+
+ fpsr = 0.0;
+ int y = 140;
+
+ if(menabled == 1 && config.music == 1) {
+ Mix_HaltChannel(-1);
+ musicchannel = Mix_PlayChannel(-1, mendofgame, -1);
+ Mix_Volume(musicchannel, 0);
+ }
+
+ secsingame = 0;
+ secstart = 0;
+
+ int ldstop = 0;
+
+ do {
+ SDL_Rect rc;
+
+ ld += 4 * fpsr;
+ if((int)ld > config.musicvol) ld = config.musicvol;
+ if(menabled == 1 && ldstop == 0) {
+ Mix_Volume(musicchannel, (int)ld);
+ if((int)ld == config.musicvol) ldstop = 1;
+ }
+
+ rc.x = -xofs;
+ rc.y = 0;
+
+ SDL_BlitSurface(titleimg, NULL, videobuffer, &rc);
+
+ rc.x = -xofs + 320;
+ rc.y = 0;
+
+ SDL_BlitSurface(titleimg, NULL, videobuffer, &rc);
+
+ if(++cnt >= 6) {
+ cnt = 0;
+ y--;
+ }
+
+ for(int i = 0; i <= 37; i++) {
+ int yy, x;
+
+ yy = y + i * 10;
+ if(yy > -8 && yy < 240) {
+ x = 160 - strlen(story[i]) * 4;
+ sys_print(videobuffer, story[i], x, yy, 4);
+ }
+
+ if(yy < 10 && i == 47) goto __exit_do;
+ }
+
+ SDL_BLITVIDEO(videobuffer, NULL, video, NULL);
+ SDL_Flip(video);
+
+ tickspassed = ticks;
+ ticks = SDL_GetTicks();
+
+ tickspassed = ticks - tickspassed;
+ fpsr = (float)tickspassed / 24.0;
+
+ fp++;
+ if(ticks > nextticks) {
+ nextticks = ticks + 1000;
+ fps = fp;
+ fp = 0;
+ }
+
+ add = 0.5 * fpsr;
+ if(add > 1) add = 1;
+ xofs += add;
+ if(xofs >= 320) xofs = xofs - 320;
+
+ SDL_PollEvent(&event);
+ keys = SDL_GetKeyState(NULL);
+
+ if(event.type == SDL_KEYDOWN) cnt = 6;
+ if(keys[SDLK_ESCAPE] || keys[SDLK_LALT]) goto __exit_do;
+
+ SDL_Delay(10);
+ } while(1);
+__exit_do:
+
+ player.px = 0;
+ player.py = 0;
+ player.opx = 0;
+ player.opy = 0;
+ player.walkdir = 0;
+ player.walkframe = 0;
+ player.walkspd = 0;
+ player.attackframe = 0;
+ player.attackspd = 0;
+ player.hp = 0;
+ player.maxhp = 0;
+ player.hpflash = 0;
+ player.level = 0;
+ player.maxlevel = 0;
+ player.sword = 0;
+ player.shield = 0;
+ player.armour = 0;
+ for(int i = 0; i < 5; i++) {
+ player.foundspell[i] = 0;
+ player.spellcharge[i] = 0;
+ player.inventory[i] = 0;
+ }
+ player.attackstrength = 0;
+ player.spelldamage = 0;
+ player.sworddamage = 0;
+ player.exp = 0;
+ player.nextlevel = 0;
+
+ memset(scriptflag, 0, sizeof(scriptflag));
+ memset(objmapf, 0, sizeof(objmapf));
+ memset(roomlocks, 0, sizeof(roomlocks));
+
+ roomlocks[66] = 2;
+ roomlocks[24] = 2;
+ roomlocks[17] = 1;
+ roomlocks[34] = 1;
+ roomlocks[50] = 1;
+ roomlocks[73] = 1;
+ roomlocks[82] = 2;
+
+ player.walkspd = 1.1;
+ animspd = 0.5;
+ attacking = 0;
+ player.attackspd = 1.5;
+
+ player.sword = 1;
+ player.level = 1;
+ player.maxlevel = 22;
+ player.nextlevel = 50;
+ player.shield = 1;
+ player.armour = 1;
+ player.hp = 14;
+ player.maxhp = player.hp;
+
+ player.sworddamage = player.level * 2;
+ player.spelldamage = player.level * 3 / 2;
+
+ player.px = 15*16 - 4;
+ player.py = 6*16 - 4;
+ player.walkdir = 1;
+
+ pgardens = 0;
+ ptown = 0;
+ pboss = 0;
+ pacademy = 0;
+ pcitadel = 0;
+
+ game_loadmap(2);
+
+ game_playgame();
+}
+
+void game_playgame()
+{
+ game_swash();
+
+ if(pmenu == 1 && menabled == 1) {
+ Mix_HaltChannel(menuchannel);
+ pmenu = 0;
+ }
+
+ do {
+ if(forcepause == 0) {
+ game_updanims();
+ game_updnpcs();
+ }
+
+ game_checktrigger();
+ game_checkinputs();
+
+ if(forcepause == 0) game_handlewalking();
+
+ game_updatey();
+ game_drawview();
+
+ game_updmusic();
+
+ sys_update();
+ } while(1);
+}
+
+void game_processtrigger(int trignum)
+{
+ int trigtype, tx, ty, tmap, tjumpstyle, tsx, tsy;
+
+ trigtype = triggers[trignum][0];
+
+ if(roomlock == 1) return;
+ // map jump------------------------------
+ if(trigtype == 0) {
+ tx = triggers[trignum][1];
+ ty = triggers[trignum][2];
+ tmap = triggers[trignum][3];
+ tjumpstyle = triggers[trignum][4];
+
+ if(roomlocks[tmap] > 0) {
+ if(saidlocked == 0) game_eventtext("Locked");
+ saidlocked = 1;
+ canusekey = 1;
+ locktype = roomlocks[tmap];
+ roomtounlock = tmap;
+ return;
+ }
+
+ if(tmap == 1) {
+ if(saidjammed == 0) game_eventtext("Door Jammed!");
+ saidjammed = 1;
+ return;
+ }
+
+ saidlocked = 0;
+ saidjammed = 0;
+
+ // loc-sxy+oldmaploc
+ if(tjumpstyle == 0) {
+
+ tsx = triggers[trignum][5];
+ tsy = triggers[trignum][6];
+
+ player.px += (tx - tsx) * 16;
+ player.py += (ty - tsy) * 16;
+
+ // HACKFIX
+ if(player.px < 0) player.px = 0;
+ if(player.py < 0) player.py = 0;
+
+ if(tmap > 0) {
+ if(menabled == 1 && config.effects == 1) {
+ int snd = Mix_PlayChannel(-1, sfx[snddoor], 0);
+ Mix_Volume(snd, config.effectsvol);
+ }
+
+ game_loadmap(tmap);
+ game_swash();
+ }
+ }
+ }
+
+ for(int i = 0; i < MAXFLOAT; i++) {
+ floattext[i][0] = 0;
+ floaticon[i][0] = 0;
+ }
+}
+
+void game_saveloadnew()
+{
+ float y; int yy;
+ int currow, curcol, lowerlock;
+ int ticks, ticks1, tickpause;
+
+ clouddeg = 0;
+
+ SDL_SetAlpha(videobuffer, SDL_SRCALPHA, 255);
+ SDL_SetAlpha(saveloadimg, SDL_SRCALPHA, 192);
+
+ currow = 0;
+ curcol = 0;
+
+ lowerlock = 0;
+
+ ticks = SDL_GetTicks();
+ ticks1 = ticks;
+ tickpause = ticks + 150;
+
+ do {
+ SDL_FillRect(videobuffer, NULL, 0);
+
+ y = y + 1 * fpsr;
+
+ rcDest.x = 256 + 256 * cos(3.141592 / 180 * clouddeg * 40);
+ rcDest.y = 192 + 192 * sin(3.141592 / 180 * clouddeg * 40);
+ rcDest.w = 320;
+ rcDest.h = 240;
+
+ SDL_SetAlpha(cloudimg, SDL_SRCALPHA, 128);
+ SDL_BlitSurface(cloudimg, &rcDest, videobuffer, NULL);
+ SDL_SetAlpha(cloudimg, SDL_SRCALPHA, 64);
+
+
+ rcDest.x = 256;
+ rcDest.y = 192;
+ rcDest.w = 320;
+ rcDest.h = 240;
+
+ SDL_SetAlpha(cloudimg, SDL_SRCALPHA, 128);
+ SDL_BlitSurface(cloudimg, &rcDest, videobuffer, NULL);
+ SDL_SetAlpha(cloudimg, SDL_SRCALPHA, 64);
+
+ SDL_BlitSurface(saveloadimg, NULL, videobuffer, NULL);
+
+ SDL_PollEvent(&event);
+ keys = SDL_GetKeyState(NULL);
+
+ if(tickpause < ticks) {
+ if(event.type == SDL_KEYDOWN) {
+ itemticks = ticks + 220;
+
+ if(keys[SDLK_LCTRL] || keys[SDLK_RETURN]) {
+ // QUIT - non existent :)
+ if(currow == 0 && curcol == 4) {
+ exit(1);
+ }
+ // RETURN
+ if(currow == 0 && curcol == 3) {
+ // reset keys to avoid returning
+ keys[SDLK_RETURN] = keys[SDLK_SPACE] = 0;
+ return;
+ }
+ // NEW GAME
+ if(currow == 0 && curcol == 0) game_newgame();
+
+ // LOAD GAME
+ if(currow == 0 && curcol == 1) {
+ lowerlock = 1;
+ currow = 1 + saveslot;
+ tickpause = ticks + 125;
+ }
+ // SAVE GAME
+ if(currow == 0 && curcol == 2) {
+ lowerlock = 1;
+ currow = 1;
+ tickpause = ticks + 125;
+ }
+
+
+ if(lowerlock == 1 && curcol == 1 && tickpause < ticks) {
+ if(state_save(currow - 1)) {
+ secstart = secstart + secsingame;
+ secsingame = 0;
+ lowerlock = 0;
+ saveslot = currow - 1;
+ currow = 0;
+ }
+ }
+
+ if(lowerlock == 1 && curcol == 2 && tickpause < ticks) {
+ if(state_load(currow - 1)) {
+ player.walkspd = 1.1;
+ animspd = .5;
+ attacking = 0;
+ player.attackspd = 1.5;
+
+ pgardens = 0;
+ ptown = 0;
+ pboss = 0;
+ pacademy = 0;
+ pcitadel = 0;
+
+ Mix_HaltChannel(-1);
+
+ secsingame = 0;
+ saveslot = currow - 1;
+ game_loadmap(curmap);
+ game_playgame();
+ }
+ }
+
+ tickpause = ticks + 125;
+ }
+
+ switch(event.key.keysym.sym) {
+ case SDLK_ESCAPE:
+ case SDLK_LALT:
+ if(lowerlock == 0) return;
+ lowerlock = 0;
+ currow = 0;
+ tickpause = ticks + 125;
+ break;
+ case SDLK_DOWN:
+ if(lowerlock == 1) {
+ currow = currow + 1;
+ if(currow == 5) currow = 1;
+ tickpause = ticks + 125;
+ }
+ break;
+
+ case SDLK_UP:
+ if(lowerlock == 1) {
+ currow = currow - 1;
+ if(currow == 0) currow = 4;
+ tickpause = ticks + 125;
+ }
+ break;
+
+ case SDLK_LEFT:
+ if(lowerlock == 0) {
+ curcol = curcol - 1;
+ if(curcol == -1) curcol = 3;
+ tickpause = ticks + 125;
+ }
+ break;
+
+ case SDLK_RIGHT:
+ if(lowerlock == 0) {
+ curcol = curcol + 1;
+ if(curcol == 4) curcol = 0;
+ tickpause = ticks + 125;
+ }
+ break;
+ default:
+ ;
+ }
+ }
+ }
+
+
+ // savestates---------------------------------
+ // read it only when needed!
+
+ for(int ff = 0; ff <= 3; ff++) {
+ state_load_player(ff);
+
+ if(playera.level > 0) {
+ char line[256];
+ int sx, sy, cc, ss, nx;
+
+ sx = 8;
+ sy = 57 + ff * 48;
+
+ // time
+ int ase = asecstart;
+ int h = ((ase - (ase % 3600)) / 3600);
+ ase = (ase - h * 3600);
+ int m = ((ase - (ase % 60)) / 60);
+ int s = (ase - m * 60);
+
+ sprintf(line, "Game Time: %02i:%02i:%02i", h, m, s);
+ sys_print(videobuffer, line, 160 - strlen(line) * 4, sy, 0);
+
+ sx = 12;
+ sy = sy + 11;
+ cc = 0;
+
+ sprintf(line, "Health: %i/%i", playera.hp, playera.maxhp);
+ sys_print(videobuffer, line, sx, sy, cc);
+
+ if(playera.level == 22)
+ strcpy(line, "Level: MAX");
+ else
+ sprintf(line, "Level: %i", playera.level);
+
+ sys_print(videobuffer, line, sx, sy + 11, 0);
+
+ rcSrc.x = sx + 15 * 8 + 24;
+ rcSrc.y = sy + 1;
+
+ ss = (playera.sword - 1) * 3;
+ if(playera.sword == 3) ss = 18;
+ SDL_BlitSurface(itemimg[ss], NULL, videobuffer, &rcSrc);
+
+ rcSrc.x = rcSrc.x + 16;
+ ss = (playera.shield - 1) * 3 + 1;
+ if(playera.shield == 3) ss = 19;
+ SDL_BlitSurface(itemimg[ss], NULL, videobuffer, &rcSrc);
+
+ rcSrc.x = rcSrc.x + 16;
+ ss = (playera.armour - 1) * 3 + 2;
+ if(playera.armour == 3) ss = 20;
+ SDL_BlitSurface(itemimg[ss], NULL, videobuffer, &rcSrc);
+
+ nx = rcSrc.x + 13 + 3 * 8;
+ rcSrc.x = nx - 17;
+
+ if(playera.foundspell[0] == 1) {
+ for(int i = 0; i < 5; i++) {
+ rcSrc.x = rcSrc.x + 17;
+ if(playera.foundspell[i] == 1) SDL_BlitSurface(itemimg[7 + i], NULL, videobuffer, &rcSrc);
+ }
+ }
+ } else {
+ int sy = 57 + ff * 48;
+ sys_print(videobuffer, "Empty", 160 - 5 * 4, sy, 0);
+ }
+ }
+ // ------------------------------------------
+
+
+ if(currow == 0) {
+ rcDest.y = 18;
+ if(curcol == 0) rcDest.x = 10;
+ if(curcol == 1) rcDest.x = 108;
+ if(curcol == 2) rcDest.x = 170;
+ if(curcol == 3) rcDest.x = 230;
+ rcDest.x = (float)(rcDest.x + 2 + 2 * sin(3.14159 * 2 * itemyloc / 16));
+ }
+
+ if(currow > 0) {
+ rcDest.x = (float)(0 + 2 * sin(3.14159 * 2 * itemyloc / 16));
+ rcDest.y = (float)(53 + (currow - 1) * 48);
+ }
+
+ SDL_BlitSurface(itemimg[15], NULL, videobuffer, &rcDest);
+
+
+ if(lowerlock == 1) {
+ rcDest.y = 18;
+ if(curcol == 1) rcDest.x = 108;
+ if(curcol == 2) rcDest.x = 170;
+ rcDest.x = rcDest.x; // + 2 + 2 * sin(-3.14159 * 2 * itemyloc / 16)
+
+ SDL_BlitSurface(itemimg[15], NULL, videobuffer, &rcDest);
+ }
+
+ yy = 255;
+ if(ticks < ticks1 + 1000) {
+ yy = 255 * (ticks - ticks1) / 1000;
+ if(yy < 0) yy = 0;
+ if(yy > 255) yy = 255;
+ }
+
+ SDL_SetAlpha(videobuffer, SDL_SRCALPHA, (int)yy);
+ SDL_BLITVIDEO(videobuffer, NULL, video, NULL);
+ SDL_SetAlpha(videobuffer, SDL_SRCALPHA, 255);
+
+ SDL_Flip(video);
+ SDL_PumpEvents();
+
+ tickspassed = ticks;
+ ticks = SDL_GetTicks();
+
+ tickspassed = ticks - tickspassed;
+ fpsr = (float)tickspassed / 24;
+
+ fp++;
+ if(ticks > nextticks) {
+ nextticks = ticks + 1000;
+ fps = fp;
+ fp = 0;
+ }
+
+ clouddeg += 0.01 * fpsr;
+ while(clouddeg >= 360) clouddeg -= 360;
+
+ itemyloc += 0.6 * fpsr;
+ while(itemyloc >= 16) itemyloc -= 16;
+
+ SDL_Delay(10);
+ } while(1);
+
+ SDL_SetAlpha(cloudimg, SDL_SRCALPHA, 64);
+}
+
+void game_showlogos()
+{
+ float y;
+ int ticks1;
+
+ ticks = SDL_GetTicks();
+ ticks1 = ticks;
+
+ y = 0.0;
+
+ do {
+ y = 255.0;
+ if(ticks < ticks1 + 1000) {
+ y = 255.0 * ((float)(ticks - ticks1) / 1000.0);
+ if(y < 0.0) y = 0.0;
+ if(y > 255.0) y = 255.0;
+ }
+
+ if(ticks > ticks1 + 3000) {
+ y = 255.0 - 255.0 * ((float)(ticks - ticks1 - 3000.0) / 1000.0);
+ if(y < 0.0) y = 0.0;
+ if(y > 255.0) y = 255.0;
+ }
+
+ SDL_FillRect(videobuffer, NULL, 0);
+
+ SDL_SetAlpha(logosimg, SDL_SRCALPHA, (int)y);
+ SDL_BlitSurface(logosimg, NULL, videobuffer, NULL);
+ SDL_SetAlpha(logosimg, SDL_SRCALPHA, 255);
+
+ SDL_BLITVIDEO(videobuffer, NULL, video, NULL);
+
+ SDL_Flip(video);
+ SDL_PumpEvents();
+
+ tickspassed = ticks;
+ ticks = SDL_GetTicks();
+
+ tickspassed = ticks - tickspassed;
+ fpsr = (float)tickspassed / 24;
+
+ fp++;
+ if(ticks > nextticks) {
+ nextticks = ticks + 1000;
+ fps = fp;
+ fp = 0;
+ }
+
+ SDL_Delay(10);
+ if(ticks > ticks1 + 4000) break;
+ } while(1);
+}
+
+
+void game_swash()
+{
+ float y;
+
+ y = 0;
+
+ do {
+ y = y + 1 * fpsr;
+
+ SDL_SetAlpha(videobuffer, SDL_SRCALPHA, (int)y);
+ SDL_FillRect(videobuffer, NULL, 0);
+ SDL_BLITVIDEO(videobuffer, NULL, video, NULL);
+
+ SDL_Flip(video);
+ SDL_PumpEvents();
+
+ tickspassed = ticks;
+ ticks = SDL_GetTicks();
+
+ tickspassed = ticks - tickspassed;
+ fpsr = (float)tickspassed / 24.0;
+
+ fp++;
+ if(ticks > nextticks) {
+ nextticks = ticks + 1000;
+ fps = fp;
+ fp = 0;
+ }
+
+ clouddeg += 0.01 * fpsr;
+ while(clouddeg >= 360) clouddeg = clouddeg - 360;
+
+ if(y > 10) break;
+ } while(1);
+
+ y = 0;
+ do {
+ y = y + 1 * fpsr;
+
+ SDL_SetAlpha(videobuffer, SDL_SRCALPHA, (int)(y * 25));
+ SDL_BlitSurface(mapbg, NULL, videobuffer, NULL);
+
+ if(cloudson == 1) {
+ rcDest.x = (float)(256 + 256 * cos(3.141592 / 180 * clouddeg));
+ rcDest.y = (float)(192 + 192 * sin(3.141592 / 180 * clouddeg));
+ rcDest.w = 320;
+ rcDest.h = 240;
+
+ SDL_BlitSurface(cloudimg, &rcDest, videobuffer, NULL);
+ }
+
+ SDL_BLITVIDEO(videobuffer, NULL, video, NULL);
+ SDL_Flip(video);
+ SDL_PumpEvents();
+
+ tickspassed = ticks;
+ ticks = SDL_GetTicks();
+
+ tickspassed = ticks - tickspassed;
+ fpsr = (float)tickspassed / 24.0;
+
+ fp++;
+ if(ticks > nextticks) {
+ nextticks = ticks + 1000;
+ fps = fp;
+ fp = 0;
+ }
+
+ clouddeg += 0.01 * fpsr;
+ while(clouddeg >= 360) clouddeg = clouddeg - 360;
+
+ if(y > 10) break;
+ } while(1);
+
+
+ SDL_SetAlpha(videobuffer, SDL_SRCALPHA, 255);
+}
+
+void game_theend()
+{
+ for(int i = 0; i < MAXFLOAT; i++) {
+ floattext[i][0] = 0;
+ floaticon[i][0] = 0;
+ }
+
+ for(float y = 0; y < 100; y += fpsr) {
+ SDL_SetAlpha(videobuffer, SDL_SRCALPHA, (int)y);
+ SDL_FillRect(videobuffer, NULL, 0);
+ SDL_BLITVIDEO(videobuffer, NULL, video, NULL);
+
+ SDL_Flip(video);
+ SDL_PumpEvents();
+
+ tickspassed = ticks;
+ ticks = SDL_GetTicks();
+
+ tickspassed = ticks - tickspassed;
+ fpsr = (float)tickspassed / 24.0;
+
+ fp++;
+ if(ticks > nextticks) {
+ nextticks = ticks + 1000;
+ fps = fp;
+ fp = 0;
+ }
+ }
+
+ game_title(0);
+}
+
+void game_title(int mode)
+{
+ float xofs = 0;
+ int ticks, ticks1, keypause;
+ int cursel, ldstop;
+ int x, y;
+
+ rcSrc.x = 0;
+ rcSrc.y = 0;
+ rcSrc.w = 320;
+ rcSrc.h = 240;
+
+ SDL_FillRect(videobuffer2, &rcSrc, 0);
+ SDL_FillRect(videobuffer3, &rcSrc, 0);
+
+ ticks = SDL_GetTicks();
+
+ SDL_BlitSurface(videobuffer, NULL, videobuffer3, NULL);
+ SDL_BlitSurface(videobuffer, NULL, videobuffer2, NULL);
+
+ cursel = 0;
+
+ keypause = ticks + 220;
+
+ ticks1 = ticks;
+
+ if(menabled == 1 && config.music == 1) {
+ Mix_Volume(musicchannel, 0);
+ Mix_Pause(musicchannel);
+
+ menuchannel = Mix_PlayChannel(-1, mmenu, -1);
+ Mix_Volume(menuchannel, config.musicvol);
+ pmenu = 1;
+ }
+
+ ldstop = 0;
+
+ float ld = 0;
+ do {
+ SDL_Rect rc;
+
+ ld += 4.0 * fpsr;
+ if(ld > config.musicvol) ld = config.musicvol;
+ if(menabled == 1 && ldstop == 0) {
+ Mix_Volume(menuchannel, (int)ld);
+ if((int)ld == config.musicvol) ldstop = 1;
+ }
+
+ rc.x = -xofs;
+ rc.y = 0;
+
+ SDL_BlitSurface(titleimg, NULL, videobuffer, &rc);
+
+ rc.x = -xofs + 320.0;
+ rc.y = 0;
+
+ SDL_BlitSurface(titleimg, NULL, videobuffer, &rc);
+
+ rc.x = 0;
+ rc.y = 0;
+
+ SDL_BlitSurface(titleimg2, NULL, videobuffer, &rc);
+
+ y = 172;
+ x = 160 - 14 * 4;
+
+ sys_print(videobuffer, "new game/save/load", x, y, 4);
+ sys_print(videobuffer, "options", x, y + 16, 4);
+ sys_print(videobuffer, "quit game", x, y + 32, 4);
+
+ if(mode == 1) sys_print(videobuffer, "return", x, y + 48, 4);
+ else sys_print(videobuffer, "(c) 2005 by Daniel 'Syn9' Kennedy", 28, 224, 4);
+
+ rc.x = (float)(x - 16 - 4 * cos(3.14159 * 2 * itemyloc / 16));
+ rc.y = (float)(y - 4 + 16 * cursel);
+
+ SDL_BlitSurface(itemimg[15], NULL, videobuffer, &rc);
+
+ float yf = 255.0;
+ if(ticks < ticks1 + 1000) {
+ yf = 255.0 * ((float)(ticks - ticks1) / 1000.0);
+ if(y < 0.0) yf = 0.0;
+ if(y > 255.0) yf = 255.0;
+ }
+
+ SDL_SetAlpha(videobuffer, SDL_SRCALPHA, (int)yf);
+ SDL_BLITVIDEO(videobuffer, NULL, video, NULL);
+ SDL_SetAlpha(videobuffer, SDL_SRCALPHA, 255);
+
+ tickspassed = ticks;
+ ticks = SDL_GetTicks();
+
+ tickspassed = ticks - tickspassed;
+ fpsr = (float)tickspassed / 24.0;
+
+ fp++;
+ if(ticks > nextticks) {
+ nextticks = ticks + 1000;
+ fps = fp;
+ fp = 0;
+ }
+
+ float add = 0.5 * fpsr;
+ if(add > 1) add = 1;
+
+ xofs = xofs + add;
+ if(xofs >= 320.0) xofs -= 320.0;
+
+ itemyloc += 0.75 * fpsr;
+
+ while(itemyloc >= 16)
+ itemyloc = itemyloc - 16;
+
+ SDL_PollEvent(&event);
+
+ if(keypause < ticks) {
+ keys = SDL_GetKeyState(NULL);
+
+ if(event.type == SDL_KEYDOWN) {
+ keypause = ticks + 150;
+
+ if((keys[SDLK_ESCAPE] || keys[SDLK_LALT]) && mode == 1) break;
+ else if(keys[SDLK_UP]) {
+ cursel--;
+ if(cursel < 0) cursel = (mode == 1 ? 3 : 2);
+ } else if(keys[SDLK_DOWN]) {
+ cursel++;
+ if(cursel >= (mode == 1 ? 4 : 3)) cursel = 0;
+ } else if(keys[SDLK_LCTRL] || keys[SDLK_RETURN]) {
+ if(cursel == 0) {
+ game_saveloadnew();
+ ticks = SDL_GetTicks();
+ keypause = ticks + 150;
+ ticks1 = ticks;
+ } else if(cursel == 1) {
+ game_configmenu();
+ ticks = SDL_GetTicks();
+ keypause = ticks + 150;
+ ticks1 = ticks;
+ } else if(cursel == 2) {
+ exit(1);
+ } else if(cursel == 3) break;
+ }
+ }
+ }
+
+ SDL_Flip(video);
+ SDL_Delay(10);
+ } while(1);
+
+ itemticks = ticks + 210;
+
+ if(menabled == 1 && config.music == 1) {
+ Mix_HaltChannel(menuchannel);
+ Mix_Resume(musicchannel);
+ Mix_Volume(musicchannel, config.musicvol);
+ pmenu = 0;
+ }
+}
+
+void game_updanims()
+{
+ for(int i = 0; i <= lastobj; i++) {
+ int nframes = objectinfo[i][0];
+ int oanimspd = objectinfo[i][3];
+ float frame = objectframe[i][0];
+ int cframe = objectframe[i][1];
+ // objectinfo[i][6] = 0; // ?? out of bounds
+
+ if(nframes > 1) {
+ frame = frame + oanimspd / 50 * fpsr;
+ while(frame >= nframes)
+ frame = frame - nframes;
+
+ cframe = (int)frame; // truncate fractional part
+ if(cframe > nframes) cframe = nframes - 1;
+ if(cframe < 0) cframe = 0;
+
+ objectframe[i][0] = frame;
+ objectframe[i][1] = cframe;
+ }
+ }
+}
+
+void game_updatey()
+{
+ int yy, ff;
+
+ for(int i = 0; i <= 2400; i++)
+ ysort[i] = -1;
+
+ ff = (int)(player.py * 10);
+ if(ff < 0) ff = 0; // HACKFIX or ysort[yy] may go out of bounds
+ player.ysort = ff;
+ ysort[ff] = 0;
+
+ firsty = 2400;
+ lasty = 0;
+
+ for(int i = 1; i <= lastnpc; i++) {
+ yy = (int)(npcinfo[i].y * 10);
+
+ do {
+ if(ysort[yy] == -1 || yy == 2400) break;
+ yy = yy + 1;
+ } while(1);
+
+ ysort[yy] = i;
+ if(yy < firsty) firsty = yy;
+ if(yy > lasty) lasty = yy;
+ }
+}
+
+void game_updmusic()
+{
+ Mix_Chunk *iplaysound = NULL;
+
+ if(menabled == 1 && config.music == 1) {
+
+ // if(curmap > 5 && curmap < 42) iplaysound = macademy;
+ // if(curmap > 47) iplaysound = mgardens;
+ iplaysound = mgardens;
+ if(roomlock == 1) iplaysound = mboss;
+
+ if(iplaysound == mboss && pboss) iplaysound = NULL;
+ if(iplaysound == mgardens && pgardens) iplaysound = NULL;
+
+ if(iplaysound != NULL) {
+ Mix_HaltChannel(musicchannel);
+
+ pboss = 0;
+ pgardens = 0;
+ ptown = 0;
+ pacademy = 0;
+ pcitadel = 0;
+
+ if(iplaysound == mboss) pboss = 1;
+ if(iplaysound == mgardens) pgardens = 1;
+
+ musicchannel = Mix_PlayChannel(-1, iplaysound, -1);
+ Mix_Volume(musicchannel, config.musicvol);
+ } else {
+ if(!Mix_Playing(musicchannel)) {
+ loopseta = loopseta + 1;
+ if(loopseta == 4) loopseta = 0;
+
+ if(pgardens == 1) {
+ Mix_HaltChannel(musicchannel);
+ if(pgardens == 1 && loopseta == 0) musicchannel = Mix_PlayChannel(-1, mgardens, 0);
+ if(pgardens == 1 && loopseta == 1) musicchannel = Mix_PlayChannel(-1, mgardens2, 0);
+ if(pgardens == 1 && loopseta == 2) musicchannel = Mix_PlayChannel(-1, mgardens3, 0);
+ if(pgardens == 1 && loopseta == 3) musicchannel = Mix_PlayChannel(-1, mgardens4, 0);
+ }
+
+ Mix_Volume(musicchannel, config.musicvol);
+ }
+ }
+ }
+}
+
+void game_updnpcs()
+{
+ float npx, npy, onpx, onpy;
+ unsigned int *temp, dq, bgc;
+ float nnxa = 0, nnya = 0, nnxb = 0, nnyb = 0;
+ int pass = 0, checkpass;
+ float wspd, xdif, ydif;
+ int sx, sy;
+ int dospell = 0;
+
+ for(int i = 1; i <= lastnpc; i++) {
+ if(npcinfo[i].hp > 0) {
+ // is npc walking
+ pass = 0;
+ if(npcinfo[i].attacking == 0) pass = 1;
+ if(npcinfo[i].spriteset == 5) pass = 1;
+ if(pass == 1) {
+ int moveup = 0;
+ int movedown = 0;
+ int moveleft = 0;
+ int moveright = 0;
+
+ npx = npcinfo[i].x;
+ npy = npcinfo[i].y;
+
+ onpx = npx;
+ onpy = npy;
+
+ wspd = npcinfo[i].walkspd / 4;
+
+ if(npcinfo[i].spriteset == 10) wspd = wspd * 2;
+ int wdir = npcinfo[i].walkdir;
+
+ int mode = npcinfo[i].movementmode;
+
+ xdif = player.px - npx;
+ 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 == 2 && npcinfo[i].castpause > ticks) mode = -1;
+
+ if(mode == 3) {
+ mode = 1;
+ if(abs(xdif) < 4 * 16 && abs(ydif) < 4 * 16) mode = 3;
+ }
+
+ checkpass = 0;
+
+ // 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 = 1;
+ if(xdif > -4) moveright = 1;
+ if(ydif < 4) moveup = 1;
+ if(ydif > -4) movedown = 1;
+ }
+ // *******************
+
+ // *** 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 = 1;
+ moveleft = 1;
+ } else if(movingdir == 1) {
+ wdir = 0; // up
+ moveup = 1;
+ } else if(movingdir == 2) {
+ wdir = 3; // right
+ moveup = 1;
+ moveright = 1;
+ } else if(movingdir == 3) {
+ wdir = 3; // right
+ moveright = 1;
+ } else if(movingdir == 4) {
+ wdir = 3; // right
+ moveright = 1;
+ movedown = 1;
+ } else if(movingdir == 5) {
+ wdir = 1; // down
+ movedown = 1;
+ } else if(movingdir == 6) {
+ wdir = 2; // left
+ movedown = 1;
+ moveleft = 1;
+ } else if(movingdir == 7) {
+ wdir = 2; // left
+ moveleft = 1;
+ }
+
+ checkpass = 1;
+ }
+ // *******************
+
+ // *** 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 = 1;
+ if(xdif > -4) moveleft = 1;
+ if(ydif < 4) movedown = 1;
+ if(ydif > -4) moveup = 1;
+ }
+ // *******************
+
+ // -------------- ?? move*** vs movin***
+ int movinup = 0;
+ int movindown = 0;
+ int movinleft = 0;
+ int movinright = 0;
+
+ float xp = (npx / 2 + 6);
+ float yp = (npy / 2 + 10);
+
+ if(npcinfo[i].spriteset == 10) wspd = wspd * 2;
+
+ float ii = wspd * fpsr;
+ if(ii < 1) ii = 1;
+
+ SDL_LockSurface(clipbg);
+
+ if(moveup) {
+ sx = xp;
+ sy = yp - ii;
+ temp = clipbg->pixels + sy * clipbg->pitch + sx * clipbg->format->BytesPerPixel;
+ dq = *temp;
+ if(npcinfo[i].spriteset == 11) dq = 0;
+
+ if(dq == 0) movinup = 1;
+ if(dq > 0) {
+ sx = xp - ii;
+ sy = yp - ii;
+ temp = clipbg->pixels + sy * clipbg->pitch + sx * clipbg->format->BytesPerPixel;
+ dq = *temp;
+ if(npcinfo[i].spriteset == 11) dq = 0;
+ if(dq == 0) {
+ movinup = 1;
+ movinleft = 1;
+ }
+ }
+ if(dq > 0) {
+ sx = xp + ii;
+ sy = yp - ii;
+ temp = clipbg->pixels + sy * clipbg->pitch + sx * clipbg->format->BytesPerPixel;
+ dq = *temp;
+ if(npcinfo[i].spriteset == 11) dq = 0;
+ if(dq == 0) {
+ movinup = 1;
+ movinright = 1;
+ }
+ }
+ }
+
+ if(movedown) {
+ sx = xp;
+ sy = yp + ii;
+ temp = clipbg->pixels + sy * clipbg->pitch + sx * clipbg->format->BytesPerPixel;
+ dq = *temp;
+ if(npcinfo[i].spriteset == 11) dq = 0;
+ if(dq == 0) movindown = 1;
+ if(dq > 0) {
+ sx = xp - ii;
+ sy = yp + ii;
+ temp = clipbg->pixels + sy * clipbg->pitch + sx * clipbg->format->BytesPerPixel;
+ dq = *temp;
+ if(npcinfo[i].spriteset == 11) dq = 0;
+ if(dq == 0) {
+ movindown = 1;
+ movinleft = 1;
+ }
+ }
+ if(dq > 0) {
+ sx = xp + ii;
+ sy = yp + ii;
+ temp = clipbg->pixels + sy * clipbg->pitch + sx * clipbg->format->BytesPerPixel;
+ dq = *temp;
+ if(npcinfo[i].spriteset == 11) dq = 0;
+ if(dq == 0 ) {
+ movindown = 1;
+ movinright = 1;
+ }
+ }
+ }
+
+ if(moveleft) {
+ sx = xp - ii;
+ sy = yp;
+ temp = clipbg->pixels + sy * clipbg->pitch + sx * clipbg->format->BytesPerPixel;
+ dq = *temp;
+ if(npcinfo[i].spriteset == 11) dq = 0;
+ if(dq == 0) movinleft = 1;
+ if(dq > 0) {
+ sx = xp - ii;
+ sy = yp - ii;
+ temp = clipbg->pixels + sy * clipbg->pitch + sx * clipbg->format->BytesPerPixel;
+ dq = *temp;
+ if(npcinfo[i].spriteset == 11) dq = 0;
+ if(dq == 0) {
+ movinleft = 1;
+ movinup = 1;
+ }
+ }
+ if(dq > 0) {
+ sx = xp - ii;
+ sy = yp + ii;
+ temp = clipbg->pixels + sy * clipbg->pitch + sx * clipbg->format->BytesPerPixel;
+ dq = *temp;
+ if(npcinfo[i].spriteset == 11) dq = 0;
+ if(dq == 0) {
+ movinleft = 1;
+ movindown = 1;
+ }
+ }
+ }
+
+ if(moveright) {
+ sx = xp + ii;
+ sy = yp;
+ temp = clipbg->pixels + sy * clipbg->pitch + sx * clipbg->format->BytesPerPixel;
+ dq = *temp;
+ if(npcinfo[i].spriteset == 11) dq = 0;
+ if(dq == 0) movinright = 1;
+ if(dq > 0) {
+ sx = xp + ii;
+ sy = yp - ii;
+ temp = clipbg->pixels + sy * clipbg->pitch + sx * clipbg->format->BytesPerPixel;
+ dq = *temp;
+ if(npcinfo[i].spriteset == 11) dq = 0;
+ if(dq == 0) {
+ movinright = 1;
+ movinup = 1;
+ }
+ }
+ if(dq > 0) {
+ sx = xp + ii;
+ sy = yp + ii;
+ temp = clipbg->pixels + sy * clipbg->pitch + sx * clipbg->format->BytesPerPixel;
+ dq = *temp;
+ if(npcinfo[i].spriteset == 11) dq = 0;
+ if(dq == 0) {
+ movinright = 1;
+ movindown = 1;
+ }
+ }
+ }
+
+ if(movinup) npy = npy - wspd * fpsr;
+ if(movindown) npy = npy + wspd * fpsr;
+ if(movinleft) npx = npx - wspd * fpsr;
+ if(movinright) npx = npx + wspd * fpsr;
+
+ if(checkpass == 1) {
+ 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 == 10) aspd = wspd / 2;
+
+ xp = (npx / 2 + 6);
+ yp = (npy / 2 + 10);
+
+ sx = xp;
+ sy = yp;
+ temp = clipbg->pixels + sy * clipbg->pitch + sx * clipbg->format->BytesPerPixel;
+ bgc = *temp;
+
+ SDL_UnlockSurface(clipbg);
+
+ 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 == 11) bgc = 0;
+
+ int rst = 0;
+
+ if(npcinfo[i].spriteset == 11) {
+ if(npx < 40 || npx > 280 || npy < 36 || npy > 204) rst = 1;
+ }
+
+ if(bgc > 0 || rst == 1) {
+ npx = onpx;
+ npy = onpy;
+ }
+
+ npcinfo[i].x = npx;
+ npcinfo[i].y = npy;
+
+ npcinfo[i].walkdir = wdir;
+ npcinfo[i].moving = 0;
+
+ if(npx != onpx || npy != onpy) npcinfo[i].moving = 1;
+
+ if(npcinfo[i].moving == 1) {
+ float frame = npcinfo[i].frame;
+ int cframe = npcinfo[i].cframe;
+
+ frame = frame + aspd * fpsr;
+ while(frame >= 16)
+ frame = frame - 16;
+
+ cframe = (int)(frame);
+ if(cframe > 16) cframe = 16 - 1;
+ if(cframe < 0) cframe = 0;
+
+ npcinfo[i].frame = frame;
+ npcinfo[i].cframe = cframe;
+ }
+
+ // spriteset1 specific
+ if(npcinfo[i].spriteset == 1 && npcinfo[i].attackattempt < ticks) {
+ if(npcinfo[i].attacknext < ticks && npcinfo[i].pause < ticks && npcinfo[i].attacking == 0) {
+ 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(menabled == 1 && config.effects == 1) {
+ int snd = Mix_PlayChannel(-1, sfx[sndenemyhit], 0);
+ Mix_Volume(snd, config.effectsvol);
+ }
+
+ npcinfo[i].attacking = 1;
+ npcinfo[i].attackframe = 0;
+ }
+ }
+ }
+ }
+
+ // onewing specific
+ if(npcinfo[i].spriteset == 2) {
+ if(npcinfo[i].attacknext < ticks && npcinfo[i].pause < ticks && npcinfo[i].attacking == 0) {
+ 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(menabled == 1 && config.effects == 1) {
+ int snd = Mix_PlayChannel(-1, sfx[sndbite], 0);
+ Mix_Volume(snd, config.effectsvol);
+ }
+
+ npcinfo[i].attacking = 1;
+ npcinfo[i].attackframe = 0;
+
+ npcinfo[i].headtargetx[0] = player.px + 12;
+ npcinfo[i].headtargety[0] = player.py - 4;
+ }
+ }
+
+ }
+
+ dospell = 0;
+
+ if(npcinfo[i].attacking == 0 && npcinfo[i].castpause < ticks) {
+ npcinfo[i].swayspd = npcinfo[i].swayspd + npcinfo[i].swayspd / 200 * fpsr;
+ if(npcinfo[i].swayspd > 15) {
+ dospell = 1;
+ npcinfo[i].swayspd = 1;
+ }
+
+ // sway code
+ npcinfo[i].swayangle = npcinfo[i].swayangle + npcinfo[i].swayspd * fpsr;
+ if(npcinfo[i].swayangle >= 360) npcinfo[i].swayangle = npcinfo[i].swayangle - 360;
+
+ npcinfo[i].headtargetx[0] = npcinfo[i].x + (24 - npcinfo[i].swayspd / 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 == 1) {
+ npcinfo[i].pause = ticks + 3000;
+ npcinfo[i].attacknext = ticks + 4500;
+ npcinfo[i].castpause = ticks + 4500;
+
+ game_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 == 3 || npcinfo[i].spriteset == 4) {
+ if(npcinfo[i].attacknext < ticks && npcinfo[i].pause < ticks && npcinfo[i].attacking == 0) {
+ npcinfo[i].attacking = 1;
+ npcinfo[i].attackframe = 0;
+
+ game_castspell(1, npcinfo[i].x, npcinfo[i].y, player.px, player.py, i);
+ }
+
+ if(npcinfo[i].castpause < ticks) {
+ game_castspell(6, npcinfo[i].x, npcinfo[i].y, player.px, player.py, i);
+ npcinfo[i].castpause = ticks + 12000;
+ }
+ }
+
+
+ // firehydra specific
+ if(npcinfo[i].spriteset == 5) {
+ npcinfo[i].swayspd = 4;
+
+ // sway code
+ npcinfo[i].swayangle = npcinfo[i].swayangle + npcinfo[i].swayspd * 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(menabled == 1 && config.effects == 1) {
+ int snd = Mix_PlayChannel(-1, sfx[sndbite], 0);
+ Mix_Volume(snd, config.effectsvol);
+ }
+
+ npcinfo[i].attacking = 1;
+ 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 == 6 && npcinfo[i].attackattempt < ticks) {
+ if(npcinfo[i].attacknext < ticks && npcinfo[i].pause < ticks && npcinfo[i].attacking == 0) {
+ 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 = 1;
+ npcinfo[i].attackframe = 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;
+ }
+
+ game_castspell(7, nnxa, nnya, nnxb, nnyb, i);
+ }
+ }
+ }
+ }
+
+ // wizard1 specific
+ if(npcinfo[i].spriteset == 7) {
+ if(npcinfo[i].attacknext < ticks && npcinfo[i].pause < ticks && npcinfo[i].attacking == 0) {
+ npcinfo[i].attacking = 1;
+ npcinfo[i].attackframe = 0;
+
+ game_castspell(9, npcinfo[i].x, npcinfo[i].y, player.px, player.py, i);
+ }
+
+ if(npcinfo[i].castpause < ticks) {
+ // game_castspell 6, npcinfo[i].x, npcinfo[i].y, player.px, player.py, i
+ // npcinfo[i].castpause = ticks + 12000
+ }
+
+ }
+
+ // spriteset6 specific
+ if(npcinfo[i].spriteset == 8 && npcinfo[i].attackattempt < ticks) {
+ if(npcinfo[i].attacknext < ticks && npcinfo[i].pause < ticks && npcinfo[i].attacking == 0) {
+ 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 = 1;
+ npcinfo[i].attackframe = 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;
+ }
+
+ game_castspell(7, nnxa, nnya, nnxb, nnyb, i);
+ }
+ }
+ }
+ }
+
+ // twowing specific
+ if(npcinfo[i].spriteset == 9) {
+ if(npcinfo[i].attacknext < ticks && npcinfo[i].pause < ticks && npcinfo[i].attacking == 0) {
+ 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(menabled == 1 && config.effects == 1) {
+ int snd = Mix_PlayChannel(-1, sfx[sndbite], 0);
+ Mix_Volume(snd, config.effectsvol);
+ }
+
+ npcinfo[i].attacking = 1;
+ npcinfo[i].attackframe = 0;
+
+ npcinfo[i].headtargetx[0] = player.px + 12;
+ npcinfo[i].headtargety[0] = player.py - 4;
+ }
+ }
+
+ }
+
+ if(npcinfo[i].attacking == 0 && npcinfo[i].castpause < ticks) {
+ npcinfo[i].swayspd = 4;
+
+ // sway code
+ npcinfo[i].swayangle = npcinfo[i].swayangle + npcinfo[i].swayspd * fpsr;
+ if(npcinfo[i].swayangle >= 360) npcinfo[i].swayangle = npcinfo[i].swayangle - 360;
+
+ npcinfo[i].headtargetx[0] = npcinfo[i].x + (24 - npcinfo[i].swayspd / 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 == 1) {
+ npcinfo[i].pause = ticks + 3000;
+ npcinfo[i].attacknext = ticks + 5000;
+ npcinfo[i].castpause = ticks + 3000;
+
+ game_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 == 10 && npcinfo[i].attackattempt < ticks) {
+ if(npcinfo[i].attacknext < ticks && npcinfo[i].pause < ticks && npcinfo[i].attacking == 0) {
+ 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(menabled == 1 && config.effects == 1) {
+ int snd = Mix_PlayChannel(-1, sfx[sndenemyhit], 0);
+ Mix_Volume(snd, config.effectsvol);
+ }
+
+ npcinfo[i].attacking = 1;
+ npcinfo[i].attackframe = 0;
+ }
+ }
+ }
+ }
+
+
+ // endboss specific
+ if(npcinfo[i].spriteset == 11 && npcinfo[i].attackattempt < ticks) {
+ if(npcinfo[i].attacknext < ticks && npcinfo[i].pause < ticks && npcinfo[i].attacking == 0) {
+ 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(menabled == 1 && config.effects == 1) {
+ int snd = Mix_PlayChannel(-1, sfx[sndice], 0);
+ Mix_Volume(snd, config.effectsvol);
+ }
+ npcinfo[i].attacking = 1;
+ npcinfo[i].attackframe = 0;
+ }
+ }
+ }
+ }
+ }
+
+
+ int dist; float damage;
+
+ npx = npcinfo[i].x;
+ npy = npcinfo[i].y;
+
+ int xp = (npx / 2 + 6);
+ int yp = (npy / 2 + 10);
+
+ rcSrc.x = xp - 1;
+ rcSrc.y = yp - 1;
+ rcSrc.w = 3;
+ rcSrc.h = 3;
+
+ if(npcinfo[i].pause < ticks) SDL_FillRect(clipbg, &rcSrc, i);
+
+
+ pass = 0;
+ if(npcinfo[i].attacking == 1) pass = 1;
+ if(npcinfo[i].spriteset == 5) {
+ if(npcinfo[i].attacking2[0] == 1) pass = 1;
+ if(npcinfo[i].attacking2[1] == 1) pass = 1;
+ if(npcinfo[i].attacking2[2] == 1) pass = 1;
+ }
+
+ if(pass == 1) {
+ // spriteset1 specific
+ if(npcinfo[i].spriteset == 1) {
+ npcinfo[i].attackframe = npcinfo[i].attackframe + npcinfo[i].attackspd * fpsr;
+ if(npcinfo[i].attackframe >= 16) {
+ npcinfo[i].attackframe = 0;
+ npcinfo[i].attacking = 0;
+ npcinfo[i].attacknext = ticks + npcinfo[i].attackdelay;
+ }
+
+ npcinfo[i].cattackframe = (int)(npcinfo[i].attackframe);
+
+ npx = npcinfo[i].x;
+ npy = npcinfo[i].y;
+
+ xdif = player.px - npx;
+ 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 = 0;
+
+ damage = (float)npcinfo[i].attackdamage * (0.5 + RND() * 1.0);
+
+ if(player.hp > 0) game_damageplayer(damage);
+ }
+ }
+
+ if(npcinfo[i].spriteset == 2) {
+ // 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);
+ 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 = 0;
+ 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 = 0
+ damage = (float)npcinfo[i].attackdamage * (1.0 + (RND() * 0.5));
+ if(player.hp > 0) game_damageplayer(damage);
+ }
+ }
+
+
+ // firehydra
+ if(npcinfo[i].spriteset == 5) {
+ for(int ff = 0; ff <= 2; ff++) {
+ if(npcinfo[i].attacking2[ff] == 1) {
+ 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 * .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] = 0;
+ 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) = 0
+ damage = (float)npcinfo[i].attackdamage * (1.0 + RND() * 0.5);
+ if(player.hp > 0) game_damageplayer(damage);
+ }
+ }
+ }
+
+ }
+
+ // twowing specific
+ if(npcinfo[i].spriteset == 9) {
+ // 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);
+ 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 = 0;
+ 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 = 0
+ damage = (float)npcinfo[i].attackdamage * (1.0 + RND() * 0.5);
+ if(player.hp > 0) game_damageplayer(damage);
+ }
+ }
+
+ // dragon 2 specific
+ if(npcinfo[i].spriteset == 10) {
+
+ npcinfo[i].attackframe = npcinfo[i].attackframe + npcinfo[i].attackspd * fpsr;
+ if(npcinfo[i].attackframe >= 16) {
+ npcinfo[i].attackframe = 0;
+ npcinfo[i].attacking = 0;
+ npcinfo[i].attacknext = ticks + npcinfo[i].attackdelay;
+ }
+
+ npcinfo[i].cattackframe = (int)(npcinfo[i].attackframe);
+
+ npx = npcinfo[i].x;
+ npy = npcinfo[i].y;
+
+ xdif = player.px - npx;
+ 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 = 0
+ damage = (float)npcinfo[i].attackdamage * (0.5 + RND() * 1.0);
+ if(player.hp > 0) game_damageplayer(damage);
+ }
+ }
+
+ // endboss specific
+ if(npcinfo[i].spriteset == 11) {
+ npcinfo[i].attackframe = npcinfo[i].attackframe + npcinfo[i].attackspd * fpsr;
+ if(npcinfo[i].attackframe >= 16) {
+ npcinfo[i].attackframe = 0;
+ npcinfo[i].attacking = 0;
+ npcinfo[i].attacknext = ticks + npcinfo[i].attackdelay;
+ }
+
+ npcinfo[i].cattackframe = (int)(npcinfo[i].attackframe);
+
+ npx = npcinfo[i].x;
+ npy = npcinfo[i].y;
+
+ xdif = player.px - npx;
+ 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 = 0
+ damage = (float)npcinfo[i].attackdamage * (0.5 + RND() * 1.0);
+ if(player.hp > 0) game_damageplayer(damage);
+ }
+ }
+ }
+ // -------end fight code
+ }
+ }
+}
+
+void game_updspells()
+{
+ int foundel[5];
+ float npx, npy;
+ long cl1, cl2, cl3;
+ int ll[4][2];
+
+ float xloc = 0, yloc = 0, xst, yst, xdif, ydif;
+
+ for(int i = 0; i < MAXSPELL; i++) {
+ if(spellinfo[i].frame > 0) {
+ int spellnum = spellinfo[i].spellnum;
+
+ // water
+ if(spellnum == 0 && forcepause == 0) {
+ float fr = (32 - spellinfo[i].frame);
+
+ 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.x = 32 + fi * 16;
+ rcSrc.y = 80;
+ rcSrc.w = 16;
+ rcSrc.h = 16;
+
+ xloc = spellinfo[i].enemyx + 12 + ll[f][0] * 16;
+ yloc = spellinfo[i].enemyy + 16 + ll[f][1] * 16;
+
+ rcDest.x = xloc;
+ rcDest.y = 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.x = 32 + fi * 16;
+ rcSrc.y = 80;
+ rcSrc.w = 16;
+ rcSrc.h = 16;
+
+ xst = spellinfo[i].enemyx + 12 + ll[f][0] * 16;
+ 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.x = xloc;
+ rcDest.y = yloc;
+
+ alf = 255;
+ }
+
+ if(xloc > -16 && xloc < 304 && yloc > -16 && yloc < 224) {
+ SDL_SetAlpha(spellimg, SDL_SRCALPHA, alf);
+ SDL_BlitSurface(spellimg, &rcSrc, videobuffer, &rcDest);
+ SDL_SetAlpha(spellimg, SDL_SRCALPHA, 255);
+
+ if(spellinfo[i].damagewho == 0) {
+ for(int e = 1; e <= lastnpc; e++) {
+
+ xdif = (xloc + 16) - (npcinfo[e].x + 12);
+ 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) {
+ game_damagenpc(e, damage, 1);
+ if(menabled == 1 && config.effects == 1) {
+ int snd = Mix_PlayChannel(-1, sfx[sndice], 0);
+ Mix_Volume(snd, config.effectsvol);
+ }
+ }
+ }
+ }
+ }
+
+ // check for post damage
+ if(nposts > 0) {
+ for(int e = 0; e <= nposts - 1; e++) {
+ xdif = (xloc + 16) - (postinfo[e][0] + 8);
+ ydif = (yloc + 16) - (postinfo[e][1] + 8);
+
+ if((abs(xdif) < 16 && abs(ydif) < 16)) {
+ objmapf[curmap][(int)postinfo[e][0] / 16][(int)postinfo[e][1] / 16] = 1;
+ objmap[(int)postinfo[e][0] / 16][(int)postinfo[e][1] / 16] = -1;
+
+ rcSrc.x = postinfo[e][0] / 2;
+ rcSrc.y = postinfo[e][1] / 2;
+ rcSrc.w = 8;
+ rcSrc.h = 8;
+
+ SDL_FillRect(clipbg2, &rcSrc, 0);
+
+ game_addFloatIcon(99, postinfo[e][0], postinfo[e][1]);
+
+ if(menabled == 1 && config.effects == 1) {
+ int snd = Mix_PlayChannel(-1, sfx[sndice], 0);
+ Mix_Volume(snd, config.effectsvol);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // metal
+ if(spellnum == 1 && forcepause == 0) {
+ float xdif, ydif;
+ int npc;
+ int fr = (int)((32 - spellinfo[i].frame)*4) % 3;
+
+ rcSrc.x = fr * 48;
+ rcSrc.y = 0;
+ rcSrc.w = 48;
+ rcSrc.h = 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.x = xloc;
+ rcDest.y = yloc;
+
+ SDL_BlitSurface(spellimg, &rcSrc, videobuffer, &rcDest);
+
+ 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++) {
+ xdif = (xloc + 24) - (npcinfo[e].x + 12);
+ 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) {
+ game_damagenpc(e, damage, 1);
+ if(menabled == 1 && config.effects == 1) {
+ int snd = Mix_PlayChannel(-1, sfx[sndmetalhit], 0);
+ Mix_Volume(snd, config.effectsvol);
+ }
+ }
+ }
+ }
+ }
+
+ if(spellinfo[i].damagewho == 1) {
+
+ // --------- boss 1 specific
+ if(spellinfo[i].frame == 0 && npcinfo[spellinfo[i].npc].spriteset == 3) {
+ npc = spellinfo[i].npc;
+ npcinfo[npc].attackframe = 0;
+ npcinfo[npc].attacking = 0;
+
+ npcinfo[npc].pause = ticks + 1000;
+ npcinfo[npc].attacknext = ticks + 4000;
+ }
+ // ---------------
+
+ // --------- blackknight specific
+ if(spellinfo[i].frame == 0 && npcinfo[spellinfo[i].npc].spriteset == 4) {
+ npc = spellinfo[i].npc;
+ npcinfo[npc].attackframe = 0;
+ npcinfo[npc].attacking = 0;
+
+ npcinfo[npc].pause = ticks + 1000;
+ npcinfo[npc].attacknext = ticks + 3500;
+ }
+ // ---------------
+
+ xdif = (xloc + 24) - (player.px + 12);
+ ydif = (yloc + 24) - (player.py + 12);
+
+ if((abs(xdif) < 24 && abs(ydif) < 24) && player.pause < ticks) {
+ npx = player.px;
+ npy = player.py;
+
+ float damage = (float)npcinfo[spellinfo[i].npc].spelldamage * (1.0 + RND() * 0.5);
+
+ if(player.hp > 0) {
+ game_damageplayer(damage);
+ if(menabled == 1 && config.effects == 1) {
+ int snd = Mix_PlayChannel(-1, sfx[sndmetalhit], 0);
+ Mix_Volume(snd, config.effectsvol);
+ }
+ }
+ }
+ }
+
+
+ // check for(int post damage
+ if(nposts > 0) {
+ for(int e = 0; e <= nposts - 1; e++) {
+ xdif = (xloc + 24) - (postinfo[e][0] + 8);
+ ydif = (yloc + 24) - (postinfo[e][1] + 8);
+
+ if((abs(xdif) < 24 && abs(ydif) < 24)) {
+ objmapf[curmap][(int)postinfo[e][0] / 16][(int)postinfo[e][1] / 16] = 1;
+ objmap[(int)postinfo[e][0] / 16][(int)postinfo[e][1] / 16] = -1;
+
+ rcSrc.x = postinfo[e][0] / 2;
+ rcSrc.y = postinfo[e][1] / 2;
+ rcSrc.w = 8;
+ rcSrc.h = 8;
+
+ SDL_FillRect(clipbg2, &rcSrc, 0);
+
+ game_addFloatIcon(99, postinfo[e][0], postinfo[e][1]);
+
+ if(menabled == 1 && config.effects == 1) {
+ int snd = Mix_PlayChannel(-1, sfx[sndmetalhit], 0);
+ Mix_Volume(snd, config.effectsvol);
+ }
+ }
+ }
+ }
+ }
+
+ // earth
+ if(spellnum == 2 && forcepause == 0) {
+ 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.x = 32 * spellinfo[i].rockimg[f];
+ rcSrc.y = 48;
+ rcSrc.w = 32;
+ rcSrc.h = 32;
+
+ int scatter = 0;
+ 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 = 1;
+ 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.x = xloc;
+ rcDest.y = yloc;
+
+ if(xloc > -16 && xloc < 304 && yloc > -16 && yloc < 224) {
+ SDL_BlitSurface(spellimg, &rcSrc, videobuffer, &rcDest);
+
+ if(scatter == 1) {
+ if(spellinfo[i].damagewho == 0) {
+ for(int e = 1; e <= lastnpc; e++) {
+ xdif = (xloc + 16) - (npcinfo[e].x + 12);
+ 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) {
+ game_damagenpc(e, damage, 1);
+ if(menabled == 1 && config.effects == 1) {
+ int snd = Mix_PlayChannel(-1, sfx[sndrocks], 0);
+ Mix_Volume(snd, config.effectsvol);
+ }
+ }
+ }
+ }
+ }
+
+
+ // check for(int post damage
+ if(nposts > 0) {
+ for(int e = 0; e <= nposts - 1; e++) {
+ xdif = (xloc + 16) - (postinfo[e][0] + 8);
+ ydif = (yloc + 16) - (postinfo[e][1] + 8);
+
+ if((abs(xdif) < 16 && abs(ydif) < 16)) {
+ objmapf[curmap][(int)postinfo[e][0] / 16][(int)postinfo[e][1] / 16] = 1;
+ objmap[(int)postinfo[e][0] / 16][(int)postinfo[e][1] / 16] = -1;
+
+ rcSrc.x = postinfo[e][0] / 2;
+ rcSrc.y = postinfo[e][1] / 2;
+ rcSrc.w = 8;
+ rcSrc.h = 8;
+
+ SDL_FillRect(clipbg2, &rcSrc, 0);
+
+ game_addFloatIcon(99, postinfo[e][0], postinfo[e][1]);
+
+ if(menabled == 1 && config.effects == 1) {
+ int snd = Mix_PlayChannel(-1, sfx[sndrocks], 0);
+ Mix_Volume(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.x = fr * 32;
+ rcSrc.y = 96 + 48;
+ rcSrc.w = 32;
+ rcSrc.h = 64;
+
+ rcDest.x = player.px - 4;
+ rcDest.y = player.py + 16 - 48;
+
+ int f = 160;
+ if(fra < 8) f = 192 * fra / 8;
+ if(fra > 24) f = 192 * (1 - (fra - 24) / 8);
+
+ SDL_SetAlpha(spellimg, SDL_SRCALPHA, f);
+ SDL_BlitSurface(spellimg, &rcSrc, videobuffer, &rcDest);
+ SDL_SetAlpha(spellimg, SDL_SRCALPHA, 255);
+
+ spellinfo[i].frame = spellinfo[i].frame - 0.3 * fpsr;
+ if(spellinfo[i].frame < 0) {
+ spellinfo[i].frame = 0;
+ forcepause = 0;
+
+ npx = player.px + 12;
+ npy = player.py + 20;
+
+ int lx = (int)npx / 16;
+ int ly = (int)npy / 16;
+
+ for(int f = 0; f < 5; f++) { // !! f < 5
+ foundel[f] = 0;
+ }
+
+ 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] = 1;
+ }
+ }
+
+ int o = objmap[sx][sy];
+ if(o > -1) {
+ if(objectinfo[o][4] == 1) foundel[2] = 1;
+ if(o == 1 || o == 2) {
+ foundel[2] = 1;
+ foundel[4] = 1;
+ }
+ }
+ }
+ }
+ }
+
+ char line[256];
+ strcpy(line, "Found... nothing...");
+
+ for(int f = 0; f < 5; f++) {
+ if(foundel[f] == 1 && player.foundspell[f] == 0) {
+ player.foundspell[f] = 1;
+ player.spellcharge[f] = 0;
+ if(f == 1) strcpy(line, "Found... Water Essence");
+ if(f == 2) strcpy(line, "Found... Metal Essence");
+ if(f == 3) strcpy(line, "Found... Earth Essence");
+ if(f == 4) strcpy(line, "Found... Fire Essence");
+ break;
+ }
+ }
+
+ game_eventtext(line);
+ }
+ }
+
+ // room fireballs
+ if(spellnum == 6 && forcepause == 0) {
+
+ if(spellinfo[i].frame > 16) {
+ float fr = (32 - spellinfo[i].frame);
+
+ SDL_SetAlpha(spellimg, SDL_SRCALPHA, 192 * sin(3.14159 * fr / 4));
+
+ rcSrc.x = 16 * (int)(RND() * 2);
+ rcSrc.y = 80;
+ rcSrc.w = 16;
+ rcSrc.h = 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.x = xloc;
+ rcDest.y = yloc;
+
+ SDL_BlitSurface(spellimg, &rcSrc, videobuffer, &rcDest);
+ }
+
+ SDL_SetAlpha(spellimg, SDL_SRCALPHA, 255);
+ } else {
+ SDL_SetAlpha(spellimg, SDL_SRCALPHA, 192);
+
+ rcSrc.x = 16 * (int)(RND() * 2);
+ rcSrc.y = 80;
+ rcSrc.w = 16;
+ rcSrc.h = 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.x = xloc;
+ rcDest.y = yloc;
+
+ SDL_BlitSurface(spellimg, &rcSrc, videobuffer, &rcDest);
+ }
+
+ if(xloc < -1 || yloc < -1 || xloc > 304 || yloc > 224) spellinfo[i].ballon[ff] = 0;
+ }
+
+ SDL_SetAlpha(spellimg, SDL_SRCALPHA, 255);
+ }
+
+ 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;
+
+ xdif = (xloc + 8) - (player.px + 12);
+ 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) game_damageplayer(damage);
+
+ if(menabled == 1 && config.effects == 1) {
+ int snd = Mix_PlayChannel(-1, sfx[sndfire], 0);
+ Mix_Volume(snd, config.effectsvol);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // lightning bomb
+ if(spellnum == 8) {
+
+ cl1 = SDL_MapRGB(videobuffer->format, 0, 32, 204);
+ cl2 = SDL_MapRGB(videobuffer->format, 142, 173, 191);
+ cl3 = SDL_MapRGB(videobuffer->format, 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 = y - 1;
+ if(orn == 2) y = y + 1;
+
+ sys_line(videobuffer,x, y - 1, x, y + 2, cl1);
+ sys_line(videobuffer,x, y, x, y + 1, cl3);
+
+ if(rn == 0) sys_line(videobuffer, x, y + 1, x, y + 1, cl2);
+ if(rn == 2) sys_line(videobuffer, x, y, x, y, cl2);
+
+ orn = rn;
+
+ if(spellinfo[i].damagewho == 0) {
+ for(int e = 1; e <= lastnpc; e++) {
+
+ xdif = (x + 16) - (npcinfo[e].x + 12);
+ 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) game_damagenpc(e, damage, 1);
+ }
+ }
+ }
+
+ // check for post damage
+ if(nposts > 0) {
+ for(int e = 0; e <= nposts - 1; e++) {
+ xdif = (xloc + 16) - (postinfo[e][0] + 8);
+ ydif = (yloc + 16) - (postinfo[e][1] + 8);
+
+ if((abs(xdif) < 16 && abs(ydif) < 16)) {
+ objmapf[curmap][(int)postinfo[e][0] / 16][(int)postinfo[e][1] / 16] = 1;
+ objmap[(int)postinfo[e][0] / 16][(int)postinfo[e][1] / 16] = -1;
+
+ rcSrc.x = postinfo[e][0] / 2;
+ rcSrc.y = postinfo[e][1] / 2;
+ rcSrc.w = 8;
+ rcSrc.h = 8;
+
+ SDL_FillRect(clipbg2, &rcSrc, 0);
+
+ game_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 = y - 1;
+ if(orn == 2) y = y + 1;
+
+ sys_line(videobuffer,x, y - 1, x, y + 2, cl1);
+ sys_line(videobuffer,x, y, x, y + 1, cl3);
+
+ if(rn == 0) sys_line(videobuffer, x, y + 1, x, y + 1, cl2);
+ if(rn == 2) sys_line(videobuffer, x, y, x, y, cl2);
+
+ orn = rn;
+
+ if(spellinfo[i].damagewho == 0) {
+ for(int e = 1; e <= lastnpc; e++) {
+
+ xdif = (x + 16) - (npcinfo[e].x + 12);
+ 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) game_damagenpc(e, damage, 1);
+ }
+ }
+ }
+
+ // check for post damage
+ if(nposts > 0) {
+ for(int e = 0; e <= nposts - 1; e++) {
+ xdif = (xloc + 16) - (postinfo[e][0] + 8);
+ ydif = (yloc + 16) - (postinfo[e][1] + 8);
+
+ if((abs(xdif) < 16 && abs(ydif) < 16)) {
+ objmapf[curmap][(int)postinfo[e][0] / 16][(int)postinfo[e][1] / 16] = 1;
+ objmap[(int)postinfo[e][0] / 16][(int)postinfo[e][1] / 16] = -1;
+
+ rcSrc.x = postinfo[e][0] / 2;
+ rcSrc.y = postinfo[e][1] / 2;
+ rcSrc.w = 8;
+ rcSrc.h = 8;
+
+ SDL_FillRect(clipbg2, &rcSrc, 0);
+
+ game_addFloatIcon(99, postinfo[e][0], postinfo[e][1]);
+ }
+ }
+ }
+ }
+
+ int x = apx;
+ orn = 0;
+ for(int y = apy; y <= 239; y++) {
+ int rn = (int)(RND() * 3);
+
+ if(orn == 0) x = x - 1;
+ if(orn == 2) x = x + 1;
+
+ sys_line(videobuffer,x - 1, y, x + 2, y, cl1);
+ sys_line(videobuffer,x, y, x + 1, y, cl3);
+
+ if(rn == 0) sys_line(videobuffer, x + 1, y, x + 1, y, cl2);
+ if(rn == 2) sys_line(videobuffer, x, y, x, y, cl2);
+
+ orn = rn;
+
+ if(spellinfo[i].damagewho == 0) {
+ for(int e = 1; e <= lastnpc; e++) {
+ xdif = (x + 16) - (npcinfo[e].x + 12);
+ 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) game_damagenpc(e, damage, 1);
+ }
+ }
+ }
+
+ // check for post damage
+ if(nposts > 0) {
+ for(int e = 0; e <= nposts - 1; e++) {
+ xdif = (xloc + 16) - (postinfo[e][0] + 8);
+ ydif = (yloc + 16) - (postinfo[e][1] + 8);
+
+ if((abs(xdif) < 16 && abs(ydif) < 16)) {
+ objmapf[curmap][(int)postinfo[e][0] / 16][(int)postinfo[e][1] / 16] = 1;
+ objmap[(int)postinfo[e][0] / 16][(int)postinfo[e][1] / 16] = -1;
+
+ rcSrc.x = postinfo[e][0] / 2;
+ rcSrc.y = postinfo[e][1] / 2;
+ rcSrc.w = 8;
+ rcSrc.h = 8;
+
+ SDL_FillRect(clipbg2, &rcSrc, 0);
+
+ game_addFloatIcon(99, postinfo[e][0], postinfo[e][1]);
+ }
+ }
+ }
+ }
+
+ x = apx;
+ orn = 0;
+ for(int y = apy; y >= 0; y--) {
+ int rn = (int)(RND() * 3);
+
+ if(orn == 0) x = x - 1;
+ if(orn == 2) x = x + 1;
+
+ sys_line(videobuffer,x - 1, y, x + 2, y, cl1);
+ sys_line(videobuffer,x, y, x + 1, y, cl3);
+
+ if(rn == 0) sys_line(videobuffer, x + 1, y, x + 1, y, cl2);
+ if(rn == 2) sys_line(videobuffer, x, y, x, y, cl2);
+
+ orn = rn;
+
+ if(spellinfo[i].damagewho == 0) {
+ for(int e = 1; e <= lastnpc; e++) {
+ xdif = (x + 16) - (npcinfo[e].x + 12);
+ 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) game_damagenpc(e, damage, 1);
+ }
+ }
+ }
+
+ // check for post damage
+ if(nposts > 0) {
+ for(int e = 0; e <= nposts - 1; e++) {
+ xdif = (xloc + 16) - (postinfo[e][0] + 8);
+ ydif = (yloc + 16) - (postinfo[e][1] + 8);
+
+ if((abs(xdif) < 16 && abs(ydif) < 16)) {
+ objmapf[curmap][(int)postinfo[e][0] / 16][(int)postinfo[e][1] / 16] = 1;
+ objmap[(int)postinfo[e][0] / 16][(int)postinfo[e][1] / 16] = -1;
+
+ rcSrc.x = postinfo[e][0] / 2;
+ rcSrc.y = postinfo[e][1] / 2;
+ rcSrc.w = 8;
+ rcSrc.h = 8;
+
+ SDL_FillRect(clipbg2, &rcSrc, 0);
+
+ game_addFloatIcon(99, postinfo[e][0], postinfo[e][1]);
+ }
+ }
+ }
+ }
+ }
+
+ spellinfo[i].frame -= 0.5 * fpsr;
+ if(spellinfo[i].frame < 0) {
+ spellinfo[i].frame = 0;
+ forcepause = 0;
+ }
+ }
+
+ // wizard 1 lightning
+ if(spellnum == 9) {
+
+ cl1 = SDL_MapRGB(videobuffer->format, 0, 32, 204);
+ cl2 = SDL_MapRGB(videobuffer->format, 142, 173, 191);
+ cl3 = SDL_MapRGB(videobuffer->format, 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) {
+ float xdif, ydif;
+ int rn = (int)(RND() * 3);
+
+ if(orn == 0) x = x - 1;
+ if(orn == 2) x = x + 1;
+
+ sys_line(videobuffer,x - 1, y, x + 2, y, cl1);
+ sys_line(videobuffer,x, y, x + 1, y, cl3);
+
+ if(rn == 0) sys_line(videobuffer, x + 1, y, x + 1, y, cl2);
+ if(rn == 2) sys_line(videobuffer, x, y, x, y, cl2);
+
+ orn = rn;
+
+ if(spellinfo[i].damagewho == 1) {
+
+ xdif = (x + 8) - (player.px + 12);
+ 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 == 12) {
+ if(damage < 50) damage = 40 + (int)(RND() * 40);
+ }
+
+ if(player.hp > 0) game_damageplayer(damage);
+ }
+ }
+ }
+ }
+
+ spellinfo[i].frame -= 0.5 * fpsr;
+ if(spellinfo[i].frame < 0) {
+ spellinfo[i].frame = 0;
+
+ npcinfo[spellinfo[i].npc].attacking = 0;
+ npcinfo[spellinfo[i].npc].attacknext = ticks + npcinfo[spellinfo[i].npc].attackdelay;
+ }
+ }
+ }
+ }
+}
+
+
+
+void game_updspellsunder()
+{
+
+ unsigned int dq, *temp;
+
+ if(forcepause == 1) return;
+
+ for(int i = 0; i < MAXSPELL; 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.x = fr * 48;
+ rcSrc.y = 96;
+ rcSrc.w = 48;
+ rcSrc.h = 48;
+
+ rcDest.x = spellinfo[i].enemyx - 12;
+ rcDest.y = spellinfo[i].enemyy - 8;
+
+ int f = 160;
+ if(fra < 8) f = 160 * fra / 8;
+ if(fra > 24) f = 160 * (1 - (fra - 24) / 8);
+
+ SDL_SetAlpha(spellimg, SDL_SRCALPHA, f);
+ SDL_BlitSurface(spellimg, &rcSrc, videobuffer, &rcDest);
+ SDL_SetAlpha(spellimg, SDL_SRCALPHA, 255);
+
+ spellinfo[i].frame = spellinfo[i].frame - 0.2 * fpsr;
+ if(spellinfo[i].frame < 0) spellinfo[i].frame = 0;
+
+
+ for(int f = 1; f <= lastnpc; f++) {
+ int xdif = spellinfo[i].enemyx - npcinfo[f].x;
+ int ydif = spellinfo[i].enemyy - npcinfo[f].y;
+
+ float dist = sqrt(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);
+ temp = clipbg->pixels + sy * clipbg->pitch + sx * clipbg->format->BytesPerPixel;
+ dq = *temp;
+
+ // SDL_UnLockSurface clipbg
+
+ 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 = clipbg->pixels + sy * clipbg->pitch + sx * clipbg->format->BytesPerPixel;
+ dq = *temp;
+
+ if(dq == 0) xpass = 1;
+
+
+ sx = (npcinfo[f].x / 2 + 6);
+ sy = (newy / 2 + 10);
+ temp = clipbg->pixels + sy * clipbg->pitch + sx * clipbg->format->BytesPerPixel;
+ 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) {
+ SDL_SetAlpha(spellimg, SDL_SRCALPHA, 192 * sin(3.14159 * x / 32) * s / 8);
+
+ float an = 360 / 5 * f + x / 32 * 180;
+
+ rcSrc.x = 16 * (int)(RND() * 2);
+ rcSrc.y = 80;
+ rcSrc.w = 16;
+ rcSrc.h = 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.x = (int)xloc;
+ rcDest.y = (int)yloc;
+
+ if(xloc > -1 && xloc < 304 && yloc > -1 && yloc < 224) {
+ SDL_BlitSurface(spellimg, &rcSrc, videobuffer, &rcDest);
+
+ int sx = (xloc / 2 + 4);
+ int sy = (yloc / 2 + 8);
+ temp = clipbg->pixels + sy * clipbg->pitch + sx * clipbg->format->BytesPerPixel;
+ 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 == 5) damage = -damage;
+ if(npcinfo[e].spriteset == 11) damage = -damage;
+ if(npcinfo[e].hp > 0 && npcinfo[e].pause < ticks) {
+ game_damagenpc(e, damage, 1);
+ if(menabled == 1 && config.effects == 1) {
+ int snd = Mix_PlayChannel(-1, sfx[sndfire], 0);
+ Mix_Volume(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) {
+ game_damageplayer(damage);
+
+ if(menabled == 1 && config.effects == 1) {
+ int snd = Mix_PlayChannel(-1, sfx[sndfire], 0);
+ Mix_Volume(snd, config.effectsvol);
+ }
+ }
+ }
+ }
+
+ // check for post damage
+ if(nposts > 0) {
+ for(int e = 0; e <= nposts - 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)) {
+ objmapf[curmap][(int)postinfo[e][0] / 16][(int)postinfo[e][1] / 16] = 1;
+ objmap[(int)postinfo[e][0] / 16][(int)postinfo[e][1] / 16] = -1;
+
+ rcSrc.x = postinfo[e][0] / 2;
+ rcSrc.y = postinfo[e][1] / 2;
+ rcSrc.w = 8;
+ rcSrc.h = 8;
+
+ SDL_FillRect(clipbg2, &rcSrc, 0);
+
+ if(menabled == 1 && config.effects == 1) {
+ int snd = Mix_PlayChannel(-1, sfx[sndfire], 0);
+ Mix_Volume(snd, config.effectsvol);
+ }
+
+ game_addFloatIcon(99, postinfo[e][0], postinfo[e][1]);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ SDL_SetAlpha(spellimg, SDL_SRCALPHA, 255);
+
+ 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;
+
+ if(alpha < 0) alpha = 0;
+ if(alpha > 255) alpha = 255;
+
+ SDL_SetAlpha(spellimg, SDL_SRCALPHA, alpha);
+
+ rcSrc.x = 16 * (int)(RND() * 2);
+ rcSrc.y = 80;
+ rcSrc.w = 16;
+ rcSrc.h = 16;
+
+ float xloc = spellinfo[i].homex + xspan / 7 * f;
+ float yloc = spellinfo[i].homey + yspan / 7 * f - yy;
+
+ rcDest.x = xloc;
+ rcDest.y = yloc;
+
+ if(xloc > -16 && xloc < 320 && yloc > -16 && yloc < 240) {
+ SDL_BlitSurface(spellimg, &rcSrc, videobuffer, &rcDest);
+
+ 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) {
+ game_damageplayer(damage);
+ if(menabled == 1 && config.effects == 1) {
+ int snd = Mix_PlayChannel(-1, sfx[sndfire], 0);
+ Mix_Volume(snd, config.effectsvol);
+ }
+ }
+
+ }
+ }
+
+ }
+
+ }
+
+ SDL_SetAlpha(spellimg, SDL_SRCALPHA, 255);
+ spellinfo[i].frame = spellinfo[i].frame - 0.5 * fpsr;
+ if(spellinfo[i].frame < 0) spellinfo[i].frame = 0;
+
+ if(spellinfo[i].frame == 0) {
+ npcinfo[spellinfo[i].npc].attacking = 0;
+ npcinfo[spellinfo[i].npc].attacknext = ticks + npcinfo[spellinfo[i].npc].attackdelay;
+ }
+ }
+ }
+ }
+}
+
+void sys_initpaths()
+{
+#ifdef __unix__
+ char line[256];
+ char *home = getenv("HOME");
+ if(!home) return;
+
+ sprintf(line, "%s/.griffon", home);
+ mkdir(line, 0777);
+
+ strcpy(config_ini, line);
+ strcat(config_ini, "/config.ini");
+
+ strcpy(player_sav, line);
+ strcat(player_sav, "/player%i.sav");
+#endif
+}
+
+void sys_initialize()
+{
+ int result;
+
+ sys_initpaths();
+
+ // init char *floatstri[MAXFLOAT]
+ for(int i = 0; i < MAXFLOAT; i++)
+ floatstri[i] = malloc(64); // 64 bytes each string (should be enough)
+
+ // set default values
+ config.scr_width = 320;
+ config.scr_height = 240;
+ config.scr_bpp = 32;
+ config.hwaccel = 0;
+ config.hwsurface = SDL_SWSURFACE;
+ config.fullscreen = 0;
+ config.music = 1;
+ config.effects = 1;
+ config.musicvol = 127;
+ config.effectsvol = 127;
+
+ config_load(&config);
+
+ printf("SCR_WIDTH: %i\n", config.scr_width);
+ printf("SCR_HEIGHT: %i\n", config.scr_height);
+ printf("SCR_BITS: %i\n", config.scr_bpp);
+
+ fullscreen = config.fullscreen | config.hwaccel | config.hwsurface;
+
+ result = SDL_Init(SDL_INIT_EVERYTHING);
+ if(result) {
+ printf("Failed to init SDL\n");
+ exit(1);
+ }
+
+ atexit(SDL_Quit);
+
+ video = SDL_SetVideoMode(config.scr_width, config.scr_height, config.scr_bpp, fullscreen); // SDL_FULLSCREEN
+ if(!video) {
+ printf("Failed to init Video\n");
+ exit(1);
+ }
+
+
+ SDL_WM_SetCaption("The Griffon Legend", NULL);
+
+ SDL_ShowCursor(SDL_DISABLE);
+
+ videobuffer = SDL_CreateRGBSurface(config.hwsurface, 320, 240, config.scr_bpp, video->format->Rmask, video->format->Gmask, video->format->Bmask, video->format->Amask);
+ videobuffer2 = SDL_CreateRGBSurface(config.hwsurface, 320, 240, config.scr_bpp, video->format->Rmask, video->format->Gmask, video->format->Bmask, video->format->Amask);
+ videobuffer3 = SDL_CreateRGBSurface(config.hwsurface, 320, 240, config.scr_bpp, video->format->Rmask, video->format->Gmask, video->format->Bmask, video->format->Amask);
+ mapbg = SDL_CreateRGBSurface(config.hwsurface, 320, 240, config.scr_bpp, video->format->Rmask, video->format->Gmask, video->format->Bmask, video->format->Amask);
+ clipbg = SDL_CreateRGBSurface(SDL_SWSURFACE, 320, 240, config.scr_bpp, video->format->Rmask, video->format->Gmask, video->format->Bmask, video->format->Amask);
+ clipbg2 = SDL_DisplayFormat(video);
+
+ for(int i = 0; i <= 3; i++) {
+ char name[128];
+
+ sprintf(name, "art/map%i.bmp", i + 1);
+ mapimg[i] = SDL_DisplayFormat(video);
+ mapimg[i] = IMG_Load(name);
+ SDL_SetColorKey(mapimg[i], SDL_SRCCOLORKEY, SDL_MapRGB(mapimg[i]->format, 255, 0, 255));
+ }
+
+ cloudimg = IMG_Load("art/clouds.bmp");
+ SDL_SetColorKey(cloudimg, SDL_SRCCOLORKEY, SDL_MapRGB(cloudimg->format, 255, 0, 255));
+ SDL_SetAlpha(cloudimg, 0 | SDL_SRCALPHA, 96);
+
+
+ saveloadimg = IMG_Load("art/saveloadnew.bmp");
+ SDL_SetColorKey(saveloadimg, SDL_SRCCOLORKEY, SDL_MapRGB(saveloadimg->format, 255, 0, 255));
+ SDL_SetAlpha(saveloadimg, 0 | SDL_SRCALPHA, 160);
+
+ titleimg = IMG_Load("art/titleb.bmp");
+ titleimg2 = IMG_Load("art/titlea.bmp");
+ SDL_SetColorKey(titleimg2, SDL_SRCCOLORKEY, SDL_MapRGB(titleimg2->format, 255, 0, 255));
+ //SDL_SetAlpha(titleimg2, 0 | SDL_SRCALPHA, 204);
+
+ inventoryimg = IMG_Load("art/inventory.bmp");
+ SDL_SetColorKey(inventoryimg, SDL_SRCCOLORKEY, SDL_MapRGB(inventoryimg->format, 255, 0, 255));
+
+ logosimg = SDL_DisplayFormat(video);
+ theendimg = SDL_DisplayFormat(video);
+ logosimg = IMG_Load("art/logos.bmp");
+ theendimg = IMG_Load("art/theend.bmp");
+
+
+ sys_LoadTiles();
+ sys_LoadTriggers();
+ sys_LoadObjectDB();
+ sys_LoadAnims();
+ sys_LoadFont();
+ sys_LoadItemImgs();
+
+ fpsr = 1;
+ nextticks = ticks + 1000;
+
+ for(int i = 0; i <= 15; i++) {
+ playerattackofs[0][i][0] = 0; // -1// -(i + 1)
+ playerattackofs[0][i][1] = -sin(3.14159 * 2 * (i + 1) / 16) * 2 - 1;
+
+ playerattackofs[1][i][0] = 0; // i + 1
+ playerattackofs[1][i][1] = -sin(3.14159 * 2 * (i + 1) / 16) * 2 + 1;
+
+ playerattackofs[2][i][0] = -1; // -(i + 1)
+ playerattackofs[2][i][1] = -sin(3.14159 * 2 * (i + 1) / 16) * 2;
+
+ playerattackofs[3][i][0] = 1; // i + 1
+ playerattackofs[3][i][1] = -sin(3.14159 * 2 * (i + 1) / 16) * 2;
+ }
+
+ sys_setupAudio();
+}
+
+void sys_line(SDL_Surface *buffer, int x1, int y1, int x2, int y2, int col)
+{
+ unsigned int *temp;
+
+ SDL_LockSurface(buffer);
+
+ int xdif = x2 - x1;
+ int ydif = y2 - y1;
+
+ if(xdif == 0) {
+ for(int y = y1; y <= y2; y++) {
+ temp = buffer->pixels + y * buffer->pitch + x1 * buffer->format->BytesPerPixel;
+ *temp = col;
+ }
+ }
+
+ if(ydif == 0) {
+ for(int x = x1; x <= x2; x++) {
+ temp = buffer->pixels + y1 * buffer->pitch + x * buffer->format->BytesPerPixel;
+ *temp = col;
+ }
+ }
+
+ SDL_UnlockSurface(buffer);
+}
+
+void sys_LoadAnims()
+{
+ spellimg = IMG_Load("art/spells.bmp");
+ SDL_SetColorKey(spellimg, SDL_SRCCOLORKEY, SDL_MapRGB(spellimg->format, 255, 0, 255));
+
+ anims[0] = IMG_Load("art/anims0.bmp");
+ SDL_SetColorKey(anims[0], SDL_SRCCOLORKEY, SDL_MapRGB(anims[0]->format, 255, 0, 255));
+
+ animsa[0] = IMG_Load("art/anims0a.bmp");
+ SDL_SetColorKey(animsa[0], SDL_SRCCOLORKEY, SDL_MapRGB(animsa[0]->format, 255, 0, 255));
+
+ anims[13] = IMG_Load("art/anims0x.bmp");
+ SDL_SetColorKey(anims[13], SDL_SRCCOLORKEY, SDL_MapRGB(anims[13]->format, 255, 0, 255));
+
+ animsa[13] = IMG_Load("art/anims0xa.bmp");
+ SDL_SetColorKey(animsa[13], SDL_SRCCOLORKEY, SDL_MapRGB(animsa[13]->format, 255, 0, 255));
+
+ anims[1] = IMG_Load("art/anims1.bmp");
+ SDL_SetColorKey(anims[1], SDL_SRCCOLORKEY, SDL_MapRGB(anims[1]->format, 255, 0, 255));
+
+ animsa[1] = IMG_Load("art/anims1a.bmp");
+ SDL_SetColorKey(animsa[1], SDL_SRCCOLORKEY, SDL_MapRGB(animsa[1]->format, 255, 0, 255));
+
+ anims[2] = IMG_Load("art/anims2.bmp");
+ SDL_SetColorKey(anims[2], SDL_SRCCOLORKEY, SDL_MapRGB(anims[2]->format, 255, 0, 255));
+
+ // huge
+ animset2[0].xofs = 8;
+ animset2[0].yofs = 7;
+ animset2[0].x = 123;
+ animset2[0].y = 0;
+ animset2[0].w = 18;
+ animset2[0].h = 16;
+ // big
+ animset2[1].xofs = 7;
+ animset2[1].yofs = 7;
+ animset2[1].x = 107;
+ animset2[1].y = 0;
+ animset2[1].w = 16;
+ animset2[1].h = 14;
+ // med
+ animset2[2].xofs = 6;
+ animset2[2].yofs = 6;
+ animset2[2].x = 93;
+ animset2[2].y = 0;
+ animset2[2].w = 14;
+ animset2[2].h = 13;
+ // small
+ animset2[3].xofs = 4;
+ animset2[3].yofs = 4;
+ animset2[3].x = 83;
+ animset2[3].y = 0;
+ animset2[3].w = 10;
+ animset2[3].h = 10;
+ // wing
+ animset2[4].xofs = 4;
+ animset2[4].yofs = 20;
+ animset2[4].x = 42;
+ animset2[4].y = 0;
+ animset2[4].w = 41;
+ animset2[4].h = 33;
+ // head
+ animset2[5].xofs = 20;
+ animset2[5].yofs = 18;
+ animset2[5].x = 0;
+ animset2[5].y = 0;
+ animset2[5].w = 42;
+ animset2[5].h = 36;
+
+ anims[9] = IMG_Load("art/anims9.bmp");
+ SDL_SetColorKey(anims[9], SDL_SRCCOLORKEY, SDL_MapRGB(anims[9]->format, 255, 0, 255));
+
+ // huge
+ animset9[0].xofs = 8;
+ animset9[0].yofs = 7;
+ animset9[0].x = 154;
+ animset9[0].y = 0;
+ animset9[0].w = 18;
+ animset9[0].h = 16;
+ // big
+ animset9[1].xofs = 7;
+ animset9[1].yofs = 7;
+ animset9[1].x = 138;
+ animset9[1].y = 0;
+ animset9[1].w = 16;
+ animset9[1].h = 14;
+ // med
+ animset9[2].xofs = 6;
+ animset9[2].yofs = 6;
+ animset9[2].x = 93 + 31;
+ animset9[2].y = 0;
+ animset9[2].w = 14;
+ animset9[2].h = 13;
+ // small
+ animset9[3].xofs = 4;
+ animset9[3].yofs = 4;
+ animset9[3].x = 83 + 31;
+ animset9[3].y = 0;
+ animset9[3].w = 10;
+ animset9[3].h = 10;
+ // wing
+ animset9[4].xofs = 36;
+ animset9[4].yofs = 20;
+ animset9[4].x = 42;
+ animset9[4].y = 0;
+ animset9[4].w = 72;
+ animset9[4].h = 33;
+ // head
+ animset9[5].xofs = 20;
+ animset9[5].yofs = 18;
+ animset9[5].x = 0;
+ animset9[5].y = 0;
+ animset9[5].w = 42;
+ animset9[5].h = 36;
+
+ anims[3] = IMG_Load("art/anims3.bmp");
+ SDL_SetColorKey(anims[3], SDL_SRCCOLORKEY, SDL_MapRGB(anims[3]->format, 255, 0, 255));
+
+ anims[4] = IMG_Load("art/anims4.bmp");
+ SDL_SetColorKey(anims[4], SDL_SRCCOLORKEY, SDL_MapRGB(anims[4]->format, 255, 0, 255));
+
+ anims[5] = IMG_Load("art/anims5.bmp");
+ SDL_SetColorKey(anims[5], SDL_SRCCOLORKEY, SDL_MapRGB(anims[5]->format, 255, 0, 255));
+
+ anims[6] = IMG_Load("art/anims6.bmp");
+ SDL_SetColorKey(anims[6], SDL_SRCCOLORKEY, SDL_MapRGB(anims[6]->format, 255, 0, 255));
+
+ anims[7] = IMG_Load("art/anims7.bmp");
+ SDL_SetColorKey(anims[7], SDL_SRCCOLORKEY, SDL_MapRGB(anims[7]->format, 255, 0, 255));
+
+ anims[8] = IMG_Load("art/anims8.bmp");
+ SDL_SetColorKey(anims[8], SDL_SRCCOLORKEY, SDL_MapRGB(anims[8]->format, 255, 0, 255));
+
+ anims[10] = IMG_Load("art/anims10.bmp");
+ SDL_SetColorKey(anims[10], SDL_SRCCOLORKEY, SDL_MapRGB(anims[10]->format, 255, 0, 255));
+
+ animsa[10] = IMG_Load("art/anims10a.bmp");
+ SDL_SetColorKey(animsa[10], SDL_SRCCOLORKEY, SDL_MapRGB(animsa[10]->format, 255, 0, 255));
+
+ anims[11] = IMG_Load("art/anims11.bmp");
+ SDL_SetColorKey(anims[11], SDL_SRCCOLORKEY, SDL_MapRGB(anims[11]->format, 255, 0, 255));
+
+ animsa[11] = IMG_Load("art/anims11a.bmp");
+ SDL_SetColorKey(animsa[11], SDL_SRCCOLORKEY, SDL_MapRGB(animsa[11]->format, 255, 0, 255));
+
+ anims[12] = IMG_Load("art/anims12.bmp");
+ SDL_SetColorKey(anims[12], SDL_SRCCOLORKEY, SDL_MapRGB(anims[12]->format, 255, 0, 255));
+}
+
+void sys_LoadItemImgs()
+{
+ SDL_Surface *temp;
+
+ temp = IMG_Load("art/icons.bmp");
+
+ for(int i = 0; i <= 20; i++) {
+ itemimg[i] = SDL_CreateRGBSurface(SDL_SWSURFACE, 16, 16, config.scr_bpp, video->format->Rmask, video->format->Gmask, video->format->Bmask, video->format->Amask);
+ SDL_SetColorKey(itemimg[i], SDL_SRCCOLORKEY, SDL_MapRGB(itemimg[i]->format, 255, 0, 255));
+
+ rcSrc.x = i * 16;
+ rcSrc.y = 0;
+ rcSrc.w = 16;
+ rcSrc.h = 16;
+
+ SDL_BlitSurface(temp, &rcSrc, itemimg[i], NULL);
+ }
+
+ SDL_FreeSurface(temp);
+}
+
+void sys_LoadFont()
+{
+ SDL_Surface *font;
+
+ font = IMG_Load("art/font.bmp");
+
+ for(int i = 32; i <= 255; i++)
+ for(int f = 0; f <= 4; f++) {
+ int i2 = i - 32;
+
+ fontchr[i2][f] = SDL_CreateRGBSurface(SDL_SWSURFACE, 8, 8, config.scr_bpp, video->format->Rmask, video->format->Gmask, video->format->Bmask, video->format->Amask);
+ SDL_SetColorKey(fontchr[i2][f], SDL_SRCCOLORKEY, SDL_MapRGB(fontchr[i2][f]->format, 255, 0, 255));
+
+ int col = i2 % 40;
+
+ int row = (i2 - col) / 40;
+
+ rcSrc.x = col * 8;
+ rcSrc.y = row * 8 + f * 48;
+ rcSrc.w = 8;
+ rcSrc.h = 8;
+
+ rcDest.x = 0;
+ rcDest.y = 0;
+ SDL_BlitSurface(font, &rcSrc, fontchr[i2][f], &rcDest);
+ }
+
+ SDL_FreeSurface(font);
+}
+
+void sys_LoadTiles()
+{
+ tiles[0] = IMG_Load("art/tx.bmp");
+ tiles[1] = IMG_Load("art/tx1.bmp");
+ tiles[2] = IMG_Load("art/tx2.bmp");
+ tiles[3] = IMG_Load("art/tx3.bmp");
+
+ for(int i = 0; i <= 3; i++)
+ SDL_SetColorKey(tiles[i], SDL_SRCCOLORKEY, SDL_MapRGB(tiles[i]->format, 255, 0, 255));
+
+ windowimg = IMG_Load("art/window.bmp");
+ SDL_SetColorKey(windowimg, SDL_SRCCOLORKEY, SDL_MapRGB(windowimg->format, 255, 0, 255));
+}
+
+void sys_LoadTriggers()
+{
+ FILE *fp;
+ char line[512];
+
+ fp = fopen("data/triggers.dat", "r");
+
+ for(int i = 0; i <= 9999; i++)
+ for(int a = 0; a <= 8; a++) {
+ fgets(line, sizeof(line), fp);
+ sscanf(line, "%i", &triggers[i][a]);
+ }
+
+ fclose(fp);
+}
+
+void sys_LoadObjectDB()
+{
+ FILE *fp;
+ char line[512];
+
+ fp = fopen("objectdb.dat", "r");
+
+ for(int a = 0; a <= 32; a++) {
+ for(int b = 0; b <= 5; b++) {
+ fgets(line, sizeof(line), fp);
+ sscanf(line, "%i", &objectinfo[a][b]);
+ }
+
+ for(int b = 0; b <= 8; b++) {
+ for(int c = 0; c <= 2; c++) {
+ for(int d = 0; d <= 2; d++) {
+ for(int e = 0; e <= 1; e++) {
+ fgets(line, sizeof(line), fp);
+ sscanf(line, "%i", &objecttile[a][b][c][d][e]);
+ }
+ }
+ }
+ }
+ }
+
+ fclose(fp);
+}
+
+void sys_print(SDL_Surface *buffer, char *stri, int xloc, int yloc, int col)
+{
+ int l = strlen(stri);
+
+ for(int i = 0; i < l; i++) {
+ rcDest.x = xloc + i * 8;
+ rcDest.y = yloc;
+
+ SDL_BlitSurface(fontchr[stri[i] - 32][col], NULL, buffer, &rcDest);
+ }
+}
+
+void sys_progress(int w, int wm)
+{
+ long ccc;
+
+ ccc = SDL_MapRGB(videobuffer->format, 0, 255, 0);
+
+ rcDest.w = w * 74 / wm;
+ SDL_FillRect(videobuffer, &rcDest, ccc);
+ SDL_BLITVIDEO(videobuffer, NULL, video, NULL);
+ SDL_Flip(video);
+ SDL_PumpEvents();
+}
+
+void sys_setupAudio()
+{
+ SDL_Surface *loadimg;
+
+ menabled = 1;
+
+ if((Mix_Init(MIX_INIT_OGG) & MIX_INIT_OGG) != MIX_INIT_OGG) {
+ printf("Failed to init OGG support\n");
+ exit(1);
+ }
+
+ Mix_OpenAudio(22050, MIX_DEFAULT_FORMAT, 2, 1024);
+
+ atexit(Mix_Quit);
+ atexit(Mix_CloseAudio);
+
+ char *stri = "Loading...";
+ sys_print(videobuffer, stri, 160 - 4 * strlen(stri), 116, 0);
+
+ loadimg = IMG_Load("art/load.bmp");
+ SDL_SetColorKey(loadimg, SDL_SRCCOLORKEY, SDL_MapRGB(loadimg->format, 255, 0, 255));
+
+ rcSrc.x = 0;
+ rcSrc.y = 0;
+ rcSrc.w = 88;
+ rcSrc.h = 32;
+
+ rcDest.x = 160 - 44;
+ rcDest.y = 116 + 12;
+
+ SDL_SetAlpha(loadimg, 0 | SDL_SRCALPHA, 160); // 128
+ SDL_BlitSurface(loadimg, &rcSrc, videobuffer, &rcDest);
+ SDL_SetAlpha(loadimg, 0 | SDL_SRCALPHA, 255);
+
+ SDL_BLITVIDEO(videobuffer, NULL, video, NULL);
+ SDL_Flip(video);
+
+ rcDest.x = 160 - 44 + 7;
+ rcDest.y = 116 + 12 + 12;
+ rcDest.h = 8;
+
+ if(menabled == 1) {
+ mboss = Mix_LoadWAV("music/boss.ogg");
+ sys_progress(1, 21);
+ mgardens = Mix_LoadWAV("music/gardens.ogg");
+ sys_progress(2, 21);
+ mgardens2 = Mix_LoadWAV("music/gardens2.ogg");
+ sys_progress(3, 21);
+ mgardens3 = Mix_LoadWAV("music/gardens3.ogg");
+ sys_progress(4, 21);
+ mgardens4 = Mix_LoadWAV("music/gardens4.ogg");
+ sys_progress(5, 21);
+ mendofgame = Mix_LoadWAV("music/endofgame.ogg");
+ sys_progress(6, 21);
+ mmenu = Mix_LoadWAV("music/menu.ogg");
+ sys_progress(7, 21);
+
+ sfx[0] = Mix_LoadWAV("sfx/bite.ogg");
+ sys_progress(8, 21);
+ sfx[1] = Mix_LoadWAV("sfx/crystal.ogg");
+ sys_progress(9, 21);
+ sfx[2] = Mix_LoadWAV("sfx/door.ogg");
+ sys_progress(10, 21);
+ sfx[3] = Mix_LoadWAV("sfx/enemyhit.ogg");
+ sys_progress(11, 21);
+ sfx[4] = Mix_LoadWAV("sfx/ice.ogg");
+ sys_progress(12, 21);
+ sfx[5] = Mix_LoadWAV("sfx/lever.ogg");
+ sys_progress(13, 21);
+ sfx[6] = Mix_LoadWAV("sfx/lightning.ogg");
+ sys_progress(14, 21);
+ sfx[7] = Mix_LoadWAV("sfx/metalhit.ogg");
+ sys_progress(15, 21);
+ sfx[8] = Mix_LoadWAV("sfx/powerup.ogg");
+ sys_progress(16, 21);
+ sfx[9] = Mix_LoadWAV("sfx/rocks.ogg");
+ sys_progress(17, 21);
+ sfx[10] = Mix_LoadWAV("sfx/swordhit.ogg");
+ sys_progress(18, 21);
+ sfx[11] = Mix_LoadWAV("sfx/throw.ogg");
+ sys_progress(19, 21);
+ sfx[12] = Mix_LoadWAV("sfx/chest.ogg");
+ sys_progress(20, 21);
+ sfx[13] = Mix_LoadWAV("sfx/fire.ogg");
+ sys_progress(21, 21);
+ sfx[14] = Mix_LoadWAV("sfx/beep.ogg");
+ }
+}
+
+void sys_update()
+{
+ unsigned int *temp, bgc;
+ int pa, sx, sy;
+ float opx, opy, spd;
+
+ SDL_Flip(video);
+ SDL_PumpEvents();
+
+ tickspassed = ticks;
+ ticks = SDL_GetTicks();
+
+ tickspassed = ticks - tickspassed;
+ fpsr = (float)tickspassed / 24.0;
+
+ fp++;
+ if(ticks > nextticks) {
+ nextticks = ticks + 1000;
+ fps = fp;
+ fp = 0;
+ secsingame = secsingame + 1;
+ }
+
+ SDL_LockSurface(clipbg);
+
+ if(attacking == 1) {
+ player.attackframe += player.attackspd * fpsr;
+ if(player.attackframe >= 16) {
+ attacking = 0;
+ player.attackframe = 0;
+ player.walkframe = 0;
+ }
+
+ pa = (int)(player.attackframe);
+
+ for(int i = 0; i <= pa; i++) {
+ if(playerattackofs[player.walkdir][i][2] == 0) {
+ playerattackofs[player.walkdir][i][2] = 1;
+
+ opx = player.px;
+ opy = player.py;
+
+ player.px = player.px + playerattackofs[player.walkdir][i][0];
+ player.py = player.py + playerattackofs[player.walkdir][i][1];
+
+ sx = (int)(player.px / 2 + 6);
+ sy = (int)(player.py / 2 + 10);
+ temp = clipbg->pixels + sy * clipbg->pitch + sx * clipbg->format->BytesPerPixel;
+ bgc = *temp;
+ if(bgc > 0) {
+ player.px = opx;
+ player.py = opy;
+ }
+ }
+ }
+
+ player.opx = player.px;
+ player.opy = player.py;
+
+ game_checkhit();
+ }
+
+ for(int i = 0; i < MAXFLOAT; i++) {
+ if(floattext[i][0] > 0) {
+ spd = 0.5 * fpsr;
+ floattext[i][0] = floattext[i][0] - spd;
+ floattext[i][2] = floattext[i][2] - spd;
+ if(floattext[i][0] < 0) floattext[i][0] = 0;
+ }
+
+ if(floaticon[i][0] > 0) {
+ spd = 0.5 * fpsr;
+ floaticon[i][0] = floaticon[i][0] - spd;
+ floaticon[i][2] = floaticon[i][2] - spd;
+ if(floaticon[i][0] < 0) floaticon[i][0] = 0;
+ }
+ }
+
+ if(player.level == player.maxlevel) player.exp = 0;
+
+ if(player.exp >= player.nextlevel) {
+ player.level = player.level + 1;
+ game_addFloatText("LEVEL UP!", player.px + 16 - 36, player.py + 16, 3);
+ player.exp = player.exp - player.nextlevel;
+ player.nextlevel = player.nextlevel * 3 / 2; // 1.5
+ player.maxhp = player.maxhp + player.level * 3;
+ if(player.maxhp > 999) player.maxhp = 999;
+ player.hp = player.maxhp;
+
+ player.sworddamage = player.level * 14 / 10;
+ player.spelldamage = player.level * 13 / 10;
+
+ if(menabled == 1 && config.effects == 1) {
+ int snd = Mix_PlayChannel(-1, sfx[sndpowerup], 0);
+ Mix_Volume(snd, config.effectsvol);
+ }
+ }
+
+ SDL_UnlockSurface(clipbg);
+ SDL_BlitSurface(clipbg2, NULL, clipbg, NULL);
+
+ SDL_Rect rc;
+
+ rc.x = player.px - 2;
+ rc.y = player.py - 2;
+ rc.w = 5;
+ rc.h = 5;
+
+ SDL_FillRect(clipbg, &rc, 1000);
+
+ if(forcepause == 0) {
+ for(int i = 0; i < 5; i++) {
+ if(player.foundspell[i] == 1) player.spellcharge[i] += 1 * player.level * 0.01 * fpsr;
+ if(player.spellcharge[i] > 100) player.spellcharge[i] = 100;
+ }
+
+ if(player.foundspell[0]) {
+ player.spellstrength += 3 * player.level * .01 * fpsr;
+ }
+
+ player.attackstrength += (30 + 3 * (float)player.level) / 50 * fpsr;
+ }
+
+ if(player.attackstrength > 100) player.attackstrength = 100;
+
+ if(player.spellstrength > 100) player.spellstrength = 100;
+
+ itemyloc += 0.75 * fpsr;
+ while(itemyloc >= 16) itemyloc -= 16;
+
+ if(player.hp <= 0) game_theend();
+
+ if(roomlock == 1) {
+ roomlock = 0;
+ for(int i = 1; i <= lastnpc; i++)
+ if(npcinfo[i].hp > 0) roomlock = 1;
+ }
+
+ clouddeg += 0.1 * fpsr;
+ while(clouddeg >= 360) clouddeg = clouddeg - 360;
+
+ player.hpflash = player.hpflash + 0.1 * fpsr;
+ if(player.hpflash >=2) {
+ player.hpflash = 0;
+ player.hpflashb = player.hpflashb + 1;
+ if(player.hpflashb == 2) player.hpflashb = 0;
+ if(menabled == 1 && config.effects == 1 && player.hpflashb == 0 && player.hp < player.maxhp / 4) {
+ int snd = Mix_PlayChannel(-1, sfx[sndbeep], 0);
+ Mix_Volume(snd, config.effectsvol);
+ }
+ }
+
+ // cloudson = 0
+
+ if(itemselon == 1) player.itemselshade = player.itemselshade + 2 * fpsr;
+ if(player.itemselshade > 24) player.itemselshade = 24;
+
+ for(int i = 0; i <= 4; i++)
+ if(player.inventory[i] > 9) player.inventory[i] = 9;
+}
diff --git a/engines/griffon/engine.h b/engines/griffon/engine.h
new file mode 100644
index 0000000000..aec0e6ef92
--- /dev/null
+++ b/engines/griffon/engine.h
@@ -0,0 +1,254 @@
+/*
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef _GRIFFON_H_
+#define _GRIFFON_H_
+
+#define MAXNPC 32
+#define MAXFLOAT 32
+#define MAXSPELL 32
+
+// spells
+#define ice 0
+#define steel 1
+#define wood 2
+#define rock 3
+#define fire 4
+
+// inventory items
+#define INV_FLASK 0
+#define INV_DOUBLEFLASK 1
+#define INV_SHOCK 2
+#define INV_NORMALKEY 3
+#define INV_MASTERKEY 4
+
+#define sndbite 0
+#define sndcrystal 1
+#define snddoor 2
+#define sndenemyhit 3
+#define sndice 4
+#define sndlever 5
+#define sndlightning 6
+#define sndmetalhit 7
+#define sndpowerup 8
+#define sndrocks 9
+#define sndswordhit 10
+#define sndthrow 11
+#define sndchest 12
+#define sndfire 13
+#define sndbeep 14
+
+typedef struct {
+ float px;
+ float py;
+ float opx;
+ float opy;
+ int walkdir;
+ float walkframe;
+ float walkspd;
+ float attackframe;
+ float attackspd;
+
+ int hp;
+ int maxhp;
+ float hpflash;
+ int hpflashb;
+ int level;
+ int maxlevel;
+ int sword;
+ int shield;
+ int armour;
+ int foundspell[5];
+ float spellcharge[5];
+ int inventory[5];
+ float attackstrength;
+ float spellstrength;
+ int spelldamage;
+ int sworddamage;
+
+ int exp;
+ int nextlevel;
+
+ int pause;
+
+ float itemselshade;
+ int ysort;
+} PLAYERTYPE;
+
+typedef struct {
+ float x;
+ float y;
+ int parentID;
+ int isbase;
+ int sprite;
+ int bonelength; // the 'bone' that connects the body sections
+} BODYSECTIONTYPE;
+
+typedef struct {
+ float x;
+ float y;
+ int spriteset;
+ int x1; // patrol area
+ int y1;
+ int x2;
+ int y2;
+ int attitude;
+ int hp;
+
+ int maxhp;
+ int item1;
+ int item2;
+ int item3;
+ int script;
+ float frame;
+ float frame2; // end boss specific
+ int cframe;
+ int onmap; // is this npc set to be genned in the mapfile
+
+ int ticks;
+ int pause;
+ int shake;
+
+ int movementmode;
+ int walkdir;
+ float walkspd;
+ int movingdir;
+ int moving;
+
+ int attacking;
+ float attackframe;
+ int cattackframe;
+ float attackspd;
+ int attackdelay;
+ int attacknext;
+ int attackattempt;
+
+ int spelldamage;
+ int attackdamage;
+
+
+ // one wing and firehydra specific
+ BODYSECTIONTYPE bodysection[31];
+ float swayangle;
+ float swayspd;
+ float headtargetx[4];
+ float headtargety[4];
+ int castpause;
+
+ // firehydra specific
+ int attacknext2[4];
+ int attacking2[4];
+ int attackframe2[4];
+
+ // dragon2 specific
+ float floating;
+} NPCTYPE;
+
+typedef struct {
+ int spellnum;
+ float homex;
+ float homey;
+ float enemyx;
+ float enemyy;
+
+ float frame;
+
+ int damagewho; // 0 = npc, 1 = player
+
+ // for earthslide
+ float rocky[9];
+ int rockimg[9];
+ int rockdeflect[9];
+
+ float strength;
+
+ // fire
+ int legalive[5];
+
+ // spell 6 specific
+ float fireballs[7][4]; // x,y,targetx, targety
+ int nfballs;
+ int ballon[7];
+
+ int npc;
+} SPELLTYPE;
+
+typedef struct {
+ int x; // xyloc on spriteimageset
+ int y;
+ int xofs; // the actual place to paste the sprite in reference to the bodypart loc on screen
+ int yofs;
+ int w; // w/h of the sprite in the imageset
+ int h;
+} ANIMSET2TYPE;
+
+extern PLAYERTYPE player;
+extern int curmap;
+extern int scriptflag[100][10];
+extern int objmapf[1000][21][15];
+extern int roomlocks[201];
+extern int secsingame, secstart;
+
+void game_addFloatIcon(int ico, float xloc, float yloc);
+void game_addFloatText(char *stri, float xloc, float yloc, int col);
+void game_attack();
+void game_castspell(int spellnum, float homex, float homey, float enemyx, float enemyy, int damagewho);
+void game_checkhit();
+void game_checkinputs();
+void game_configmenu();
+void game_damagenpc(int npcnum, int damage, int spell);
+void game_damageplayer(int damage);
+void game_drawanims(int Layer);
+void game_drawhud();
+void game_drawnpcs(int mode);
+void game_drawover(int modx, int mody);
+void game_drawplayer();
+void game_drawview();
+void game_endofgame();
+void game_eventtext(char *stri);
+void game_handlewalking();
+void game_loadmap(int mapnum);
+void game_main();
+void game_newgame();
+void game_playgame();
+void game_processtrigger(int trignum);
+void game_saveloadnew();
+void game_showlogos();
+void game_swash();
+void game_theend();
+void game_title(int mode);
+void game_updanims();
+void game_updatey();
+void game_updmusic();
+void game_updnpcs();
+void game_updspells();
+void game_updspellsunder();
+
+void sys_initialize();
+void sys_line(SDL_Surface *buffer, int x1, int y1, int x2, int y2, int col);
+void sys_LoadAnims();
+void sys_LoadFont();
+void sys_LoadItemImgs();
+void sys_LoadTiles();
+void sys_LoadTriggers();
+void sys_print(SDL_Surface *buffer, char *stri, int xloc, int yloc, int col);
+void sys_progress(int w, int wm);
+void sys_LoadObjectDB();
+void sys_setupAudio();
+void sys_update();
+
+#endif // _GRIFFON_H_
diff --git a/engines/griffon/state.cpp b/engines/griffon/state.cpp
new file mode 100644
index 0000000000..a68132ef2b
--- /dev/null
+++ b/engines/griffon/state.cpp
@@ -0,0 +1,256 @@
+/*
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <sys/stat.h>
+
+#include <SDL/SDL.h>
+
+#include "griffon.h"
+#include "state.h"
+
+char player_sav[256] = "data/player%i.sav";
+
+#define PRINT(A,B) \
+do { \
+ char line[256]; \
+ sprintf(line, A "\n", B); \
+ fputs(line, fp); \
+} while(0)
+
+#define INPUT(A, B) \
+do { \
+ char line[256]; \
+ fgets(line, sizeof(line), fp); \
+ sscanf(line, A, B); \
+} while(0)
+
+// externs (to be removed later)
+extern PLAYERTYPE playera;
+extern int asecstart;
+
+int state_load(int slotnum)
+{
+ FILE *fp;
+ char line[256];
+
+ sprintf(line, player_sav, slotnum);
+
+ fp = fopen(line, "r");
+ if(fp) {
+ INPUT("%i", &player.level);
+
+ if(player.level > 0) {
+ INPUT("%i", &secstart);
+ INPUT("%s", line);
+
+ INPUT("%f", &player.px);
+ INPUT("%f", &player.py);
+ INPUT("%f", &player.opx);
+ INPUT("%f", &player.opy);
+ INPUT("%i", &player.walkdir);
+ INPUT("%f", &player.walkframe);
+ INPUT("%f", &player.walkspd);
+ INPUT("%f", &player.attackframe);
+ INPUT("%f", &player.attackspd);
+ INPUT("%i", &player.hp);
+ INPUT("%i", &player.maxhp);
+ INPUT("%f", &player.hpflash);
+ INPUT("%i", &player.level);
+ INPUT("%i", &player.maxlevel);
+ INPUT("%i", &player.sword);
+ INPUT("%i", &player.shield);
+ INPUT("%i", &player.armour);
+ for(int i = 0; i < 5; i++) {
+ INPUT("%i", &player.foundspell[i]);
+ INPUT("%f", &player.spellcharge[i]);
+ }
+ for(int a = 0; a < 5; a++) {
+ INPUT("%i", &player.inventory[a]);
+ }
+ INPUT("%f", &player.attackstrength);
+ INPUT("%i", &player.spelldamage);
+ INPUT("%i", &player.sworddamage);
+ INPUT("%i", &player.exp);
+ INPUT("%i", &player.nextlevel);
+ for(int a = 0; a <= 99; a++) {
+ for(int b = 0; b <= 9; b++) {
+ INPUT("%i", &scriptflag[a][b]);
+ }
+ }
+ INPUT("%i", &curmap);
+
+ for(int a = 0; a <= 999; a++) {
+ for(int b = 0; b <= 20; b++) {
+ for(int c = 0; c <= 14; c++) {
+ INPUT("%i", &objmapf[a][b][c]);
+ }
+ }
+ }
+
+ for(int a = 0; a <= 200; a++) {
+ INPUT("%i", &roomlocks[a]);
+ }
+
+ INPUT("%f", &player.spellstrength);
+
+ fclose(fp);
+
+ return 1; // success
+ }
+
+ fclose(fp);
+ }
+
+ return 0; // fail
+}
+
+/* fill PLAYERTYPE playera; */
+int state_load_player(int slotnum)
+{
+ FILE *fp;
+ char line[256];
+
+ sprintf(line, player_sav, slotnum);
+
+ playera.level = 0;
+
+ fp = fopen(line, "r");
+ if(fp) {
+ INPUT("%i", &playera.level);
+
+ if(playera.level > 0) {
+ INPUT("%i", &asecstart);
+ INPUT("%s", line);
+
+ INPUT("%f", &playera.px);
+ INPUT("%f", &playera.py);
+ INPUT("%f", &playera.opx);
+ INPUT("%f", &playera.opy);
+ INPUT("%i", &playera.walkdir);
+ INPUT("%f", &playera.walkframe);
+ INPUT("%f", &playera.walkspd);
+ INPUT("%f", &playera.attackframe);
+ INPUT("%f", &playera.attackspd);
+ INPUT("%i", &playera.hp);
+ INPUT("%i", &playera.maxhp);
+ INPUT("%f", &playera.hpflash);
+ INPUT("%i", &playera.level);
+ INPUT("%i", &playera.maxlevel);
+ INPUT("%i", &playera.sword);
+ INPUT("%i", &playera.shield);
+ INPUT("%i", &playera.armour);
+ for(int i = 0; i < 5; i++) {
+ INPUT("%i", &playera.foundspell[i]);
+ INPUT("%f", &playera.spellcharge[i]);
+ }
+ for(int a = 0; a < 5; a++) {
+ INPUT("%i", &playera.inventory[a]);
+ }
+ INPUT("%f", &playera.attackstrength);
+ INPUT("%i", &playera.spelldamage);
+ INPUT("%i", &playera.sworddamage);
+ INPUT("%i", &playera.exp);
+ INPUT("%i", &playera.nextlevel);
+
+ fclose(fp);
+
+ return 1; // success
+ }
+
+ fclose(fp);
+ }
+
+ return 0; // fail
+}
+
+int state_save(int slotnum)
+{
+ FILE *fp;
+ char line[256];
+
+ sprintf(line, player_sav, slotnum);
+
+ fp = fopen(line, "w");
+ if(fp) {
+ PRINT("%i", player.level);
+
+ if(player.level > 0) {
+ PRINT("%i", (secstart + secsingame));
+ PRINT("%s", "a");
+
+ PRINT("%f", player.px);
+ PRINT("%f", player.py);
+ PRINT("%f", player.opx);
+ PRINT("%f", player.opy);
+ PRINT("%i", player.walkdir);
+ PRINT("%f", player.walkframe);
+ PRINT("%f", player.walkspd);
+ PRINT("%f", player.attackframe);
+ PRINT("%f", player.attackspd);
+ PRINT("%i", player.hp);
+ PRINT("%i", player.maxhp);
+ PRINT("%f", player.hpflash);
+ PRINT("%i", player.level);
+ PRINT("%i", player.maxlevel);
+ PRINT("%i", player.sword);
+ PRINT("%i", player.shield);
+ PRINT("%i", player.armour);
+ for(int i = 0; i < 5; i++) {
+ PRINT("%i", player.foundspell[i]);
+ PRINT("%f", player.spellcharge[i]);
+ }
+ for(int a = 0; a < 5; a++) {
+ PRINT("%i", player.inventory[a]);
+ }
+ PRINT("%f", player.attackstrength);
+ PRINT("%i", player.spelldamage);
+ PRINT("%i", player.sworddamage);
+ PRINT("%i", player.exp);
+ PRINT("%i", player.nextlevel);
+ for(int a = 0; a <= 99; a++) {
+ for(int b = 0; b <= 9; b++) {
+ PRINT("%i", scriptflag[a][b]);
+ }
+ }
+ PRINT("%i", curmap);
+
+ for(int a = 0; a <= 999; a++) {
+ for(int b = 0; b <= 20; b++) {
+ for(int c = 0; c <= 14; c++) {
+ PRINT("%i", objmapf[a][b][c]);
+ }
+ }
+ }
+
+ for(int a = 0; a <= 200; a++) {
+ PRINT("%i", roomlocks[a]);
+ }
+
+ PRINT("%f", player.spellstrength);
+ }
+
+ fclose(fp);
+
+ return 1; // success
+ }
+
+ return 0; // fail
+}
diff --git a/engines/griffon/state.h b/engines/griffon/state.h
new file mode 100644
index 0000000000..d7f93aac95
--- /dev/null
+++ b/engines/griffon/state.h
@@ -0,0 +1,27 @@
+/*
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#ifndef _STATE_H_
+#define _STATE_H_
+
+extern char player_sav[];
+
+int state_load(int slotnum);
+int state_load_player(int slotnum);
+int state_save(int slotnum);
+
+#endif // _STATE_H_