Some game functionalities of CK 8.4 has been implemented.
Fixed a bug which made the main-menu crash sometimes git-svn-id: https://clonekeenplus.svn.sourceforge.net/svnroot/clonekeenplus/cgenius/trunk@205 4df4b0f3-56ce-47cb-b001-ed939b7d65a6
This commit is contained in:
@@ -288,7 +288,7 @@ void CGame::preallocateCKP(stCloneKeenPlus *pCKP)
|
||||
|
||||
framebyframe = 0;
|
||||
|
||||
demomode = DEMO_NODEMO;
|
||||
pCKP->Control.levelcontrol.demomode = DEMO_NODEMO;
|
||||
current_demo = 1;
|
||||
|
||||
pCKP->Joystick = NULL;
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
*/
|
||||
|
||||
#include "keen.h"
|
||||
#include "keenext.h"
|
||||
//#include "externals.h"
|
||||
#include "CGraphics.h"
|
||||
#include "sdl/CVideoDriver.h"
|
||||
#include "sdl/video/colourtable.h"
|
||||
|
||||
@@ -45,8 +45,7 @@ int speed;
|
||||
}
|
||||
|
||||
// test if it hit a baddie
|
||||
//for(i=1;i<highest_objslot;i++)
|
||||
for(i=1;i<MAX_OBJECTS;i++) // TODO: Must be replaced by the upper when highest_objslot is in existence
|
||||
for(i=1;i<highest_objslot;i++)
|
||||
{
|
||||
if (!objects[i].exists || i==o) continue;
|
||||
if (objects[i].type==OBJ_RAY || objects[i].type==OBJ_FIREBALL) continue;
|
||||
|
||||
13
src/externals.cpp
Normal file
13
src/externals.cpp
Normal file
@@ -0,0 +1,13 @@
|
||||
/*
|
||||
* externals.cpp
|
||||
*
|
||||
* Created on: 02.08.2009
|
||||
* Author: gerstrong
|
||||
*
|
||||
* That file declare the external (without extern) variables that are used in the game
|
||||
*
|
||||
* I personally am not a fan of external variables, but we still need some of them.
|
||||
* In future that file should be able to be removed.
|
||||
*/
|
||||
|
||||
int highest_objslot; // the highest object slot in use, +1
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "sdl/CSettings.h"
|
||||
|
||||
extern int highest_objslot; // the highest object slot in use, +1
|
||||
extern char PlatExtending;
|
||||
extern stFade fade;
|
||||
extern stMap map;
|
||||
@@ -76,7 +77,6 @@ extern int DemoSprite;
|
||||
extern stShipQueue shipqueue[32];
|
||||
extern int ShipQueuePtr;
|
||||
|
||||
extern int demomode;
|
||||
extern FILE *demofile;
|
||||
extern unsigned int demo_RLERunLen;
|
||||
extern unsigned char demo_data[DEMO_MAX_SIZE+1];
|
||||
@@ -11,7 +11,6 @@
|
||||
#include "hqp/CMusic.h"
|
||||
#include "include/fileio.h"
|
||||
#include "include/fileio/rle.h"
|
||||
#include "vorticon/CPlayer.h"
|
||||
#include "CLogFile.h"
|
||||
#include "CGraphics.h"
|
||||
#include <unistd.h>
|
||||
@@ -21,8 +20,6 @@
|
||||
#include "Debug.h"
|
||||
#include "FindFile.h"
|
||||
|
||||
extern CPlayer *Player;
|
||||
|
||||
unsigned int curmapx, curmapy;
|
||||
unsigned char mapdone;
|
||||
void addmaptile(unsigned int t)
|
||||
|
||||
@@ -13,32 +13,21 @@ void gamedo_render_drawdebug(void);
|
||||
void gamedo_render_erasedebug(void);
|
||||
void gamedo_fades(void);
|
||||
|
||||
// gamepdo.c
|
||||
|
||||
|
||||
// gamepdowm.c
|
||||
//void gamepdo_wm_HandlePlayer(int cp);
|
||||
//void gamepdo_InertiaAndFriction_Y(int cp);
|
||||
//void gamepdo_wm_AllowEnterLevel(int cp);
|
||||
char wm_issolid(int xb, int yb, int *levels_completed);
|
||||
|
||||
// game.c
|
||||
//void SetGameOver(void);
|
||||
void overrun_detect(void);
|
||||
void scrolltest(void);
|
||||
//void gameloop_initialize(void);
|
||||
void give_keycard(int doortile, int p);
|
||||
void take_keycard(int doortile, int p);
|
||||
//void open_door(int doortile, int doorsprite, int mpx, int mpy, int cp, stCloneKeenPlus *pCKP)
|
||||
void extralifeat(int p);
|
||||
char spawn_object(int x, int y, int otype);
|
||||
void common_enemy_ai(int o);
|
||||
char hitdetect(int object1, int object2);
|
||||
void freezeplayer(int theplayer);
|
||||
void unregister_animtiles(int tile);
|
||||
//void endlevel(int success, stCloneKeenPlus *pCKP)
|
||||
char checkobjsolid(unsigned int x, unsigned int y, unsigned int cp);
|
||||
//void initsprites(stCloneKeenPlus *pCKP)
|
||||
void CopyTileToSprite(int t, int s, int ntilestocopy, int transparent);
|
||||
void GiveAnkh(int cp);
|
||||
// map.c
|
||||
@@ -104,12 +93,6 @@ void sb_mask_font_draw(unsigned char *text, int xoff, int yoff, char mask);
|
||||
void sb_color_font_draw(unsigned char *text, int xoff, int yoff, unsigned int colour, unsigned short bgcolour);
|
||||
void sb_font_draw_inverse(unsigned char *text, int xoff, int yoff);
|
||||
// viddrv.c
|
||||
// fileio.c
|
||||
//void addmaptile(unsigned int t, stCloneKeenPlus *pCKP);
|
||||
//void addenemytile(unsigned int t, stCloneKeenPlus *pCKP);
|
||||
//unsigned int fgeti(FILE *fp);
|
||||
//unsigned long fgetl(FILE *fp);
|
||||
//unsigned int loadmap(char *filename, char *path, int lvlnum, int isworldmap);
|
||||
#include "fileio.h"
|
||||
|
||||
bool loadtileattributes(int episode, int version, unsigned char *filebuf);
|
||||
@@ -155,8 +138,5 @@ char lz_decompress(FILE *lzfile, unsigned char *outbuffer);
|
||||
// finale.c
|
||||
void finale_draw(const std::string& filename, const std::string& path);
|
||||
|
||||
// scalerx.c
|
||||
//void scale2x(void* void_dst, unsigned dst_slice, const void* void_src, unsigned src_slice, unsigned pixel, unsigned width, unsigned height);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
288
src/game.cpp
288
src/game.cpp
@@ -18,7 +18,6 @@
|
||||
#include "sdl/sound/CSound.h"
|
||||
#include "include/enemyai.h"
|
||||
#include "hqp/CMusic.h"
|
||||
#include "vorticon/CPlayer.h"
|
||||
#include "vorticon/CHighScores.h"
|
||||
#include "hqp/CHQBitmap.h"
|
||||
#include "CLogFile.h"
|
||||
@@ -94,18 +93,6 @@ void gameloop(stCloneKeenPlus *pCKP)
|
||||
{
|
||||
if (primaryplayer==1) otherplayer = 0; else otherplayer = 1;
|
||||
|
||||
#ifdef NETWORK_PLAY
|
||||
// if (numplayers>1) net_getdata();
|
||||
if (is_server)
|
||||
{
|
||||
Net_Server_Run();
|
||||
}
|
||||
else if (is_client)
|
||||
{
|
||||
Net_Client_Run();
|
||||
}
|
||||
#endif
|
||||
|
||||
gamedo_fades();
|
||||
|
||||
// periodically make all enemy gun fixtures fire (in ep3)
|
||||
@@ -159,7 +146,7 @@ void gameloop(stCloneKeenPlus *pCKP)
|
||||
{
|
||||
if (fade.dir==FADE_OUT)
|
||||
{
|
||||
demomode = DEMO_NODEMO;
|
||||
pCKP->Control.levelcontrol.demomode = DEMO_NODEMO;
|
||||
pCKP->Control.levelcontrol.level_done = LEVEL_COMPLETE;
|
||||
pCKP->Control.levelcontrol.command = LVLC_CHANGE_LEVEL;
|
||||
if (pCKP->Control.levelcontrol.curlevel != WM_MAP_NUM)
|
||||
@@ -378,15 +365,6 @@ short tilefix=0;
|
||||
objects[o].sprite = doorsprite;
|
||||
}
|
||||
|
||||
void delete_object(int o)
|
||||
{
|
||||
if (objects[o].exists)
|
||||
{
|
||||
objects[o].exists = 0;
|
||||
//if (o+1==highest_objslot) highest_objslot--;
|
||||
}
|
||||
}
|
||||
|
||||
// checks if score is > than "extra life at" and award 1-UPs when appropriate
|
||||
void extralifeat(int cp)
|
||||
{
|
||||
@@ -557,19 +535,19 @@ unsigned int i;
|
||||
}
|
||||
// each player is tied to a "puppet" object.
|
||||
// initialize objects used by players.
|
||||
int o;
|
||||
for(i=0;i<numplayers;i++)
|
||||
{
|
||||
o = player[i].useObject;
|
||||
if (player[i].isPlaying)
|
||||
{
|
||||
objects[o].exists = 1;
|
||||
objects[o].onscreen = 1;
|
||||
objects[o].type = OBJ_PLAYER;
|
||||
objects[o].sprite = 0;
|
||||
objects[o].onscreen = 1;
|
||||
objects[o].AssociatedWithPlayer = i;
|
||||
objects[o].honorPriority = 1;
|
||||
objects[player[i].useObject].exists = 1;
|
||||
objects[player[i].useObject].onscreen = 1;
|
||||
objects[player[i].useObject].type = OBJ_PLAYER;
|
||||
objects[player[i].useObject].sprite = 0;
|
||||
objects[player[i].useObject].onscreen = 1;
|
||||
objects[player[i].useObject].AssociatedWithPlayer = i;
|
||||
objects[player[i].useObject].honorPriority = 1;
|
||||
objects[player[i].useObject].canbezapped = false;
|
||||
highest_objslot = player[i].useObject + 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -616,10 +594,10 @@ int initgamefirsttime(stCloneKeenPlus *pCKP, int s)
|
||||
{
|
||||
player[i].inventory.charges = 5;
|
||||
}
|
||||
if (demomode) player[i].inventory.charges = 100;
|
||||
if (pCKP->Control.levelcontrol.demomode) player[i].inventory.charges = 100;
|
||||
|
||||
// start with pogo stick in all episodes but 1
|
||||
if (pCKP->Control.levelcontrol.episode!=1 || demomode)
|
||||
if (pCKP->Control.levelcontrol.episode!=1 || pCKP->Control.levelcontrol.demomode)
|
||||
{ player[i].inventory.HasPogo = 1; }
|
||||
else
|
||||
{ player[i].inventory.HasPogo = 0; }
|
||||
@@ -627,7 +605,7 @@ int initgamefirsttime(stCloneKeenPlus *pCKP, int s)
|
||||
|
||||
initsprites(pCKP, s);
|
||||
|
||||
if (demomode) srand(375);
|
||||
if (pCKP->Control.levelcontrol.demomode) srand(375);
|
||||
|
||||
primaryplayer = 0;
|
||||
|
||||
@@ -638,7 +616,7 @@ char spawn_object(int x, int y, int otype)
|
||||
{
|
||||
int i;
|
||||
// find an unused object slot
|
||||
for(i=1;i<MAX_OBJECTS-1;i++)
|
||||
for(i=1;i<MAX_OBJECTS;i++)
|
||||
{
|
||||
if (!objects[i].exists && objects[i].type != OBJ_PLAYER)
|
||||
{
|
||||
@@ -648,163 +626,121 @@ int i;
|
||||
objects[i].sprite = objdefsprites[otype];
|
||||
objects[i].exists = 1;
|
||||
objects[i].needinit = 1;
|
||||
objects[i].dead = false;
|
||||
objects[i].onscreen = 0;
|
||||
objects[i].hasbeenonscreen = 0;
|
||||
objects[i].canbezapped = 0;
|
||||
objects[i].zapped = 0;
|
||||
objects[i].canbezapped = 0;
|
||||
objects[i].inhibitfall = 0;
|
||||
objects[i].honorPriority = 1;
|
||||
|
||||
SetAllCanSupportPlayer(i, 0);
|
||||
|
||||
if( i >= highest_objslot )
|
||||
highest_objslot = i+1;
|
||||
|
||||
return i;
|
||||
}
|
||||
}
|
||||
// object could not be created
|
||||
|
||||
g_pLogFile->textOut(PURPLE, "Warning : Object could not be created.");
|
||||
return 0;
|
||||
// object could not be created
|
||||
//crash("Object of type %d could not be created at %d,%d (out of object slots)",otype,x,y);
|
||||
g_pLogFile->ftextOut("Object of type %d could not be created at %d,%d (out of object slots)<br>",otype,x,y);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// common enemy/object ai, such as falling, setting blocked variables,
|
||||
// detecting player contact, etc.
|
||||
void common_enemy_ai(int o)
|
||||
void delete_object(int o)
|
||||
{
|
||||
int x,y,xa,ya,xsize,ysize;
|
||||
int temp;
|
||||
int cplayer;
|
||||
if (objects[o].exists)
|
||||
{
|
||||
objects[o].exists = 0;
|
||||
if (o+1==highest_objslot) highest_objslot--;
|
||||
}
|
||||
}
|
||||
|
||||
if (objects[o].type==OBJ_DEMOMSG) return;
|
||||
void delete_all_objects(void)
|
||||
{
|
||||
int i;
|
||||
for(i=0;i<MAX_OBJECTS;i++)
|
||||
{
|
||||
if (objects[i].exists && objects[i].type != OBJ_PLAYER)
|
||||
delete_object(i);
|
||||
}
|
||||
recalc_highest_objslot();
|
||||
}
|
||||
void recalc_highest_objslot(void)
|
||||
{
|
||||
int i;
|
||||
highest_objslot = 0;
|
||||
for(i=MAX_OBJECTS-1;i>=0;i--)
|
||||
{
|
||||
if (objects[i].exists)
|
||||
{
|
||||
highest_objslot = i+1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
xsize = sprites[objects[o].sprite].xsize;
|
||||
ysize = sprites[objects[o].sprite].ysize;
|
||||
// anything (players/enemies) occupying the map tile at [mpx,mpy] is killed
|
||||
/*void kill_all_intersecting_tile(int mpx, int mpy)
|
||||
{
|
||||
int xpix,ypix;
|
||||
int i;
|
||||
xpix = mpx<<TILE_S<<CSF;
|
||||
ypix = mpy<<TILE_S<<CSF;
|
||||
for(i=0;i<highest_objslot;i++)
|
||||
{
|
||||
if (objects[i].exists)
|
||||
{
|
||||
if (xpix <= objects[i].x && xpix+(16<<CSF) >= objects[i].x)
|
||||
{
|
||||
if (ypix <= objects[i].y && ypix+(16<<CSF) >= objects[i].y)
|
||||
{
|
||||
killobject(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
// set value of blockedd--should object fall?
|
||||
temp = (objects[o].y>>CSF)+ysize;
|
||||
if ((temp>>4)<<4 != temp)
|
||||
{
|
||||
objects[o].blockedd = 0;
|
||||
}
|
||||
else
|
||||
{ // on a tile boundary, test if tile under object is solid
|
||||
objects[o].blockedd = 0;
|
||||
x = (objects[o].x>>CSF);
|
||||
y = (objects[o].y>>CSF)+ysize+1;
|
||||
for(xa=0;xa<xsize-2;xa+=16)
|
||||
{
|
||||
if(TileProperty[getmaptileat(x+xa,y)][BUP] || (TileProperty[getmaptileat(x+xa,y)][BEHAVIOR] > 1 &&
|
||||
TileProperty[getmaptileat(x+xa,y)][BEHAVIOR] < 6) )
|
||||
{
|
||||
objects[o].blockedd = 1;
|
||||
goto setblockedd;
|
||||
}
|
||||
}
|
||||
if(TileProperty[getmaptileat(x+xsize-2, y)][BUP] || (TileProperty[getmaptileat(x+xa,y)][BEHAVIOR] > 1 &&
|
||||
TileProperty[getmaptileat(x+xa,y)][BEHAVIOR] < 6) )
|
||||
{
|
||||
objects[o].blockedd = 1;
|
||||
}
|
||||
setblockedd: ;
|
||||
}
|
||||
// returns whether pix position x,y is a stop point for object o.
|
||||
// stop points are invisible blockers that act solid only to certain
|
||||
// kinds of enemies. They're used to help make the enemies seem smarter
|
||||
// and keep them from falling off certain platforms. Stoppoints are manually
|
||||
// placed from fileio.c.
|
||||
char IsStopPoint(int x, int y, int o)
|
||||
{
|
||||
switch(objects[o].type)
|
||||
{
|
||||
case OBJ_YORP:
|
||||
case OBJ_GARG:
|
||||
case OBJ_MOTHER:
|
||||
case OBJ_VORT:
|
||||
case OBJ_VORTELITE:
|
||||
case OBJ_TANK:
|
||||
case OBJ_TANKEP2:
|
||||
//if (getlevelat(x,y)==ENEMY_STOPPOINT) return 1;
|
||||
case OBJ_WALKER:
|
||||
case OBJ_PLATFORM:
|
||||
case OBJ_PLATVERT:
|
||||
case OBJ_BABY:
|
||||
//if (IsDoor(getmaptileat(x,y))) return 1;
|
||||
break;
|
||||
|
||||
// set blockedu
|
||||
objects[o].blockedu = 0;
|
||||
x = (objects[o].x>>CSF);
|
||||
y = (objects[o].y>>CSF)-1;
|
||||
for(xa=0;xa<xsize;xa+=16)
|
||||
{
|
||||
if(TileProperty[getmaptileat(x+xa,y)][BDOWN])
|
||||
//if (tiles[getmaptileat(x+xa,y)].solidceil)
|
||||
{
|
||||
objects[o].blockedu = 1;
|
||||
goto setblockedu;
|
||||
}
|
||||
}
|
||||
if(TileProperty[getmaptileat(x+xsize-1, y)][BDOWN])
|
||||
//if (tiles[getmaptileat(x+xsize-1, y)].solidceil)
|
||||
{
|
||||
objects[o].blockedu = 1;
|
||||
}
|
||||
setblockedu: ;
|
||||
case OBJ_RAY:
|
||||
/*if (getoption(OPT_DOORSBLOCKRAY)) // TODO: The option must has to be implemented
|
||||
{
|
||||
if (IsDoor(getmaptileat(x,y))) return 1;
|
||||
}*/
|
||||
break;
|
||||
|
||||
// set blockedl
|
||||
objects[o].blockedl = 0;
|
||||
x = (objects[o].x>>CSF)-1;
|
||||
y = (objects[o].y>>CSF)+1;
|
||||
for(ya=0;ya<ysize;ya+=16)
|
||||
{
|
||||
if(TileProperty[getmaptileat(x,y+ya)][BRIGHT])
|
||||
//if (tiles[getmaptileat(x,y+ya)].solidr)
|
||||
{
|
||||
objects[o].blockedl = 1;
|
||||
goto setblockedl;
|
||||
}
|
||||
}
|
||||
if(TileProperty[getmaptileat(x, ((objects[o].y>>CSF)+ysize-1))][BRIGHT])
|
||||
//if (tiles[getmaptileat(x, ((objects[o].y>>CSF)+ysize-1))].solidr)
|
||||
{
|
||||
objects[o].blockedl = 1;
|
||||
}
|
||||
setblockedl: ;
|
||||
case OBJ_BALL:
|
||||
if (getlevelat(x,y)==BALL_NOPASSPOINT) return 1;
|
||||
//if (IsDoor(getmaptileat(x,y))) return 1;
|
||||
break;
|
||||
}
|
||||
|
||||
// set blockedr
|
||||
objects[o].blockedr = 0;
|
||||
x = (objects[o].x>>CSF)+xsize;
|
||||
y = (objects[o].y>>CSF)+1;
|
||||
for(ya=0;ya<ysize;ya+=16)
|
||||
{
|
||||
if(TileProperty[getmaptileat(x,y+ya)][BRIGHT])
|
||||
//if (tiles[getmaptileat(x,y+ya)].solidl)
|
||||
{
|
||||
objects[o].blockedr = 1;
|
||||
goto setblockedr;
|
||||
}
|
||||
}
|
||||
if(TileProperty[getmaptileat(x, ((objects[o].y>>CSF)+ysize-1))][BLEFT])
|
||||
//if (tiles[getmaptileat(x, ((objects[o].y>>CSF)+ysize-1))].solidl)
|
||||
{
|
||||
objects[o].blockedr = 1;
|
||||
}
|
||||
setblockedr: ;
|
||||
|
||||
// hit detection with players
|
||||
objects[o].touchPlayer = 0;
|
||||
for(cplayer=0;cplayer<MAX_PLAYERS;cplayer++)
|
||||
{
|
||||
if (player[cplayer].isPlaying)
|
||||
{
|
||||
objects[player[cplayer].useObject].x = player[cplayer].x;
|
||||
objects[player[cplayer].useObject].y = player[cplayer].y;
|
||||
objects[player[cplayer].useObject].sprite = 0;
|
||||
if (!player[cplayer].pdie)
|
||||
{
|
||||
if (hitdetect(o, player[cplayer].useObject))
|
||||
{
|
||||
objects[o].touchPlayer = 1;
|
||||
objects[o].touchedBy = cplayer;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// have object fall if it should
|
||||
if (!objects[o].inhibitfall)
|
||||
{
|
||||
#define OBJFALLSPEED 20
|
||||
if (objects[o].blockedd)
|
||||
{
|
||||
objects[o].yinertia = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
#define OBJ_YINERTIA_RATE 5
|
||||
if (objects[o].yinertiatimer>OBJ_YINERTIA_RATE)
|
||||
{
|
||||
if (objects[o].yinertia < OBJFALLSPEED) objects[o].yinertia++;
|
||||
objects[o].yinertiatimer = 0;
|
||||
} else objects[o].yinertiatimer++;
|
||||
}
|
||||
objects[o].y += objects[o].yinertia;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// returns nonzero if object1 overlaps object2
|
||||
@@ -943,7 +879,7 @@ char checkobjsolid(unsigned int x, unsigned int y, unsigned int cp)
|
||||
{
|
||||
int o;
|
||||
|
||||
for(o=1;o<MAX_OBJECTS;o++)
|
||||
for(o=1;o<highest_objslot;o++)
|
||||
{
|
||||
if (objects[o].exists && objects[o].cansupportplayer[cp])
|
||||
{
|
||||
|
||||
209
src/gamedo.cpp
209
src/gamedo.cpp
@@ -15,8 +15,7 @@
|
||||
#include "sdl/CInput.h"
|
||||
#include "sdl/sound/CSound.h"
|
||||
#include "CGraphics.h"
|
||||
#include "vorticon/CPlayer.h"
|
||||
#include "keenext.h"
|
||||
#include "externals.h"
|
||||
#include "StringUtils.h"
|
||||
|
||||
#include "include/enemyai.h"
|
||||
@@ -28,8 +27,6 @@ extern unsigned long CurrentTickCount;
|
||||
|
||||
extern unsigned int unknownKey;
|
||||
|
||||
extern CPlayer *Player;
|
||||
|
||||
int animtiletimer, curanimtileframe;
|
||||
|
||||
// gathers data from input controllers: keyboard, joystick, network,
|
||||
@@ -46,7 +43,8 @@ int i=0;
|
||||
int byt;
|
||||
unsigned int msb, lsb;
|
||||
|
||||
if (demomode==DEMO_PLAYBACK)
|
||||
|
||||
if (pCKP->Control.levelcontrol.demomode==DEMO_PLAYBACK)
|
||||
{
|
||||
// time to get a new key block?
|
||||
if (!demo_RLERunLen)
|
||||
@@ -123,7 +121,7 @@ unsigned int msb, lsb;
|
||||
if(g_pInput->getHoldedCommand(p, IC_STATUS))
|
||||
player[p].playcontrol[PA_STATUS] = 1;
|
||||
|
||||
if (demomode==DEMO_RECORD)
|
||||
if (pCKP->Control.levelcontrol.demomode==DEMO_RECORD)
|
||||
{
|
||||
if(i) player[p].playcontrol[PA_X] += 100;
|
||||
fputc(i, demofile);
|
||||
@@ -214,12 +212,16 @@ int i;
|
||||
// do object and enemy AI
|
||||
void gamedo_enemyai(stCloneKeenPlus *pCKP)
|
||||
{
|
||||
int i;
|
||||
// handle objects and do enemy AI
|
||||
for(i=1;i<MAX_OBJECTS-1;i++)
|
||||
int i, topobj;
|
||||
// handle objects and do enemy AI
|
||||
topobj = highest_objslot;
|
||||
for(i=1;i<topobj;i++)
|
||||
{
|
||||
if (!objects[i].exists || objects[i].type==OBJ_PLAYER) continue;
|
||||
|
||||
//gamedo_calcenemyvisibility(i);
|
||||
|
||||
// This will do the function gamedo_calcenemyvisibility(i);
|
||||
// check if object is really in the map!!!
|
||||
if (objects[i].x < 0 || objects[i].y < 0)
|
||||
continue;
|
||||
@@ -238,19 +240,16 @@ int i;
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef TARGET_WIN32
|
||||
// if (numplayers>1)
|
||||
// if (!objects[i].hasbeenonscreen)
|
||||
// net_sendobjectonscreen(i);
|
||||
#endif
|
||||
|
||||
objects[i].onscreen = 1;
|
||||
objects[i].hasbeenonscreen = 1;
|
||||
}
|
||||
|
||||
if (objects[i].hasbeenonscreen || objects[i].type==OBJ_RAY || \
|
||||
objects[i].type==OBJ_ICECHUNK || objects[i].type==OBJ_PLATFORM ||\
|
||||
objects[i].type==OBJ_PLATVERT)
|
||||
if (objects[i].hasbeenonscreen || objects[i].zapped ||
|
||||
objects[i].type==OBJ_RAY || \
|
||||
objects[i].type==OBJ_ICECHUNK || objects[i].type==OBJ_PLATFORM ||\
|
||||
objects[i].type==OBJ_PLATVERT || objects[i].type==OBJ_YORP ||
|
||||
objects[i].type==OBJ_FOOB || objects[i].type==OBJ_WALKER)
|
||||
|
||||
{
|
||||
common_enemy_ai(i);
|
||||
switch(objects[i].type)
|
||||
@@ -263,6 +262,7 @@ int i;
|
||||
case OBJ_TANK: tank_ai(i, pCKP->Control.levelcontrol.hardmode); break;
|
||||
case OBJ_RAY: ray_ai(i, pCKP, pCKP->Control.levelcontrol); break;
|
||||
case OBJ_DOOR: door_ai(i, pCKP->Control.levelcontrol.cepvars.DoorOpenDir); break;
|
||||
//case OBJ_ICECANNON: icecannon_ai(i); break; TODO: Add this AI
|
||||
case OBJ_ICECHUNK: icechunk_ai(i); break;
|
||||
case OBJ_ICEBIT: icebit_ai(i); break;
|
||||
case OBJ_TELEPORTER: teleporter_ai(i, pCKP->Control.levelcontrol); break;
|
||||
@@ -277,6 +277,7 @@ int i;
|
||||
pCKP->Control.levelcontrol.hardmode); break;
|
||||
case OBJ_EXPLOSION: explosion_ai(i); break;
|
||||
case OBJ_EARTHCHUNK: earthchunk_ai(i); break;
|
||||
//case OBJ_SPARK: spark_ai(i); break; TODO: Add this AI
|
||||
//KEEN3
|
||||
case OBJ_FOOB: foob_ai(i, pCKP); break;
|
||||
case OBJ_NINJA: ninja_ai(i, pCKP); break;
|
||||
@@ -288,13 +289,13 @@ int i;
|
||||
case OBJ_JACK: ballandjack_ai(i); break;
|
||||
case OBJ_PLATVERT: platvert_ai(i); break;
|
||||
case OBJ_NESSIE: nessie_ai(i); break;
|
||||
//Specials
|
||||
//case OBJ_AUTORAY: case OBJ_AUTORAY_V: autoray_ai(i); break;
|
||||
//case OBJ_GOTPOINTS: gotpoints_ai(i); break;
|
||||
|
||||
case OBJ_DEMOMSG: break;
|
||||
default:
|
||||
crashflag = 1;
|
||||
crashflag2 = i;
|
||||
crashflag3 = objects[i].type;
|
||||
why_term_ptr = "Invalid object flag2 of type flag3";
|
||||
//crash("gamedo_enemy_ai: Object %d is of invalid type %d\n", i, objects[i].type);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -304,6 +305,162 @@ int i;
|
||||
}
|
||||
}
|
||||
|
||||
// common enemy/object ai, such as falling, setting blocked variables,
|
||||
// detecting player contact, etc.
|
||||
void common_enemy_ai(int o)
|
||||
{
|
||||
int x,y,xa,ya,xsize,ysize;
|
||||
int temp;
|
||||
int cplayer;
|
||||
|
||||
//if (objects[o].type==OBJ_GOTPOINTS) return;
|
||||
|
||||
xsize = sprites[objects[o].sprite].xsize;
|
||||
ysize = sprites[objects[o].sprite].ysize;
|
||||
|
||||
// set value of blockedd--should object fall?
|
||||
temp = (objects[o].y>>CSF)+ysize;
|
||||
if ((temp>>TILE_S)<<TILE_S != temp)
|
||||
{
|
||||
objects[o].blockedd = 0;
|
||||
}
|
||||
else
|
||||
{ // on a tile boundary, test if tile under object is solid
|
||||
objects[o].blockedd = 0;
|
||||
x = (objects[o].x>>CSF);
|
||||
y = (objects[o].y>>CSF)+ysize+1;
|
||||
for(xa=0;xa<xsize-2;xa+=16)
|
||||
{
|
||||
if (TileProperty[getmaptileat(x+xa,y)][BDOWN] || IsStopPoint(x+xa,y,o))
|
||||
{
|
||||
objects[o].blockedd = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!objects[o].blockedd) // check final point
|
||||
{
|
||||
if (TileProperty[getmaptileat(x+xsize-2, y)][BDOWN] || IsStopPoint(x+xsize-2,y,o))
|
||||
{
|
||||
objects[o].blockedd = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// set blockedu
|
||||
objects[o].blockedu = 0;
|
||||
x = (objects[o].x>>CSF);
|
||||
y = (objects[o].y>>CSF)-1;
|
||||
for(xa=1;xa<xsize;xa+=16) // change start pixel to xa=1 for icecannon in ep1l8
|
||||
{
|
||||
if (TileProperty[getmaptileat(x+xa,y)][BUP] || IsStopPoint(x+xa,y,o))
|
||||
{
|
||||
objects[o].blockedu = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!objects[o].blockedu) // check final point
|
||||
{
|
||||
if (TileProperty[getmaptileat(x+xsize-2, y)][BUP] || IsStopPoint(x+xsize-2,y,o))
|
||||
{
|
||||
objects[o].blockedu = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// set blockedl
|
||||
objects[o].blockedl = 0;
|
||||
x = (objects[o].x>>CSF)-1;
|
||||
y = (objects[o].y>>CSF)+1;
|
||||
for(ya=0;ya<ysize;ya+=16)
|
||||
{
|
||||
|
||||
if (TileProperty[getmaptileat(x,y+ya)][BRIGHT] || IsStopPoint(x,y+ya,o))
|
||||
{
|
||||
objects[o].blockedl = 1;
|
||||
goto blockedl_set;
|
||||
}
|
||||
}
|
||||
if (TileProperty[getmaptileat(x, ((objects[o].y>>CSF)+ysize-1))][BRIGHT] ||
|
||||
IsStopPoint(x, (objects[o].y>>CSF)+ysize-1, o))
|
||||
{
|
||||
objects[o].blockedl = 1;
|
||||
}
|
||||
blockedl_set: ;
|
||||
|
||||
// set blockedr
|
||||
objects[o].blockedr = 0;
|
||||
x = (objects[o].x>>CSF)+xsize;
|
||||
y = (objects[o].y>>CSF)+1;
|
||||
for(ya=0;ya<ysize;ya+=16)
|
||||
{
|
||||
if (TileProperty[getmaptileat(x,y+ya)][BLEFT] || IsStopPoint(x,y+ya,o))
|
||||
{
|
||||
objects[o].blockedr = 1;
|
||||
goto blockedr_set;
|
||||
}
|
||||
}
|
||||
if (TileProperty[getmaptileat(x, ((objects[o].y>>CSF)+ysize-1))][BLEFT] ||
|
||||
IsStopPoint(x, (objects[o].y>>CSF)+ysize-1, o))
|
||||
{
|
||||
objects[o].blockedr = 1;
|
||||
}
|
||||
blockedr_set: ;
|
||||
|
||||
// hit detection with players
|
||||
objects[o].touchPlayer = 0;
|
||||
for(cplayer=0;cplayer<MAX_PLAYERS;cplayer++)
|
||||
{
|
||||
if (player[cplayer].isPlaying)
|
||||
{
|
||||
objects[player[cplayer].useObject].x = player[cplayer].x;
|
||||
objects[player[cplayer].useObject].y = player[cplayer].y;
|
||||
objects[player[cplayer].useObject].sprite = 0;
|
||||
if (!player[cplayer].pdie)
|
||||
{
|
||||
if (hitdetect(o, player[cplayer].useObject))
|
||||
{
|
||||
if (!player[cplayer].godmode)
|
||||
{
|
||||
objects[o].touchPlayer = 1;
|
||||
objects[o].touchedBy = cplayer;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (objects[o].type==OBJ_MOTHER || objects[o].type==OBJ_BABY ||\
|
||||
objects[o].type==OBJ_MEEP || objects[o].type==OBJ_YORP)
|
||||
{
|
||||
if (objects[o].canbezapped)
|
||||
objects[o].zapped += 100;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// have object fall if it should
|
||||
if (!objects[o].inhibitfall)
|
||||
{
|
||||
#define OBJFALLSPEED 20
|
||||
if (objects[o].blockedd)
|
||||
{
|
||||
objects[o].yinertia = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
#define OBJ_YINERTIA_RATE 5
|
||||
if (objects[o].yinertiatimer>OBJ_YINERTIA_RATE)
|
||||
{
|
||||
if (objects[o].yinertia < OBJFALLSPEED) objects[o].yinertia++;
|
||||
objects[o].yinertiatimer = 0;
|
||||
} else objects[o].yinertiatimer++;
|
||||
}
|
||||
objects[o].y += objects[o].yinertia;
|
||||
}
|
||||
}
|
||||
|
||||
int savew, saveh;
|
||||
|
||||
@@ -337,7 +494,7 @@ int xa,ya;
|
||||
|
||||
// if we're playing a demo keep the "DEMO" message on the screen
|
||||
// as an object
|
||||
if (demomode==DEMO_PLAYBACK)
|
||||
if (pCKP->Control.levelcontrol.demomode==DEMO_PLAYBACK)
|
||||
{
|
||||
#define DEMO_X_POS 137
|
||||
#define DEMO_Y_POS 6
|
||||
@@ -353,7 +510,7 @@ int xa,ya;
|
||||
|
||||
// draw all objects. drawn in reverse order because the player sprites
|
||||
// are in the first few indexes and we want them to come out on top.
|
||||
for(i=MAX_OBJECTS-1;;i--)
|
||||
for(i=highest_objslot;;i--)
|
||||
{
|
||||
if (objects[i].exists && objects[i].onscreen)
|
||||
{
|
||||
@@ -515,10 +672,10 @@ void gamedo_RenderScreen(stCloneKeenPlus *pCKP)
|
||||
|
||||
g_pGraphics->renderHQBitmap();
|
||||
|
||||
gamedo_render_drawobjects(pCKP);
|
||||
|
||||
if(pCKP != NULL)
|
||||
{
|
||||
gamedo_render_drawobjects(pCKP);
|
||||
|
||||
if (pCKP->Control.levelcontrol.gameovermode)
|
||||
{
|
||||
// figure out where to center the gameover bitmap and draw it
|
||||
|
||||
@@ -66,7 +66,7 @@ char doFall;
|
||||
}
|
||||
|
||||
|
||||
if (fade.mode==NO_FADE || fade.dir==FADE_IN || demomode)
|
||||
if (fade.mode==NO_FADE || fade.dir==FADE_IN || pCKP->Control.levelcontrol.demomode)
|
||||
{
|
||||
gamepdo_playpushed(cp, pCKP);
|
||||
gamepdo_InertiaAndFriction_X(cp, pCKP);
|
||||
|
||||
@@ -51,6 +51,7 @@ struct stLevelControl
|
||||
int episode; // which episode we're playing (1-3)
|
||||
bool hardmode;
|
||||
bool usedhintmb; // Has the message box been used?
|
||||
int demomode;
|
||||
|
||||
// array of which levels have been completed (have "Done" tiles over them
|
||||
// on the world map)
|
||||
|
||||
@@ -214,6 +214,9 @@ void initsprites(stCloneKeenPlus *pCKP, int s);
|
||||
void keen_get_goodie(int px, int py, int theplayer, stCloneKeenPlus *pCKP);
|
||||
void procgoodie(int t, int mpx, int mpy, int theplayer, stCloneKeenPlus *pCKP);
|
||||
|
||||
void recalc_highest_objslot(void);
|
||||
char IsStopPoint(int x, int y, int o);
|
||||
|
||||
void initgame(stCloneKeenPlus *pCKP);
|
||||
int initgamefirsttime(stCloneKeenPlus *pCKP, int s);
|
||||
|
||||
|
||||
@@ -65,6 +65,9 @@ typedef struct stFade
|
||||
#define SCROLLBUF_XSIZE 512
|
||||
#define SCROLLBUF_YSIZE 512
|
||||
#define SCROLLBUF_MEMSIZE ((SCROLLBUF_XSIZE)*(SCROLLBUF_YSIZE+300))
|
||||
#define TILE_W 16
|
||||
#define TILE_H 16
|
||||
#define TILE_S 4
|
||||
#define SCROLLBUF_NUMTILESX (SCROLLBUF_XSIZE / 16)
|
||||
#define SCROLLBUF_NUMTILESY (SCROLLBUF_YSIZE / 16)
|
||||
|
||||
@@ -497,6 +500,7 @@ typedef struct stObject
|
||||
|
||||
unsigned int needinit; // 1=new object--requires initilization
|
||||
unsigned char wasoffscreen; // set to 1 when object goes offscreen
|
||||
bool dead;
|
||||
// data for ai and such, used differently depending on
|
||||
// what kind of object it is
|
||||
union ai
|
||||
@@ -855,7 +859,7 @@ typedef struct stShipQueue
|
||||
|
||||
#include <SDL.h>
|
||||
#include "include/declarations.h"
|
||||
#include "keenext.h"
|
||||
#include "externals.h"
|
||||
#include "sdl/CSettings.h"
|
||||
|
||||
struct stCloneKeenPlus
|
||||
|
||||
@@ -41,7 +41,6 @@
|
||||
#include "include/fileio/story.h"
|
||||
#include "include/main.h"
|
||||
#include "fileio/CParser.h"
|
||||
#include "vorticon/CPlayer.h"
|
||||
#include "vorticon/CHighScores.h"
|
||||
#include "CLogFile.h"
|
||||
#include "CGame.h"
|
||||
@@ -70,7 +69,6 @@ char QuitState = NO_QUIT;
|
||||
stString strings[MAX_STRINGS+1];
|
||||
int numStrings = 0;
|
||||
|
||||
int demomode;
|
||||
FILE *demofile = NULL;
|
||||
|
||||
char ScreenIsScrolling;
|
||||
@@ -87,8 +85,6 @@ extern unsigned char scrollpixy;
|
||||
extern unsigned int mapy;
|
||||
extern unsigned int mapystripepos;
|
||||
|
||||
extern CPlayer *Player;
|
||||
|
||||
char loadinggame, loadslot;
|
||||
|
||||
stFade fade;
|
||||
@@ -548,7 +544,7 @@ gotEOF: ;
|
||||
// initilize some variables
|
||||
demo_RLERunLen = 0;
|
||||
demo_data_index = 0;
|
||||
demomode = DEMO_PLAYBACK;
|
||||
pCKP->Control.levelcontrol.demomode = DEMO_PLAYBACK;
|
||||
loadinggame = 0;
|
||||
p_levelcontrol->curlevel = lvl;
|
||||
p_levelcontrol->command = LVLC_NOCOMMAND;
|
||||
@@ -650,7 +646,7 @@ short readCommandLine(int argc, char *argv[], stCloneKeenPlus *pCKP)
|
||||
}
|
||||
else if (strcmp(tempbuf, "-rec")==0) // record a demo
|
||||
{
|
||||
demomode = DEMO_RECORD;
|
||||
pCKP->Control.levelcontrol.demomode = DEMO_RECORD;
|
||||
}
|
||||
else if (strcmp(tempbuf, "-eseq")==0) // play end sequence
|
||||
{
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
|
||||
#include "../keen.h"
|
||||
#include "../keenext.h"
|
||||
//#include "../externals.h"
|
||||
#include "../MathLib.h"
|
||||
|
||||
#include "CTimer.h"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*/
|
||||
|
||||
#include "../keen.h"
|
||||
#include "../keenext.h"
|
||||
//#include "../externals.h"
|
||||
#include "CVideoDriver.h"
|
||||
#include "../CLogFile.h"
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#include "CPlanes.h"
|
||||
#include "../funcdefs.h"
|
||||
#include "../keen.h"
|
||||
#include "../keenext.h"
|
||||
//#include "../externals.h"
|
||||
#include "../FindFile.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
Reference in New Issue
Block a user