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:
gerstrong
2009-08-02 16:16:00 +00:00
parent 59ce82756c
commit 89dd1e260c
18 changed files with 328 additions and 241 deletions

View File

@@ -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;

View File

@@ -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"

View File

@@ -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
View 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

View File

@@ -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];

View File

@@ -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)

View File

@@ -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

View File

@@ -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])
{

View File

@@ -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

View File

@@ -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);

View File

@@ -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)

View File

@@ -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);

View File

@@ -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

View File

@@ -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
{

View File

@@ -7,7 +7,7 @@
#include "../keen.h"
#include "../keenext.h"
//#include "../externals.h"
#include "../MathLib.h"
#include "CTimer.h"

View File

@@ -3,7 +3,7 @@
*/
#include "../keen.h"
#include "../keenext.h"
//#include "../externals.h"
#include "CVideoDriver.h"
#include "../CLogFile.h"

View File

@@ -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>