void CK6_FlectDraw(CK_object *obj) { // Hit wall walking right; turn around and go left if (obj->xDirection == IN_motion_Right && obj->leftTI != 0) { obj->posX -= obj->deltaPosX; obj->xDirection = IN_motion_Left; obj->timeUntillThink = US_RndT() / 32; CK_SetAction2(obj, obj->currentAction); } // Hit wall walking left; turn around and go right else if (obj->xDirection == IN_motion_Left && obj->rightTI != 0) { obj->posX -= obj->deltaPosX; obj->xDirection = IN_motion_Right; obj->timeUntillThink = US_RndT() / 32; CK_SetAction2(obj, obj->currentAction); } // Walked off of ledge; turn around else if (obj->topTI == 0) { obj->posX -= obj->deltaPosX; obj->xDirection = -obj->xDirection; CK_SetAction2(obj, obj->currentAction); } RF_AddSpriteDraw(&(obj->sde), obj->posX, obj->posY, obj->gfxChunk, false, obj->zLayer); }
void CK6_BloogguardWalk(CK_object *obj) { if (US_RndT() < 0x20) obj->xDirection = obj->posX < ck_keenObj->posX ? IN_motion_Right : IN_motion_Left; if ((obj->xDirection == IN_motion_Right && ck_keenObj->posX > obj->posX) || (obj->xDirection == IN_motion_Left && ck_keenObj->posX < obj->posX)) { if (obj->clipRects.unitY2 == ck_keenObj->clipRects.unitY2) { if (US_RndT() < 0x20) obj->currentAction = CK_GetActionByName("CK6_ACT_BloogguardClub0"); } } }
void UpdateFace() { if (SD_SoundPlaying() == GETGATLINGSND) return; facecount += tics; if (facecount > US_RndT()) { gamestate.faceframe = (US_RndT()>>6); if (gamestate.faceframe==3) gamestate.faceframe = 1; facecount = 0; DrawFace(); }
// Blooglets void CK6_SpawnBlooglet(int tileX, int tileY, int type) { CK_object *obj = CK_GetNewObj(false); obj->type = CT6_Blooglet; obj->active = OBJ_ACTIVE; obj->zLayer = PRIORITIES - 4; obj->posX = RF_TileToUnit(tileX); obj->posY = RF_TileToUnit(tileY) - 0x80; obj->xDirection = US_RndT() < 0x80 ? IN_motion_Right : IN_motion_Left; obj->yDirection = IN_motion_Down; obj->user1 = type; switch (type%4) { case 0: CK_SetAction(obj, CK_GetActionByName("CK6_ACT_BloogletRRun0")); break; case 1: CK_SetAction(obj, CK_GetActionByName("CK6_ACT_BloogletYRun0")); break; case 2: CK_SetAction(obj, CK_GetActionByName("CK6_ACT_BloogletBRun0")); break; case 3: CK_SetAction(obj, CK_GetActionByName("CK6_ACT_BloogletGRun0")); break; } }
//-------------------------------------------------------------------------- // Random() //-------------------------------------------------------------------------- unsigned Random(unsigned Max) { unsigned returnval; if (Max) { if (Max > 255) returnval = (US_RndT()<<8) + US_RndT(); else returnval = US_RndT(); return(returnval % Max); } else return(0); }
uint16_t Random( uint16_t Max) { uint16_t returnval; if (Max) { if (Max > 255) { returnval = (US_RndT() << 8) + US_RndT(); } else { returnval = US_RndT(); } return returnval % Max; } else { return 0; } }
void CK6_BipshipFly(CK_object *obj) { CK_PhysAccelHorz(obj, obj->xDirection, 20); int xdir = obj->xDirection; int ycheck = ck_keenObj->clipRects.unitY2 + 0x100 - obj->clipRects.unitY2; if (ycheck <= 0x200 && ycheck >= 0) { // Fire!! xdir = (ck_keenObj->posX < obj->posX) ? IN_motion_Left : IN_motion_Right; if (obj->xDirection == xdir && US_RndT() < SD_GetSpriteSync() * 2) { SD_PlaySound(SOUND_KEENSHOOT); CK_object *shot = CK_GetNewObj(true); shot->type = CT6_EnemyShot; shot->active = OBJ_EXISTS_ONLY_ONSCREEN; shot->zLayer = PRIORITIES - 3; if (obj->xDirection == IN_motion_Right) { shot->posX = obj->posX + 0x100; shot->velX = 64; } else { shot->posX = obj->posX; shot->velX = -64; } shot->posY = obj->posY + 0xA0; shot->velY = 16; CK_SetAction(shot, CK_GetActionByName("CK6_ACT_BipShot0")); } } int startx = obj->clipRects.tileXmid + 2 * xdir; int y = obj->clipRects.tileY1; uint16_t *tile = CA_TilePtrAtPos(startx, y, 1); for (y; y <= obj->clipRects.tileY2; y++, tile += CA_GetMapWidth()) { if (TI_ForeLeft(*tile) || TI_ForeRight(*tile)) { xdir = -xdir; goto checkTurn; } } // And turn around at ledge-ends if (!TI_ForeTop(*tile)) xdir = -xdir; checkTurn: if (obj->xDirection != xdir) { obj->xDirection = xdir; CK_SetAction2(obj, CK_GetActionByName("CK6_ACT_BipshipTurn0")); } }
void WalkReact (objtype *ob) { if (ob->xdir == 1 && ob->hitwest) { ob->x -= ob->xmove; ob->xdir = -1; ob->nothink = US_RndT()>>5; ChangeState (ob,ob->state); }
void CK6_SpawnBipship(int tileX, int tileY) { CK_object *obj = CK_GetNewObj(false); obj->type = CT6_Bipship; obj->active = OBJ_ACTIVE; obj->posX = RF_TileToUnit(tileX); obj->posY = RF_TileToUnit(tileY) - 0x180; obj->xDirection = US_RndT() < 0x80 ? IN_motion_Right : IN_motion_Left; obj->velX = obj->xDirection * 20; CK_SetAction(obj, CK_GetActionByName("CK6_ACT_BipshipFly0")); }
void CK6_SpawnBloog(int tileX, int tileY) { CK_object *obj = CK_GetNewObj(false); obj->type = CT6_Bloog; obj->active = OBJ_ACTIVE; obj->zLayer = PRIORITIES - 4; obj->posX = RF_TileToUnit(tileX); obj->posY = RF_TileToUnit(tileY) - 0x200; obj->xDirection = US_RndT() < 0x80 ? IN_motion_Right : IN_motion_Left; obj->yDirection = IN_motion_Down; CK_SetAction(obj, CK_GetActionByName("CK6_ACT_BloogWalk0")); }
void CK6_NospikeWalk(CK_object *obj) { if (US_RndT() < 0x10) { obj->currentAction = CK_GetActionByName("CK6_ACT_NospikeSit0"); } else if (obj->clipRects.unitY2 == ck_keenObj->clipRects.unitY2 && US_RndT() <= 0x20) { obj->xDirection = ck_keenObj->posX > obj->posX ? IN_motion_Right : IN_motion_Left; obj->user1 = 0; obj->user2 = 1; if (obj->currentAction == CK_GetActionByName("CK6_ACT_NospikeWalk0")) obj->currentAction = CK_GetActionByName("CK6_ACT_NospikeCharge1"); else if (obj->currentAction == CK_GetActionByName("CK6_ACT_NospikeWalk1")) obj->currentAction = CK_GetActionByName("CK6_ACT_NospikeCharge2"); else if (obj->currentAction == CK_GetActionByName("CK6_ACT_NospikeWalk2")) obj->currentAction = CK_GetActionByName("CK6_ACT_NospikeCharge3"); else if (obj->currentAction == CK_GetActionByName("CK6_ACT_NospikeWalk3")) obj->currentAction = CK_GetActionByName("CK6_ACT_NospikeCharge0"); } }
// Orbatrices void CK6_SpawnOrbatrix(int tileX, int tileY) { CK_object *obj = CK_GetNewObj(false); obj->type = CT6_Orbatrix; obj->active = OBJ_ACTIVE; obj->zLayer = PRIORITIES - 4; obj->posX = RF_TileToUnit(tileX); obj->posY = RF_TileToUnit((tileY)) - 0x180; obj->xDirection = US_RndT() < 0x80 ? IN_motion_Right : IN_motion_Left; obj->yDirection = IN_motion_Down; obj->user4 = 1; CK_SetAction(obj, CK_GetActionByName("CK6_ACT_OrbatrixFloat0")); }
void CK6_OrbatrixFloat(CK_object *obj) { if (US_RndT() < 0x20) { obj->currentAction = CK_GetActionByName("CK6_ACT_OrbatrixUncurl2"); } else if (obj->clipRects.unitY2 == ck_keenObj->clipRects.unitY2) { int dx = ck_keenObj->posX - obj->posX; obj->xDirection = dx < 0 ? IN_motion_Left : IN_motion_Right; if (dx > -0x500 && dx < 0x500) obj->currentAction = CK_GetActionByName("CK6_ACT_OrbatrixCurl0"); } }
void CK6_BipshipCrash(CK_object *obj) { SD_PlaySound(SOUND_BIPSHIPCRASH); // Spawn smoke CK_object *smoke = CK_GetNewObj(true); smoke->type = CT_Friendly; smoke->active = OBJ_ACTIVE; smoke->zLayer = PRIORITIES - 2; smoke->posX = obj->posX; smoke->posY = obj->posY - 0x180; CK_SetAction(smoke, CK_GetActionByName("CK6_ACT_BipshipSmoke0")); smoke->xDirection = US_RndT() < 0x80 ? IN_motion_Right : IN_motion_Left; CK_object *bip = CK_GetNewObj(true); bip->type = CT6_Bip; bip->active = OBJ_ACTIVE; bip->zLayer = PRIORITIES - 4; bip->posX = obj->posX; bip->posY = obj->posY - 0x80; bip->xDirection = US_RndT() < 0x80 ? IN_motion_Right : IN_motion_Left; CK_SetAction(bip, CK_GetActionByName("CK6_ACT_BipStand0")); }
/* ----------------------------------------------------------------------------- Function: Parameters: Returns: Notes: ----------------------------------------------------------------------------- */ PUBLIC void fire_hit( player_t *self ) { entity_t *closest; int dist, d1, n, shot_dist, damage; Sound_StartSound( NULL, 0, CHAN_WEAPON, Sound_RegisterSound( "lsfx/023.wav" ), 1, ATTN_NORM, 0 ); // actually fire dist = 0x7fffffff; closest = NULL; for( n = 0 ; n < NumGuards ; ++n ) { if( Guards[ n ].flags & FL_SHOOTABLE ) // && Guards[n].flags&FL_VISABLE { shot_dist = Point2LineDist( Guards[ n ].x - self->position.origin[ 0 ], Guards[ n ].y - self->position.origin[ 1 ], self->position.angle ); if( shot_dist > (2 * TILEGLOBAL / 3) ) { continue; // miss } d1 = LineLen2Point( Guards[ n ].x - self->position.origin[ 0 ], Guards[ n ].y - self->position.origin[ 1 ], self->position.angle ); if( d1 < 0 || d1 > dist ) { continue; } if( ! Level_CheckLine( Guards[ n ].x, Guards[ n ].y, Player.position.origin[0], Player.position.origin[1], r_world ) ) { //if( ! CheckLine( &Guards[ n ] ) ) continue; // obscured } dist = d1; closest = &Guards[ n ]; } } if( ! closest || dist > TILE2POS( 1 ) ) { return; // missed if further than 1.5 tiles } damage = US_RndT() >> 4; A_DamageActor( closest, damage ); // hit something }
/* ----------------------------------------------------------------------------- Function: Parameters: Returns: Notes: ----------------------------------------------------------------------------- */ PUBLIC void SpawnBoss( enemy_t which, int x, int y ) { entity_t *self; dir4type face; switch( which ) { case en_boss: case en_schabbs: case en_fat: case en_hitler: face = dir4_south; break; case en_fake: case en_gretel: case en_gift: face = dir4_north; break; case en_trans: case en_uber: case en_will: case en_death: case en_angel: case en_spectre: face = dir4_nodir; break; default: face = dir4_nodir; break; } self = SpawnActor( which, x, y, face, r_world ); if( ! self ) { return; } self->state = which == en_spectre ? st_path1 : st_stand; self->speed = SPDPATROL; self->health = starthitpoints[ (int)skill->value ][ which ]; self->ticcount = objstate[ which ][ st_stand ].timeout ? US_RndT() % objstate[ which ][ st_stand ].timeout + 1 : 0; self->flags |= FL_SHOOTABLE | FL_AMBUSH; levelstate.total_monsters++; }
void UpdateFace (void) { // don't make demo depend on sound playback if(demoplayback || demorecord) { if(facetimes > 0) { facetimes--; return; } } else if(SD_SoundPlaying() == GETGATLINGSND) return; facecount += tics; if (facecount > US_RndT()) { gamestate.faceframe = (US_RndT()>>6); if (gamestate.faceframe==3) gamestate.faceframe = 1; facecount = 0; DrawFace (); }
/* ----------------------------------------------------------------------------- Function: Parameters: Returns: Notes: ----------------------------------------------------------------------------- */ PUBLIC void SpawnDeadGuard( enemy_t which, int x, int y ) { entity_t *self; self = SpawnActor( which, x, y, dir4_nodir, r_world ); if( ! self ) { return; } self->state = st_dead; self->speed = 0; self->health = 0; self->ticcount = objstate[ which ][ st_dead ].timeout ? US_RndT() % objstate[ which ][ st_dead ].timeout + 1 : 0; }
/* ----------------------------------------------------------------------------- Function: Parameters: Returns: Notes: ----------------------------------------------------------------------------- */ PUBLIC void SpawnGhosts( enemy_t which, int x, int y ) { entity_t *self; self = SpawnActor( which, x, y, dir4_nodir, r_world ); if( ! self ) { return; } self->state = st_chase1; self->speed = SPDPATROL * 3; self->health = starthitpoints[ (int)skill->value ][ which ]; self->ticcount = objstate[ which ][ st_chase1 ].timeout ? US_RndT() % objstate[ which ][ st_chase1 ].timeout + 1: 0; self->flags |= FL_AMBUSH; levelstate.total_monsters++; }
/* ----------------------------------------------------------------------------- Function: Parameters: Returns: Notes: ----------------------------------------------------------------------------- */ PUBLIC void SpawnPatrol( enemy_t which, int x, int y, int dir ) { entity_t *self; self = SpawnActor( which, x, y, dir, r_world ); if( ! self ) { return; } self->state = st_path1; self->speed = (which == en_dog) ? SPDDOG : SPDPATROL; self->distance = TILEGLOBAL; self->ticcount = objstate[ which ][ st_path1 ].timeout ? US_RndT() % objstate[ which ][ st_path1 ].timeout + 1 : 0; self->flags |= FL_SHOOTABLE; levelstate.total_monsters++; }
void CK6_BipWalk(CK_object *obj) { if (obj->clipRects.unitY2 == ck_keenObj->clipRects.unitY2) { if (ck_keenObj->clipRects.unitX1 - 0x40 < obj->clipRects.unitX2) obj->xDirection = IN_motion_Right; if (ck_keenObj->clipRects.unitX2 + 0x40 > obj->clipRects.unitX1) obj->xDirection = IN_motion_Left; } else { if (US_RndT() < 0x10) { obj->xDirection = -obj->xDirection; obj->currentAction = CK_GetActionByName("CK6_ACT_BipStand0"); } } }
void CK6_FlectWalk(CK_object *obj) { if (ck_keenObj->posX < obj->posX && obj->xDirection == IN_motion_Right) { if (obj->xDirection == IN_motion_Left) obj->currentAction = CK_GetActionByName("CK6_ACT_FlectTurn1"); obj->xDirection = IN_motion_Left; } if (ck_keenObj->posX > obj->posX && obj->xDirection == IN_motion_Left) { if (obj->xDirection == IN_motion_Right) obj->currentAction = CK_GetActionByName("CK6_ACT_FlectTurn1"); obj->xDirection = IN_motion_Right; } if (US_RndT() < 0x20) obj->currentAction = CK_GetActionByName("CK6_ACT_FlectTurn0"); }
/* ----------------------------------------------------------------------------- Function: Parameters: Returns: Notes: ----------------------------------------------------------------------------- */ PUBLIC void SpawnStand( enemy_t which, int x, int y, int dir, LevelData_t *lvl ) { entity_t *self; self = SpawnActor( which, x, y, dir, r_world ); if( ! self ) { return; } self->state = st_stand; self->speed = SPDPATROL; self->ticcount = objstate[ which ][ st_stand ].timeout ? US_RndT() % objstate[ which ][ st_stand ].timeout + 1 : 0; self->flags |= FL_SHOOTABLE; if( lvl->tilemap[ x ][ y ] & AMBUSH_TILE ) { self->flags |= FL_AMBUSH; } levelstate.total_monsters++; }
void CK6_NospikeCharge(CK_object *obj) { if (obj->user1 == 0) { if (((ck_keenObj->clipRects.unitY2 != obj->clipRects.unitY2 || (obj->xDirection == IN_motion_Left && obj->posX < ck_keenObj->posX) || (obj->xDirection == IN_motion_Right && obj->posX > ck_keenObj->posX)) && US_RndT() < 0x8) || !CK_ObjectVisible(obj)) { // Stop charging if nospike gets bored, or goes off screen obj->user2 = 0; if (obj->currentAction == CK_GetActionByName("CK6_ACT_NospikeCharge0")) obj->currentAction = CK_GetActionByName("CK6_ACT_NospikeWalk1"); else if (obj->currentAction == CK_GetActionByName("CK6_ACT_NospikeCharge1")) obj->currentAction = CK_GetActionByName("CK6_ACT_NospikeWalk2"); else if (obj->currentAction == CK_GetActionByName("CK6_ACT_NospikeCharge2")) obj->currentAction = CK_GetActionByName("CK6_ACT_NospikeWalk3"); else if (obj->currentAction == CK_GetActionByName("CK6_ACT_NospikeCharge3")) obj->currentAction = CK_GetActionByName("CK6_ACT_NospikeWalk0"); } } }
*/ void WalkReact (objtype *ob) { if (ob->xdir == 1 && ob->hitwest) { ob->x -= ob->xmove; ob->xdir = -1; ob->nothink = US_RndT()>>5; ChangeState (ob,ob->state); } else if (ob->xdir == -1 && ob->hiteast) { ob->x -= ob->xmove; ob->xdir = 1; ob->nothink = US_RndT()>>5; ChangeState (ob,ob->state); } else if (!ob->hitnorth) { ob->x -= 2*ob->xmove; ob->y -= ob->ymove; ob->xdir = -ob->xdir; ob->nothink = US_RndT()>>5; ChangeState (ob,ob->state); } PLACESPRITE; }
/* ----------------------------------------------------------------------------- Function: Parameters: Returns: Notes: ----------------------------------------------------------------------------- */ PUBLIC void fire_lead( player_t *self ) { entity_t *closest; int damage; int dx, dy, dist; int d1, shot_dist, n; switch( self->weapon ) { case WEAPON_PISTOL: Sound_StartSound( NULL, 0, CHAN_WEAPON, Sound_RegisterSound( "sfx/012.wav" ), 1, ATTN_NORM, 0 ); break; case WEAPON_AUTO: Sound_StartSound( NULL, 0, CHAN_WEAPON, Sound_RegisterSound( "sfx/011.wav" ), 1, ATTN_NORM, 0 ); break; case WEAPON_CHAIN: Sound_StartSound( NULL, 0, CHAN_WEAPON, Sound_RegisterSound( "sfx/013.wav" ), 1, ATTN_NORM, 0 ); break; } self->madenoise = true; dist = 0x7fffffffl; closest = NULL; for( n = 0 ; n < NumGuards; ++n ) { if( Guards[ n ].flags & FL_SHOOTABLE ) // && Guards[n].flags&FL_VISABLE { shot_dist = Point2LineDist( Guards[ n ].x - self->position.origin[ 0 ], Guards[ n ].y - self->position.origin[ 1 ], self->position.angle ); if( shot_dist > (2 * TILEGLOBAL / 3) ) { continue; // miss } d1 = LineLen2Point( Guards[ n ].x - self->position.origin[ 0 ], Guards[ n ].y - self->position.origin[ 1 ], self->position.angle ); if( d1 < 0 || d1 > dist ) { continue; } if( ! Level_CheckLine( Guards[ n ].x, Guards[ n ].y, Player.position.origin[0], Player.position.origin[1], r_world ) ) { //if( ! CheckLine( &Guards[ n ] ) ) continue; // obscured } dist = d1; closest = &Guards[ n ]; } } if( ! closest ) // missed { r_trace_t trace; trace.a = NormalizeAngle( self->position.angle - DEG2FINE( 2 ) + rand() % (DEG2FINE( 4 ) ) ); trace.x = self->position.origin[ 0 ]; trace.y = self->position.origin[ 1 ]; trace.flags = TRACE_BULLET; trace.tile_vis = NULL; R_Trace( &trace, r_world ); if( trace.flags & TRACE_HIT_DOOR ) { Sound_StartSound( NULL, 0, CHAN_AUTO, Sound_RegisterSound( "lsfx/028.wav" ), 1, ATTN_NORM, 0 ); } return; } // hit something dx = ABS( closest->tilex - self->tilex ); dy = ABS( closest->tiley - self->tiley ); dist = max_of_2( dx, dy ); if( dist < 2 ) { damage = US_RndT() / 4; } else if( dist < 4 ) { damage = US_RndT() / 6; } else { if( US_RndT() / 12 < dist ) { return; // missed } damage = US_RndT() / 6; } A_DamageActor( closest, damage ); }
void PlayLoop (void) { int give; int helmetangle; playstate = ex_stillplaying; TimeCount = lasttimecount = 0; frameon = 0; running = False; anglefrac = 0; facecount = 0; funnyticount = 0; memset (buttonstate,0,sizeof(buttonstate)); ClearPaletteShifts (); //if (MousePresent) // PORT //Mouse(MDelta); // Clear accumulated mouse movement if (demoplayback) IN_StartAck (); do { if (virtualreality) { //helmetangle = peek (0x40,0xf0); // PORT player->angle += helmetangle; if (player->angle >= ANGLES) player->angle -= ANGLES; } PollControls(); // // actor thinking // madenoise = False; MoveDoors (); MovePWalls (); for (obj = player;obj;obj = obj->next) DoActor (obj); UpdatePaletteShifts (); ThreeDRefresh (); // // MAKE FUNNY FACE IF BJ DOESN'T MOVE FOR AWHILE // #ifdef SPEAR funnyticount += tics; if (funnyticount > 30l*70) { funnyticount = 0; StatusDrawPic (17,4,BJWAITING1PIC+(US_RndT()&1)); facecount = 0; } #endif gamestate.TimeCount+=tics; SD_Poll (); UpdateSoundLoc(); // JAB if (screenfaded) VW_FadeIn (); CheckKeys(); // // debug aids // if (singlestep) { VW_WaitVBL(14); lasttimecount = TimeCount; } if (extravbls) VW_WaitVBL(extravbls); if (demoplayback) { if (IN_CheckAck ()) { IN_ClearKeysDown (); playstate = ex_abort; } } if (virtualreality) { player->angle -= helmetangle; if (player->angle < 0) player->angle += ANGLES; } }while (!playstate && !startgame); if (playstate != ex_died) FinishPaletteShifts (); }
// Bloogs void CK6_Bloog(CK_object *obj) { if (US_RndT() < 0x20) obj->xDirection = obj->posX < ck_keenObj->posX ? IN_motion_Right : IN_motion_Left; }
void PlayLoop (void) { #if defined(USE_FEATUREFLAGS) && defined(USE_CLOUDSKY) if(GetFeatureFlags() & FF_CLOUDSKY) InitSky(); #endif #ifdef USE_SHADING InitLevelShadeTable(); #endif playstate = ex_stillplaying; lasttimecount = GetTimeCount(); frameon = 0; anglefrac = 0; facecount = 0; funnyticount = 0; memset (buttonstate, 0, sizeof (buttonstate)); ClearPaletteShifts (); if (MousePresent && IN_IsInputGrabbed()) IN_CenterMouse(); // Clear accumulated mouse movement if (demoplayback) IN_StartAck (); do { PollControls (); // // actor thinking // madenoise = false; MoveDoors (); MovePWalls (); for (obj = player; obj; obj = obj->next) DoActor (obj); UpdatePaletteShifts (); ThreeDRefresh (); // // MAKE FUNNY FACE IF BJ DOESN'T MOVE FOR AWHILE // #ifdef SPEAR funnyticount += tics; if (funnyticount > 30l * 70) { funnyticount = 0; if(viewsize != 21) StatusDrawFace(BJWAITING1PIC + (US_RndT () & 1)); facecount = 0; } #endif gamestate.TimeCount += tics; UpdateSoundLoc (); // JAB if (screenfaded) VW_FadeIn (); CheckKeys (); // // debug aids // if (singlestep) { VW_WaitVBL (singlestep); lasttimecount = GetTimeCount(); } if (extravbls) VW_WaitVBL (extravbls); if (demoplayback) { if (IN_CheckAck ()) { IN_ClearKeysDown (); playstate = ex_abort; } } } while (!playstate && !startgame); if (playstate != ex_died) FinishPaletteShifts (); }
void ChaseThink (objtype *obj, id0_boolean_t diagonal) { id0_int_t deltax,deltay/*,i*/; dirtype d[3]; // (REFKEEN) Incrementing/Decrementing an enum is a bad idea (leading to undefined behaviors in C, including "Bad dir" bug reproduced), // and illegal in C++. Hence, tdir is redefined to be a (signed) int here. Casts are done (to be compatible with C++). int tdir; dirtype /*tdir, */olddir, turnaround; olddir=obj->dir; turnaround=opposite[olddir]; deltax=player->tilex - obj->tilex; deltay=player->tiley - obj->tiley; d[1]=nodir; d[2]=nodir; if (deltax>0) d[1]= east; if (deltax<0) d[1]= west; if (deltay>0) d[2]=south; if (deltay<0) d[2]=north; if (abs(deltay)>abs(deltax)) { tdir=(int)d[1]; d[1]=d[2]; d[2]=(dirtype)tdir; } if (d[1]==turnaround) d[1]=nodir; if (d[2]==turnaround) d[2]=nodir; if (diagonal) { /*ramdiagonals try the best dir first*/ if (d[1]!=nodir) { obj->dir=d[1]; if (Walk(obj)) return; /*either moved forward or attacked*/ } if (d[2]!=nodir) { obj->dir=d[2]; if (Walk(obj)) return; } } else { /*ramstraights try the second best dir first*/ if (d[2]!=nodir) { obj->dir=d[2]; if (Walk(obj)) return; } if (d[1]!=nodir) { obj->dir=d[1]; if (Walk(obj)) return; } } /* there is no direct path to the player, so pick another direction */ obj->dir=olddir; if (Walk(obj)) return; if (US_RndT()>128) /*randomly determine direction of search*/ { for (tdir=north;tdir<=west;tdir++) { if (tdir!=(int)turnaround) { obj->dir=(dirtype)tdir; if (Walk(obj)) return; } } } else { for (tdir=west;tdir>=north;tdir--) { if (tdir!=(int)turnaround) { obj->dir=(dirtype)tdir; if (Walk(obj)) return; } } } obj->dir=turnaround; Walk(obj); /*last chance, don't worry about returned value*/ }