// Filename : GOBJECTS.C // Coded by : Scott Evans // Created/Modified : 21/3/98 // Description : Game object routines #include "gobjects.h" // Variables in other modules extern PROGRAM_DATA pd; extern GAME_DATA gd; extern BLOKE_DATA bd; extern BRIGHTNESS default_brightness,brightness[]; extern OBJECT_LIST_HEADER objects_list,wind_objects_list,paused_objects,gun_objects,platform_objects,fan_objects; extern SPRITE_DATA_INFO game_sprites_info,map_blocks_info,font_sprite_info; extern u_byte xplo_animation[],start_block_animation[],bloke_moving_animation[],right_gun_anim[],left_gun_anim[]; extern u_byte spring_up_animation[],spring_down_animation[],spring_left_animation[],spring_right_animation[]; extern u_byte up_fan_anim[],down_fan_anim[],left_fan_anim[],right_fan_anim[]; extern OBJECT *bat,*start_block,*bloke; extern BACKGRND bg; extern FONT_INFO game_font,game_info_font; extern COUNTER *diamond_counter,*block_counter; extern SOUND_DATA *sounds; extern VOLUME game_volume; // Variables for this module // Bat performance settings Velocity Acceleration Max velocity Min velocity PERFORMANCE performances[]={{{1.5*FPN24_8,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}}, {{1.7*FPN24_8,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}}, {{2*FPN24_8,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,0,0,0}}, // Bloke performance Velocity Acceleration Max velocity Min velocity {{0.48*FPN24_8,0,0,0}, {0,0.08*FPN24_8,0,0}, {0,0,0,0}, {0,2*FPN24_8,0,0}}, {{0.57*FPN24_8,0,0,0}, {0,0.12*FPN24_8,0,0}, {0,0,0,0}, {0,2.3*FPN24_8,0,0}}, {{0.7*FPN24_8,0,0,0}, {0,0.15*FPN24_8,0,0}, {0,0,0,0}, {0,3*FPN24_8,0,0}}}; PERFORMANCE pbat,pbloke; // Function : SetPerformanceLevel() // Coded by : Scott Evans // Created/Modified : 21/3/98 // Description : Initialise the performance level // Parameters : p - performance to set // level - the level of performance // Returns : None // Notes : None void SetPerformanceLevel(PERFORMANCE *p,u_byte level) { copyVector(&p->vel,&performances[level].vel); copyVector(&p->acc,&performances[level].acc); copyVector(&p->max_vel,&performances[level].max_vel); copyVector(&p->min_vel,&performances[level].min_vel); } // Function : SetPerformanceLevels() // Coded by : Scott Evans // Created/Modified : 21/3/98 // Description : Initialise a set of performance levels // Parameters : level - the level of performance // Returns : None // Notes : None void SetPerformanceLevels(u_byte level) { SetPerformanceLevel(&pbat,level); SetPerformanceLevel(&pbloke,level+3); #ifdef DEBUG_INFO sprintf(fm_string,"Performance level=%d\n",level); PrintFM(fm_string); #endif } // Function : CreateBatSprite() // Coded by : Scott Evans // Created/Modified : 21/3/98 // Description : Create the bat sprite object // Parameters : None // Returns : Pointer to bat object // Notes : None OBJECT *CreateBatSprite(void) { SPRITE *spr; OBJECT *o=CreateObject(&objects_list,SPRITE_OBJECT); u_word n=BAT_LEFT; if(o) { // Set the sprite data spr=&o->type.s; SetSprite(spr,&game_sprites_info.offsets[0],0,0,0,0); spr->current_frame=n; SetObjectsWidthHeight(o,spr->info[n].w-6,spr->info[n].h); // Set the GsSPRITE data SetGsSPRITE(&spr->s,0,0,0,o->w,o->h, game_sprites_info.tpage,spr->info[n].u,spr->info[n].v, game_sprites_info.cx,game_sprites_info.cy+spr->info[n].clut_y, 0,0,0,0,0,ONE,ONE,0); // Set the object data SetObjectsDefaultProperties(o); SetObjectsBrightness(o,&default_brightness); SetObjectsPosition(o,((GAME_SCREEN_W-o->w)>>1),GAME_SCREEN_H-o->h,0); SetObjectsHandler(o,HandleBatObject); return(o); } #ifdef DEBUG_INFO else PrintFM("Failed\n"); #endif return(0); } // Function : CreateStartBlockSprite() // Coded by : Scott Evans // Created/Modified : 21/3/98 // Description : Create the start block sprite object // Parameters : None // Returns : Pointer to start block object // Notes : None OBJECT *CreateStartBlockSprite(void) { OBJECT *o=CreateObject(&objects_list,SPRITE_OBJECT); SPRITE *spr; u_word n=STARTING_BLOCK_DOWN; if(o) { spr=&o->type.s; SetSprite(spr,&game_sprites_info.offsets[0],4,3,0,&start_block_animation[0]); SetObjectsWidthHeight(o,spr->info[n].w,spr->info[n].h); // Set the GsSPRITE SetGsSPRITE(&spr->s,0,0,0,o->w,o->h, game_sprites_info.tpage,spr->info[n].u,spr->info[n].v, game_sprites_info.cx,game_sprites_info.cy+spr->info[n].clut_y, 0,0,0,0,0,ONE,ONE,0); // Set the object data SetObjectsDefaultProperties(o); SetObjectsBrightness(o,&default_brightness); SetObjectsHandler(o,HandleStartBlockObject); SetObjectsTimer(o,SECOND*5); // Find a position for the stat block PositionStartBlock(o); return(o); } #ifdef DEBUG_INFO else PrintFM("Failed\n"); #endif return(0); } // Function : PositionStartBlock() // Coded by : Scott Evans // Created/Modified : 7/3/98 // Description : Finds a random position for the starting block // Parameters : None // Returns : None // Notes : None void PositionStartBlock(OBJECT *o) { u_word sx,r,c,n=0; word block_no; r=MAX_MAP_SCREEN_ROWS-1; // Could in theory get stuck in this loop, so give it 40 iterations while(n<40) { // Get random screen position sx=(c=(rand()%(GAME_SCREEN_W-o->w))>>4)<<4; block_no=GetMapBlock(&bg,r,c); block_no+=GetMapBlock(&bg,r-1,c); // Check that it is OK to put it here if((sx+o->wscreen.vx || sx>bat->screen.vx+bat->w) && block_no>=(FIRST_BACKGROUND_MAP_BLOCK<<1)) break; n++; } // Could not find a space for start block, so make one if(n==50) CreateExplosionSprite((GAME_SCREEN_H-o->h)>>4,sx>>4,1); // Set the start block at found position SetObjectsPosition(o,sx,GAME_SCREEN_H-o->h,0); o->active=1; o->visible=1; o->allow_fading=1; o->dying=0; o->timer=SECOND*5; o->type.s.current_frame=0; o->type.s.s.attribute=0; } // Function : CreateExplosionSprite() // Coded by : Scott Evans // Created/Modified : 21/3/98 // Description : Create an explosion sprite // Parameters : r,c - position of explosion // sound - play a sound effect // Returns : Pointer to explosion object // Notes : None OBJECT *CreateExplosionSprite(word r,word c,u_byte sound) { PARTICLE_EXPLOSION e; SPRITE *spr; OBJECT *o=CreateObject(&objects_list,SPRITE_OBJECT); u_word blkid,n=EXPLOSION_START; // Did we get a free object if(o) { // Set the sprite spr=&o->type.s; SetSprite(spr,&game_sprites_info.offsets[0],3,11,1,&xplo_animation[0]); SetObjectsWidthHeight(o,spr->info[n].w,spr->info[n].h); // Set the GsSPRITE SetGsSPRITE(&spr->s,TRANSPARENCY_ON|BG_PLUS_SP,0,0,o->w,o->h, game_sprites_info.tpage,spr->info[n].u,spr->info[n].v, game_sprites_info.cx,game_sprites_info.cy+spr->info[n].clut_y, 0,0,0,o->w>>1,o->h>>1,ONE*3,ONE*3,0); // Set the object SetObjectsDefaultProperties(o); SetObjectsPosition(o,(c<<4)+(o->w>>1),(r<<4)+(o->h>>1),0); SetObjectsHandler(o,HandleExplosionObject); SetObjectsTimer(o,100); SetObjectsOtOffset(o,1); StartObjectFading(o); // Initialise particle explosion SetParticleExplosion(&e,&objects_list,HandleExplosionFragment,4,280,3,3,0,0); setVECTOR(&e.maxvel,4,6,0); setVECTOR(&e.acc,0,0.2*FPN24_8,0); if(gd.demo_mode) { SetObjectsBrightness(o,&default_brightness); e.b.r=default_brightness.r; e.b.g=default_brightness.g; e.b.b=default_brightness.b; } else { SetObjectsBrightness(o,&brightness[GAME_MAX_BRIGHTNESS]); e.b.r=brightness[GAME_MAX_BRIGHTNESS].r; e.b.g=brightness[GAME_MAX_BRIGHTNESS].g; e.b.b=brightness[GAME_MAX_BRIGHTNESS].b; } // Clear blocks behind explosion r--; for(n=0;n<3;n++) { if((blkid=GetMapBlock(&bg,r+n,c-1))=bg.area.x) { SetMapBlock(&bg,r+n,c-1,FIRST_BACKGROUND_MAP_BLOCK+2); setRECT(&e.r,(c-1)<<4,(r+n)<<4,16,16); CreateParticleExplosion(&e); // If we have destroyed an up arrow block put another one on screen if(blkid==UP_ARROW_MAP_BLOCK) PositionUpArrowMapBlock(); // If we have hit another explosion block create another explosion if(blkid==EXPLOSION_MAP_BLOCK) CreateExplosionSprite(r+n,c-1,0); // Blown up a diamond if(blkid>=FIRST_DIAMOND_MAP_BLOCK && blkid<=LAST_DIAMOND_MAP_BLOCK) SubtractFromCounter(diamond_counter,1); if(blkid>=FIRST_FAN_MAP_BLOCK && blkid<=LAST_FAN_MAP_BLOCK) { OBJECT *o=FindObjectAtPosition(&fan_objects,r+n,c-1); if(o) { o->dying=1; RemoveObjectFromList(&wind_objects_list,o->type.f.w); RemoveObjectFromList(&fan_objects,o); } } } if((blkid=GetMapBlock(&bg,r+n,c))=bg.area.x) { SetMapBlock(&bg,r+n,c,FIRST_BACKGROUND_MAP_BLOCK); setRECT(&e.r,c<<4,(r+n)<<4,16,16); CreateParticleExplosion(&e); if(blkid==UP_ARROW_MAP_BLOCK) PositionUpArrowMapBlock(); if(blkid==EXPLOSION_MAP_BLOCK) CreateExplosionSprite(r+n,c,0); if(blkid>=FIRST_DIAMOND_MAP_BLOCK && blkid<=LAST_DIAMOND_MAP_BLOCK) SubtractFromCounter(diamond_counter,1); if(blkid>=FIRST_FAN_MAP_BLOCK && blkid<=LAST_FAN_MAP_BLOCK) { OBJECT *o=FindObjectAtPosition(&fan_objects,r+n,c); if(o) { o->dying=1; RemoveObjectFromList(&wind_objects_list,o->type.f.w); RemoveObjectFromList(&fan_objects,o); } } } if((blkid=GetMapBlock(&bg,r+n,c+1))=bg.area.x) { SetMapBlock(&bg,r+n,c+1,FIRST_BACKGROUND_MAP_BLOCK+1); setRECT(&e.r,(c+1)<<4,(r+n)<<4,16,16); CreateParticleExplosion(&e); if(blkid==UP_ARROW_MAP_BLOCK) PositionUpArrowMapBlock(); if(blkid==EXPLOSION_MAP_BLOCK) CreateExplosionSprite(r+n,c+1,0); if(blkid>=FIRST_DIAMOND_MAP_BLOCK && blkid<=LAST_DIAMOND_MAP_BLOCK) SubtractFromCounter(diamond_counter,1); if(blkid>=FIRST_FAN_MAP_BLOCK && blkid<=LAST_FAN_MAP_BLOCK) { OBJECT *o=FindObjectAtPosition(&fan_objects,r+n,c+1); if(o) { o->dying=1; RemoveObjectFromList(&wind_objects_list,o->type.f.w); RemoveObjectFromList(&fan_objects,o); } } } } if(sound) PlaySoundEffect(sounds,&game_volume,SFX_EXPLOSION); return(o); } #ifdef DEBUG_INFO else PrintFM("Failed\n"); #endif return(0); } // Function : CreateExplosionSprite2() // Coded by : Scott Evans // Created/Modified : 5/4/98 // Description : Create an explosion sprite, when a bullet hits an object // Parameters : r,c - position of explosion // Returns : Pointer to explosion object // Notes : None OBJECT *CreateExplosionSprite2(word r,word c) { PARTICLE_EXPLOSION e; SPRITE *spr; OBJECT *gun,*o=CreateObject(&objects_list,SPRITE_OBJECT); u_word blkid,n=EXPLOSION_START; // Did we get a free object if(o) { // Set the sprite spr=&o->type.s; SetSprite(spr,&game_sprites_info.offsets[0],3,11,1,&xplo_animation[0]); SetObjectsWidthHeight(o,spr->info[n].w,spr->info[n].h); // Set the GsSPRITE SetGsSPRITE(&spr->s,TRANSPARENCY_ON|BG_PLUS_SP,0,0,o->w,o->h, game_sprites_info.tpage,spr->info[n].u,spr->info[n].v, game_sprites_info.cx,game_sprites_info.cy+spr->info[n].clut_y, 0,0,0,o->w>>1,o->h>>1,ONE,ONE,0); // Set the object SetObjectsDefaultProperties(o); SetObjectsPosition(o,(c<<4)+(o->w>>1),(r<<4)+(o->h>>1),0); SetObjectsHandler(o,HandleExplosionObject); SetObjectsTimer(o,100); SetObjectsOtOffset(o,2); StartObjectFading(o); if(gd.demo_mode) { SetObjectsBrightness(o,&default_brightness); e.b.r=default_brightness.r; e.b.g=default_brightness.g; e.b.b=default_brightness.b; } else { SetObjectsBrightness(o,&brightness[GAME_MAX_BRIGHTNESS]); e.b.r=brightness[GAME_MAX_BRIGHTNESS].r; e.b.g=brightness[GAME_MAX_BRIGHTNESS].g; e.b.b=brightness[GAME_MAX_BRIGHTNESS].b; } // Initialise particle explosion SetParticleExplosion(&e,&objects_list,HandleExplosionFragment,4,280,3,3,0,0); setVECTOR(&e.maxvel,4,6,0); setVECTOR(&e.acc,0,0.2*FPN24_8,0); // If there is a block here, create a few fragments if((blkid=GetMapBlock(&bg,r,c))=bg.area.x) { SetMapBlock(&bg,r,c,FIRST_BACKGROUND_MAP_BLOCK+2); setRECT(&e.r,c<<4,r<<4,16,16); CreateParticleExplosion(&e); // Which type of block was destroyed switch(blkid) { case UP_ARROW_MAP_BLOCK: PositionUpArrowMapBlock(); break; case EXPLOSION_MAP_BLOCK: CreateExplosionSprite(r,c,1); break; case GUN_FACING_LEFT_MAP_BLOCK+2: case GUN_FACING_RIGHT_MAP_BLOCK+2: if((gun=FindObjectAtPosition(&gun_objects,r,c))) { gun->dying=1; RemoveObjectFromList(&gun_objects,gun); } break; } if(blkid>=FIRST_DIAMOND_MAP_BLOCK && blkid<=LAST_DIAMOND_MAP_BLOCK) SubtractFromCounter(diamond_counter,1); } PlaySoundEffect(sounds,&game_volume,SFX_EXPLOSION); return(o); } #ifdef DEBUG_INFO PrintFM("Failed\n"); #endif return(0); } // Function : CreateBlokeSprite() // Coded by : Scott Evans // Created/Modified : 21/3/98 // Description : Create the bloke sprite object // Parameters : None // Returns : Pointer to bloke object // Notes : None OBJECT *CreateBlokeSprite(void) { OBJECT *o=CreateObject(&objects_list,SPRITE_OBJECT); SPRITE *spr; u_word n=BLOKE_STANDING_STILL; if(o) { spr=&o->type.s; SetSprite(spr,&game_sprites_info.offsets[0],5,5,0,&bloke_moving_animation[0]); SetObjectsWidthHeight(o,spr->info[n].w,spr->info[n].h); // Set the GsSPRITE SetGsSPRITE(&spr->s,0,0,0,o->w,o->h, game_sprites_info.tpage,spr->info[n].u,spr->info[n].v, game_sprites_info.cx,game_sprites_info.cy+spr->info[n].clut_y, 0,0,0,0,0,ONE,ONE,0); // Set the object data SetObjectsDefaultProperties(o); SetObjectsBrightness(o,&default_brightness); SetObjectsHandler(o,HandleBlokeObject); SetObjectsBoundingBox(o,0,0,BLOKE_BOUNDING_BOX_WIDTH,BLOKE_BOUNDING_BOX_HEIGHT); o->direction=0; o->extra[0]=0; o->parent=0; bd.beam_timer=0; bd.beam=0; return(o); } #ifdef DEBUG_INFO else PrintFM("Failed\n"); #endif return(0); } // Function : CreateBlockSprite() // Coded by : Scott Evans // Created/Modified : 22/3/98 // Description : Move a hit block off screen // Parameters : r,c - position in map // b - ID of hit block // Returns : Pointer to created object // Notes : None OBJECT *CreateBlockSprite(word r,word c,word b) { static long block_vx[]={2*FPN24_8,2.5*FPN24_8,2.8*FPN24_8,3*FPN24_8,3.2*FPN24_8,3.5*FPN24_8}; OBJECT *o=CreateObject(&objects_list,SPRITE_OBJECT); SPRITE *spr; if(o) { if(b>=FIRST_DIAMOND_MAP_BLOCK && b<=LAST_DIAMOND_MAP_BLOCK) { b=HIT_DIAMOND_SPRITE; SubtractFromCounter(diamond_counter,1); PlaySoundEffect(sounds,&game_volume,SFX_HIT_DIAMOND); } // Set the sprite spr=&o->type.s; spr->info=&map_blocks_info.offsets[0]; spr->current_frame=b; spr->animation_on=0; SetObjectsWidthHeight(o,map_blocks_info.offsets[b].w,map_blocks_info.offsets[b].h); SetGsSPRITE(&spr->s,TRANSPARENCY_ON|BG_PLUS_SP,0,0,o->w,o->h, map_blocks_info.tpage,spr->info[b].u,spr->info[b].v, map_blocks_info.cx,map_blocks_info.cy+spr->info[b].clut_y, 0,0,0,o->w>>1,o->h>>1,ONE,ONE,0); // Set the object SetObjectsDefaultProperties(o); SetObjectsHandler(o,HandleBlockObject); SetObjectsTimer(o,50); SetObjectsPosition(o,((c<<4)+(o->w>>1))+2,((r<<4)+(o->h>>1)),0); if(gd.demo_mode) SetObjectsBrightness(o,&default_brightness); else SetObjectsBrightness(o,&brightness[GAME_MAX_BRIGHTNESS]); o->extra[0]=0; o->extra[1]=1; if(b!=HIT_DIAMOND_SPRITE) { SetObjectsTimer(o,200); if(gd.bonus_level || gd.demo_mode || b>=FIRST_EFFECTS_BLOCK) { o->extra[0]=1; SetObjectsVelocity(o,0,-((rand()%4)+3),0); o->velocity.vx=block_vx[rand()%6]; SetObjectsAcceleration(o,0,0.4,0); if(bloke->velocity.vx<0) o->velocity.vx=-block_vx[rand()%6]; } } else SetObjectsPosition(o,(c<<4)+11,(r<<4)+7,0); return(o); } #ifdef DEBUG_INFO else PrintFM("Failed\n"); #endif return(0); } // Function : CreateBonusSprite() // Coded by : Scott Evans // Created/Modified : 22/3/98 // Description : Create a bonus // Parameters : r,c - position in map // Returns : Pointer to created object // Notes : None OBJECT *CreateBonusSprite(word x,word y,word n) { OBJECT *o=CreateObject(&objects_list,GsSPRITE_OBJECT); if(o) { // Set object stuff SetObjectsDefaultProperties(o); SetObjectsHandler(o,HandleBonusObject); SetObjectsTimer(o,2); SetObjectsWidthHeight(o,game_sprites_info.offsets[n].w,game_sprites_info.offsets[n].h); SetObjectsOtOffset(o,1); StartObjectFading(o); // Set the sprite SetGsSPRITE(&o->type.gss,TRANSPARENCY_ON|BG_PLUS_SP,0,0,o->w,o->h, game_sprites_info.tpage,game_sprites_info.offsets[n].u,game_sprites_info.offsets[n].v, game_sprites_info.cx,game_sprites_info.cy+game_sprites_info.offsets[n].clut_y, 0,0,0,o->w>>1,o->h>>1,ONE,ONE,0); if(gd.demo_mode || gd.bonus_type==BT_CATCH) SetObjectsBrightness(o,&default_brightness); else SetObjectsBrightness(o,&brightness[GAME_MAX_BRIGHTNESS]); SetObjectsPosition(o,x+(o->w>>1),y+(o->h>>1),0); SetObjectsVelocity(o,0,2,0); // Use this to identify bonus when collected o->direction=n; o->tmp=0; o->extra[0]=0; return(o); } #ifdef DEBUG_INFO else PrintFM("Failed\n"); #endif return(0); } // Function : CreateExpandingBlock() // Coded by : Scott Evans // Created/Modified : 22/3/98 // Description : The effect when hit an expanding block // Parameters : r,c - position in map // Returns : Pointer to created object // Notes : None OBJECT *CreateExpandingBlock(word r,word c) { OBJECT *o=CreateObject(&objects_list,GsBOXF_OBJECT); word i,block_no; r--; block_no=FIRST_DESTRUCTIBLE_MAP_BLOCK+(rand()%NUMBER_NORMAL_MAP_BLOCKS); // Replace surrounding blocks if empty for(i=0;i<3;i++) { if(GetMapBlock(&bg,r+i,c)>=FIRST_BACKGROUND_MAP_BLOCK) SetMapBlock(&bg,r+i,c,block_no); if(GetMapBlock(&bg,r+i,c+1)>=FIRST_BACKGROUND_MAP_BLOCK) SetMapBlock(&bg,r+i,c+1,block_no); if(GetMapBlock(&bg,r+i,c-1)>=FIRST_BACKGROUND_MAP_BLOCK) SetMapBlock(&bg,r+i,c-1,block_no); } if(o) { // Set the object SetObjectsDefaultProperties(o); SetObjectsTimer(o,28); SetObjectsWidthHeight(o,48,48); SetObjectsHandler(o,HandleExpandingBlock); StartObjectFading(o); o->type.gsbf.attribute=TRANSPARENCY_ON|HALF_BG_PLUS_HALF_SP; if(gd.demo_mode) SetObjectsBrightness(o,&default_brightness); else SetObjectsBrightness(o,&brightness[GAME_EFFECTS_BRIGHTNESS+(rand()%5)]); SetObjectsPosition(o,(c-1)<<4,r<<4,0); PlaySoundEffect(sounds,&game_volume,SFX_EXPANDING_BLOCK); return(o); } #ifdef DEBUG_INFO else PrintFM("Failed\n"); #endif return(0); } // Function : CreateDecoyBloke() // Coded by : Scott Evans // Created/Modified : 22/3/98 // Description : Create another bloke who acts as a decoy // Parameters : None // Returns : Pointer to created object // Notes : None void CreateDecoyBloke(u_word m) { OBJECT *o; SPRITE *spr; word n; if(start_block->dying && !bloke->dying) { while(m) { if((o=CreateObject(&objects_list,SPRITE_OBJECT))) { // Create another bloke n=BLOKE_MOVING_START; spr=&o->type.s; SetSprite(spr,&game_sprites_info.offsets[0],5,5,0,&bloke_moving_animation[0]); SetObjectsDefaultProperties(o); SetObjectsWidthHeight(o,game_sprites_info.offsets[n].w,game_sprites_info.offsets[n].h); SetObjectsHandler(o,HandleBlokeObject); SetObjectsTimer(o,SECOND*10); SetGsSPRITE(&spr->s,0,0,0,o->w,o->h, game_sprites_info.tpage,spr->info[n].u,spr->info[n].v, game_sprites_info.cx,game_sprites_info.cy+spr->info[n].clut_y, 0,0,0,0,0,ONE,ONE,0); SetObjectsPosition(o,bloke->screen.vx,bloke->screen.vy,0); if(gd.demo_mode) SetObjectsBrightness(o,&default_brightness); else SetObjectsBrightness(o,&brightness[GAME_DECOY_BRIGHTNESS]); spr->animation_on=1; // Move him in the opposite direction if(m%2) o->velocity.vx=-bloke->velocity.vx; else o->velocity.vx=bloke->velocity.vx; o->velocity.vy=0; o->acceleration.vx=-bloke->acceleration.vx; o->acceleration.vy=bloke->acceleration.vy; o->parent=bloke; o->wind_effect=1; o->direction=0; o->extra[0]=0; SetObjectsBoundingBox(o,0,0,BLOKE_BOUNDING_BOX_WIDTH,BLOKE_BOUNDING_BOX_HEIGHT); m--; } #ifdef DEBUG_INFO else PrintFM("Failed\n"); #endif } PlaySoundEffect(sounds,&game_volume,SFX_SPLIT_BLOKE); } } // Function : CreateSpringSprite() // Coded by : Scott Evans // Created/Modified : 22/3/98 // Description : Create a spring // Parameters : None // Returns : Pointer to created object // Notes : None #if 0 OBJECT *CreateSpringSprite(word n,word r,word c) { OBJECT *o=CreateObject(&objects_list,SPRITE_OBJECT); SPRITE *spr; if(o) { // Create a spring sprite spr=&o->type.s; SetSprite(spr,&map_blocks_info.offsets[0],5,3,0,0); SetObjectsDefaultProperties(o); SetObjectsHandler(o,HandleSpringObject); SetObjectsWidthHeight(o,map_blocks_info.offsets[n].w,map_blocks_info.offsets[n].h); SetGsSPRITE(&spr->s,0,0,0,o->w,o->h, map_blocks_info.tpage,spr->info[n].u,spr->info[n].v, map_blocks_info.cx,map_blocks_info.cy+spr->info[n].clut_y, 0,0,0,0,0,ONE,ONE,0); SetObjectsPosition(o,c<<4,r<<4,0); // If the level is being faded up new objects should also fade up if(bg.block->is_fading) SetObjectsBrightness(o,&brightness[GAME_MIN_BRIGHTNESS]); else SetObjectsBrightness(o,&default_brightness); switch(n) { case SPRING_FACING_UP_MAP_BLOCK: o->direction=FACING_UP; spr->frames_list=&spring_up_animation[0]; SetObjectsBoundingBox(o,o->screen.vx,o->screen.vy+8,o->w,8); break; case SPRING_FACING_DOWN_MAP_BLOCK: o->direction=FACING_DOWN; spr->frames_list=&spring_down_animation[0]; o->screen.vy-=2; o->position.vy=o->screen.vy<screen.vx,o->screen.vy,o->w,8); break; case SPRING_FACING_LEFT_MAP_BLOCK: o->direction=FACING_LEFT; spr->frames_list=&spring_left_animation[0]; o->screen.vx-=2; o->position.vx=o->screen.vx<screen.vx,o->screen.vy,8,o->w); break; case SPRING_FACING_RIGHT_MAP_BLOCK: o->direction=FACING_RIGHT; spr->frames_list=&spring_right_animation[0]; SetObjectsBoundingBox(o,o->screen.vx+8,o->screen.vy,8,o->w); break; } // Keep track of the springs created gd.no_springs++; return(o); } else printf("CreateSpringSprite : Failed\n"); return(0); } #endif // Function : CreateGunSprite() // Coded by : Scott Evans // Created/Modified : 4/4/98 // Description : Create a gun // Parameters : n - texture number of gun // r,c - map position for gun // Returns : Pointer to created object // Notes : None OBJECT *CreateGunSprite(word n,word r,word c) { OBJECT *o=CreateObject(&gun_objects,GUN_OBJECT); SPRITE *spr; if(o) { o->type.g.just_fired=0; o->type.g.bullet=0; spr=&o->type.g.s; SetSprite(spr,&map_blocks_info.offsets[0],5,4,0,0); SetObjectsDefaultProperties(o); SetObjectsHandler(o,HandleGunObject); SetObjectsWidthHeight(o,map_blocks_info.offsets[n].w,map_blocks_info.offsets[n].h); SetGsSPRITE(&spr->s,0,0,0,o->w,o->h, map_blocks_info.tpage,spr->info[n].u,spr->info[n].v, map_blocks_info.cx,map_blocks_info.cy+spr->info[n].clut_y, 0,0,0,0,0,ONE,ONE,0); SetObjectsPosition(o,c<<4,r<<4,0); switch(n) { case GUN_FACING_LEFT_MAP_BLOCK+2: o->direction=FACING_LEFT; o->screen.vx-=2; o->position.vx=o->screen.vx<frames_list=&left_gun_anim[0]; break; case GUN_FACING_RIGHT_MAP_BLOCK+2: o->direction=FACING_RIGHT; spr->frames_list=&right_gun_anim[0]; break; } // If the level is being faded up new objects should also fade up if(bg.block->is_fading) SetObjectsBrightness(o,&brightness[GAME_MIN_BRIGHTNESS]); else SetObjectsBrightness(o,&default_brightness); #ifdef DEBUG_INFO PrintFM("Completed\n"); #endif return(o); } #ifdef DEBUG_INFO PrintFM("Failed\n"); #endif return(0); } // Function : PositionUpArrowMapBlock() // Coded by : Scott Evans // Created/Modified : 4/4/98 // Description : Moves the up arrow block when destroyed // Parameters : None // Returns : None // Notes : None void PositionUpArrowMapBlock(void) { OBJECT *o; PARTICLE_EXPLOSION e; word n=0,x,y; // Not at top yet if(bg.yoff) { if((o=CreateObject(&objects_list,GsBOXF_OBJECT))) { // Find an empty space for another up arrow do { x=rand()%(GAME_SCREEN_W-bg.bw); y=rand()%(GAME_SCREEN_H-bg.bh); n++; } while(y>>4>bg.area.h-3 || GetMapBlock(&bg,y>>4,x>>4)>4,x>>4,UP_ARROW_MAP_BLOCK); // Create a few fragments SetParticleExplosion(&e,&objects_list,HandleExplosionFragment,6,280,1,1,0,0); setVECTOR(&e.maxvel,1,2,0); setVECTOR(&e.acc,0,0.1*FPN24_8,0); setRECT(&e.r,x,y,bg.bw,bg.bh); if(gd.demo_mode) { e.b.r=0x0; e.b.g=0x30<type.gsbf.attribute=TRANSPARENCY_ON|BG_PLUS_SP; if(gd.demo_mode) SetObjectsBrightness(o,&default_brightness); else SetObjectsBrightness(o,&brightness[GAME_UP_BLOCK_BRIGHTNESS]); SetObjectsPosition(o,(x>>4)<<4,(y>>4)<<4,0); } } } } // Function : CreateCounterSprite() // Coded by : Scott Evans // Created/Modified : 18/4/98 // Description : Create a sprite used as a counter // Parameters : l - object list // x,y - position of sprite // Returns : Pointer to created object // Notes : None OBJECT *CreateCounterSprite(OBJECT_LIST_HEADER *l,word x,word y) { OBJECT *o=CreateObject(l,GsSPRITE_OBJECT); GsSPRITE *spr; word n; // Did we get a new object if(o) { // Set the object stuff SetObjectsDefaultProperties(o); SetObjectsPosition(o,x,y,0); n=MapCharacterToImage("0"); spr=&o->type.gss; SetObjectsWidthHeight(o,font_sprite_info.offsets[n].w,font_sprite_info.offsets[n].h); // Define the sprite SetGsSPRITE(spr,0,0,0,o->w,o->h, font_sprite_info.tpage,font_sprite_info.offsets[n].u,font_sprite_info.offsets[n].v, font_sprite_info.cx,font_sprite_info.cy+font_sprite_info.offsets[n].clut_y, 0,0,0,0,0,ONE,ONE,0); o->type.gss.attribute=TRANSPARENCY_ON|BG_PLUS_SP; SetObjectsBrightness(o,&brightness[GAME_WHITE_BRIGHTNESS]); return(o); } #ifdef DEBUG_INFO PrintFM("Failed\n"); #endif return(0); } // Function : CreateMovingPlatformSprite() // Coded by : Scott Evans // Created/Modified : 18/4/98 // Description : Create a sprite used for the moving platforms // Parameters : r,c - map position of sprite // Returns : Pointer to created object // Notes : None OBJECT *CreateMovingPlatformSprite(word r,word c) { OBJECT *o=CreateObject(&platform_objects,GsSPRITE_OBJECT); GsSPRITE *spr; word n=MOVING_PLATFORM_SPRITE; if(o) { spr=&o->type.gss; SetObjectsDefaultProperties(o); SetObjectsHandler(o,HandleMovingPlatformObject); SetObjectsWidthHeight(o,map_blocks_info.offsets[n].w,map_blocks_info.offsets[n].h); o->direction=FACING_LEFT; SetGsSPRITE(spr,0,0,0,o->w,o->h, map_blocks_info.tpage,map_blocks_info.offsets[n].u,map_blocks_info.offsets[n].v, map_blocks_info.cx,map_blocks_info.cy+map_blocks_info.offsets[n].clut_y, 0,0,0,0,0,ONE,ONE,0); SetObjectsPosition(o,(c<<4)+bg.bw,r<<4,0); SetObjectsVelocity(o,1,0,0); if(bg.block->is_fading) SetObjectsBrightness(o,&brightness[GAME_MIN_BRIGHTNESS]); else SetObjectsBrightness(o,&default_brightness); SetObjectsBoundingBox(o,o->screen.vx,o->screen.vy,o->w,o->h); #ifdef DEBUG_INFO PrintFM("Completed\n"); #endif return(o); } #ifdef DEBUG_INFO PrintFM("Failed\n"); #endif return(0); } // Function : CreateFanSprite() // Coded by : Scott Evans // Created/Modified : 18/4/98 // Description : Create a sprite used for the fans // Parameters : n - texture number for fan // r,c - map position of sprite // Returns : Pointer to created object // Notes : None OBJECT *CreateFanSprite(word n,word r,word c) { // Velocities for different strength winds static VECTOR wvel[MAX_WIND_STRENGTHS]={{3*FPN24_8,3*FPN24_8,0},{4.5*FPN24_8,4.5*FPN24_8,0},{6*FPN24_8,6*FPN24_8,0}, {7.5*FPN24_8,7.5*FPN24_8,0},{9*FPN24_8,9*FPN24_8,0}}; OBJECT *o=CreateObject(&fan_objects,FAN_OBJECT); OBJECT *wind; SPRITE *spr; VECTOR vel; word x,y,w,h,wind_strength; if(o) { o->type.f.in_reverse=0; spr=&o->type.f.s; SetSprite(spr,&map_blocks_info.offsets[0],3,8,1,0); // Object stuff SetObjectsDefaultProperties(o); SetObjectsHandler(o,HandleFanObject); SetObjectsWidthHeight(o,map_blocks_info.offsets[n].w,map_blocks_info.offsets[n].h); // Sprite stuff SetGsSPRITE(&spr->s,0,0,0,o->w,o->h, map_blocks_info.tpage,spr->info[n].u,spr->info[n].v, map_blocks_info.cx,map_blocks_info.cy+spr->info[n].clut_y, 0,0,0,0,0,ONE,ONE,0); SetObjectsPosition(o,c<<4,r<<4,0); // Default area for wind to be effective w=h=32; // Which way is the fan blowing switch(n) { case FAN_FACING_LEFT_MAP_BLOCK: case FAN_FACING_LEFT_MAP_BLOCK+1: case FAN_FACING_LEFT_MAP_BLOCK+2: case FAN_FACING_LEFT_MAP_BLOCK+3: case FAN_FACING_LEFT_MAP_BLOCK+4: o->direction=FACING_LEFT; o->screen.vx-=1; o->position.vx=o->screen.vx<frames_list=&left_fan_anim[0]; x=(c<<4)+o->w; y=(r<<4)-6; wind_strength=n-FAN_FACING_LEFT_MAP_BLOCK; spr->frame_rate=5-wind_strength; w+=(wind_strength*20); vel.vx=wvel[wind_strength].vx; vel.vy=0; break; case FAN_FACING_RIGHT_MAP_BLOCK: case FAN_FACING_RIGHT_MAP_BLOCK+1: case FAN_FACING_RIGHT_MAP_BLOCK+2: case FAN_FACING_RIGHT_MAP_BLOCK+3: case FAN_FACING_RIGHT_MAP_BLOCK+4: o->direction=FACING_RIGHT; spr->frames_list=&right_fan_anim[0]; wind_strength=n-FAN_FACING_RIGHT_MAP_BLOCK; spr->frame_rate=5-wind_strength; w+=(wind_strength*20); x=(c<<4)-w; y=(r<<4)-6; vel.vx=-wvel[wind_strength].vx; vel.vy=0; break; case FAN_FACING_UP_MAP_BLOCK: case FAN_FACING_UP_MAP_BLOCK+1: case FAN_FACING_UP_MAP_BLOCK+2: case FAN_FACING_UP_MAP_BLOCK+3: case FAN_FACING_UP_MAP_BLOCK+4: o->direction=FACING_UP; spr->frames_list=&up_fan_anim[0]; wind_strength=n-FAN_FACING_UP_MAP_BLOCK; spr->frame_rate=5-wind_strength; h+=(wind_strength*20); x=(c<<4)-6; y=(r<<4)-h; vel.vx=0; vel.vy=-wvel[wind_strength].vy; break; case FAN_FACING_DOWN_MAP_BLOCK: case FAN_FACING_DOWN_MAP_BLOCK+1: case FAN_FACING_DOWN_MAP_BLOCK+2: case FAN_FACING_DOWN_MAP_BLOCK+3: case FAN_FACING_DOWN_MAP_BLOCK+4: o->direction=FACING_DOWN; o->screen.vy-=1; o->position.vy=o->screen.vy<frames_list=&down_fan_anim[0]; wind_strength=n-FAN_FACING_UP_MAP_BLOCK; spr->frame_rate=5-wind_strength; x=(c<<4)-6; y=(r<<4)+o->h; h+=(wind_strength*20); vel.vx=0; vel.vy=wvel[n-FAN_FACING_UP_MAP_BLOCK].vy; break; } // Create a virtual wind for the fan wind=CreateObject(&wind_objects_list,WIND_OBJECT); if(wind) { VIRTUAL_WIND *vwind=&wind->type.w; // Assign a wind to a fan o->type.f.w=wind; SetObjectsPosition(wind,x,y,0); wind->w=w; wind->h=h; wind->type.w.velocity.vx=vel.vx; wind->type.w.velocity.vy=vel.vy; wind->type.w.velocity.vz=0; // Start the wind blowing wind->type.w.blowing=1; switch(o->direction) { case FACING_UP: case FACING_DOWN: SetAirResistance(vwind,0,0.04,0); break; case FACING_LEFT: case FACING_RIGHT: SetAirResistance(vwind,0.03,0.02,0); break; } } // If the level is being faded up new objects should also fade up if(bg.block->is_fading) SetObjectsBrightness(o,&brightness[GAME_MIN_BRIGHTNESS]); else SetObjectsBrightness(o,&default_brightness); #ifdef DEBUG_INFO PrintFM("Completed\n"); #endif return(o); } #ifdef DEBUG_INFO PrintFM("Failed\n"); #endif return(0); } // Function : CreatePausedSprites() // Coded by : Scott Evans // Created/Modified : 14/4/98 // Description : Create the paused message // Parameters : None // Returns : Pointer to object string // Notes : None OBJECT_STRING *CreatePausedSprites(void) { static OBJECT_STRING paused_string; VECTOR pos={0,-50,0}; OBJECT *o; static u_byte *s="Paused"; u_byte i; // Create objects in a different list, so they can be updated when the game is paused game_font.list=&paused_objects; pos.vx=(GAME_SCREEN_W-(game_font.cw*strlen(s)))>>1; PrintString(s,&game_font,&pos,&paused_string); // Reset the objects for(o=paused_string.start,i=0;iallow_fading=0; SetObjectsHandler(o,HandlePausedObject); SetObjectsAcceleration(o,0,0.2,0); o->active=1; o->tmp=0; o=o->next; } game_font.list=&objects_list; return(&paused_string); } // Function : CreateScoreMultiplier() // Coded by : Scott Evans // Created/Modified : 14/4/98 // Description : Create the little sprite which goes along side the score // Parameters : n - texture number // Returns : Pointer to object // Notes : None OBJECT *CreateScoreMultiplier(word n) { OBJECT *o; word x,y; // Is there one already active if(!gd.multiplier_sprite) { o=CreateObject(&objects_list,GsSPRITE_OBJECT); if(o) { gd.multiplier_sprite=o; SetObjectsDefaultProperties(o); SetObjectsHandler(o,HandleScoreMultiplierObject); SetObjectsTimer(o,SECOND*5); SetObjectsWidthHeight(o,game_sprites_info.offsets[n].w,game_sprites_info.offsets[n].h); SetObjectsOtOffset(o,1); StartObjectFading(o); // Set the sprite SetGsSPRITE(&o->type.gss,TRANSPARENCY_ON|BG_PLUS_SP,0,0,o->w,o->h, game_sprites_info.tpage,game_sprites_info.offsets[n].u,game_sprites_info.offsets[n].v, game_sprites_info.cx,game_sprites_info.cy+game_sprites_info.offsets[n].clut_y, 0,0,0,0,0,ONE*2,ONE*2,0); SetObjectsBrightness(o,&brightness[GAME_MIN_BRIGHTNESS]); x=SCORE_POS_X+((NO_SCORE_DIGITS-1)<<3)+10; y=SCORE_POS_Y-2; SetObjectsPosition(o,x,y,0); return(o); } } #ifdef DEBUG_INFO PrintFM("Failed\n"); #endif return(0); } // Function : CreateIconSprite() // Coded by : Scott Evans // Created/Modified : 14/4/98 // Description : Create an icon // Parameters : l - pointer to list // x,y - screen position of icon // n - texture number to use for icon // Returns : Pointer to object // Notes : None OBJECT *CreateIconSprite(OBJECT_LIST_HEADER *l,word x,word y,word n) { OBJECT *o=CreateObject(l,GsSPRITE_OBJECT); // Set the new object if(o) { SetObjectsDefaultProperties(o); SetObjectsWidthHeight(o,game_sprites_info.offsets[n].w,game_sprites_info.offsets[n].h); SetObjectsOtOffset(o,1); o->allow_fading=0; // Set the sprite SetGsSPRITE(&o->type.gss,TRANSPARENCY_ON|BG_PLUS_SP,0,0,o->w,o->h, game_sprites_info.tpage,game_sprites_info.offsets[n].u,game_sprites_info.offsets[n].v, game_sprites_info.cx,game_sprites_info.cy+game_sprites_info.offsets[n].clut_y, 0,0,0,0,0,ONE,ONE,0); SetObjectsBrightness(o,&brightness[GAME_WHITE_BRIGHTNESS]); SetObjectsPosition(o,x,y,0); return(o); } #ifdef DEBUG_INFO PrintFM("Failed\n"); #endif return(0); } // Function : KillIconSprite() // Coded by : Scott Evans // Created/Modified : 14/4/98 // Description : Remove an icon // Parameters : l - pointer to list // o - pointer to object to remove // Returns : Pointer to object // Notes : None void KillIconSprite(OBJECT_LIST_HEADER *l,OBJECT *o) { PARTICLE_EXPLOSION e; // Create a few fragments SetParticleExplosion(&e,&objects_list,HandleExplosionFragment,6,280,1,1,0,0); setVECTOR(&e.maxvel,2,2,0); setVECTOR(&e.acc,0,0.15*FPN24_8,0); setRECT(&e.r,o->screen.vx,o->screen.vy,8,8); e.b.r=0xff<parent); RemoveObjectFromList(l,o); } // Function : CreateTextString() // Coded by : Scott Evans // Created/Modified : 27/4/98 // Description : Make a text string from sprites // Parameters : pos - screen position // f - pointer to font // s - pointer to string to create // c - center the text // Returns : Pointer to object // Notes : None OBJECT_STRING *CreateTextString(DVECTOR *pos,FONT_INFO *f,u_byte *s,u_byte c) { VECTOR p={pos->vx,pos->vy,0}; static OBJECT_STRING strings[MAX_STRINGS]; static u_byte no_strings=0; no_strings=(++no_strings)%MAX_STRINGS; if(c) p.vx=(GAME_SCREEN_W-(f->cw*strlen(s)))>>1; PrintString(s,f,&p,&strings[no_strings]); return(&strings[no_strings]); } // Function : FindObjectAtPosition() // Coded by : Scott Evans // Created/Modified : 3/6/98 // Description : Find an object at the specified position // Parameters : l - list of objects to search // r,c - screen position // Returns : Pointer to object if found, 0 if not found // Notes : None OBJECT *FindObjectAtPosition(OBJECT_LIST_HEADER *l,word r,word c) { OBJECT *o=l->start; word ox,oy; // Work out screen coordinates ox=c<<4; oy=r<<4; while(o) { // Search for the gun object if((o->screen.vx==ox || o->screen.vx==ox-2 || o->screen.vx==ox-1) && o->screen.vy==oy) return(o); o=o->next; } #ifdef DEBUG_INFO PrintFM("Failed\n"); #endif return(0); } // Function : KillActiveGuns() // Coded by : Scott Evans // Created/Modified : 4/6/98 // Description : Destroy all the active guns on screen // Parameters : None // Returns : None // Notes : None void KillActiveGuns(void) { OBJECT *next,*o=gun_objects.start; while(o) { next=o->next; o->dying=1; if(o->direction==FACING_LEFT) CreateExplosionSprite2(o->screen.vy>>4,(o->screen.vx+2)>>4); else CreateExplosionSprite2(o->screen.vy>>4,o->screen.vx>>4); o=next; } } // Function : KillActivePlatforms() // Coded by : Scott Evans // Created/Modified : 8/6/98 // Description : Destroy all the active moving platforms on screen // Parameters : None // Returns : None // Notes : None void KillActivePlatforms(void) { OBJECT *next,*o=platform_objects.start; while(o) { next=o->next; o->can_move=0; o->dying=1; CreateExplosionSprite2(o->screen.vy>>4,o->screen.vx>>4); RemoveObjectFromList(&platform_objects,o); o=next; } } // Function : KillActiveFans() // Coded by : Scott Evans // Created/Modified : 9/6/98 // Description : Destroy all the active fans on screen // Parameters : None // Returns : None // Notes : None void KillActiveFans(void) { OBJECT *next,*o=fan_objects.start; while(o) { next=o->next; o->dying=1; CreateExplosionSprite2(o->screen.vy>>4,o->screen.vx>>4); RemoveObjectFromList(&wind_objects_list,o->type.f.w); RemoveObjectFromList(&fan_objects,o); o=next; } } #ifdef DEBUG_INFO void ShowWindObjects(void) { OBJECT *new,*o=wind_objects_list.start; while(o) { if((new=CreateObject(&fan_objects,GsBOX_OBJECT))) { SetObjectsDefaultProperties(new); SetObjectsPosition(new,o->screen.vx,o->screen.vy,0); SetObjectsWidthHeight(new,o->w,o->h); SetObjectsBrightness(new,&brightness[GAME_MAX_BRIGHTNESS]); SetObjectsOtOffset(new,1); new->type.gsb.attribute=TRANSPARENCY_ON; } o=o->next; } } #endif // Function : CreateTimerSprite() // Coded by : Scott Evans // Created/Modified : 26/6/98 // Description : Create a sprite used in the big timer // Parameters : l - object list // x,y - position of sprite // Returns : Pointer to created object // Notes : None OBJECT *CreateTimerSprite(OBJECT_LIST_HEADER *l,word t) { OBJECT *o=CreateObject(l,GsSPRITE_OBJECT); GsSPRITE *spr; word n; // Did we get a new object if(o) { // Set the object stuff SetObjectsDefaultProperties(o); SetObjectsOtOffset(o,1); SetObjectsHandler(o,HandleBigTimerObject); SetObjectsTimer(o,t*SECOND); o->extra[0]=t; n=BIG_NUMBER_0+t; spr=&o->type.gss; SetObjectsWidthHeight(o,font_sprite_info.offsets[n].w,font_sprite_info.offsets[n].h); // Define the sprite SetGsSPRITE(spr,0,0,0,o->w,o->h, font_sprite_info.tpage,font_sprite_info.offsets[n].u,font_sprite_info.offsets[n].v, font_sprite_info.cx,font_sprite_info.cy+font_sprite_info.offsets[n].clut_y, 0,0,0,o->w>>1,o->h>>1,ONE*7,ONE*7,0); o->type.gss.attribute=TRANSPARENCY_ON|BG_PLUS_SP; SetObjectsBrightness(o,&brightness[GAME_RED_BRIGHTNESS]); SetObjectsPosition(o,GAME_SCREEN_W>>1,GAME_SCREEN_H>>1,0); return(o); } #ifdef DEBUG_INFO PrintFM("Failed\n"); #endif return(0); } // Function : CreateIntroExplosionSprite() // Coded by : Scott Evans // Created/Modified : 1/7/98 // Description : Create an explosion sprite // Parameters : x,y - position of explosion // Returns : Pointer to explosion object // Notes : None OBJECT *CreateIntroExplosionSprite(word x,word y) { extern OBJECT_LIST_HEADER intro_objects; SPRITE *spr; OBJECT *o=CreateObject(&intro_objects,SPRITE_OBJECT); u_word n=EXPLOSION_START; // Did we get a free object if(o) { // Set the sprite spr=&o->type.s; SetSprite(spr,&game_sprites_info.offsets[0],4,11,1,&xplo_animation[0]); SetObjectsWidthHeight(o,spr->info[n].w,spr->info[n].h); // Set the GsSPRITE SetGsSPRITE(&spr->s,TRANSPARENCY_ON|BG_PLUS_SP,0,0,o->w,o->h, game_sprites_info.tpage,spr->info[n].u,spr->info[n].v, game_sprites_info.cx,game_sprites_info.cy+spr->info[n].clut_y, 0,0,0,o->w>>1,o->h>>1,ONE*3,ONE*3,0); // Set the object SetObjectsDefaultProperties(o); SetObjectsPosition(o,x+(o->w>>1),y+(o->h>>1),0); SetObjectsHandler(o,HandleIntroExplosionObject); SetObjectsTimer(o,100); SetObjectsOtOffset(o,1); StartObjectFading(o); SetObjectsBrightness(o,&brightness[GAME_MAX_BRIGHTNESS]); return(o); } #ifdef DEBUG_INFO else PrintFM("Failed\n"); #endif return(0); } // Function : CreateBonusLevelSprites() // Coded by : Scott Evans // Created/Modified : 1/7/98 // Description : Create the bonus level message // Parameters : None // Returns : Pointer to object string // Notes : None OBJECT_STRING *CreateBonusLevelSprites(void) { static OBJECT_STRING string; VECTOR pos={0,-50,0}; OBJECT *o; static u_byte *s="Bonus Level"; u_byte i; u_word t; pos.vx=(GAME_SCREEN_W-(game_font.cw*strlen(s)))>>1; PrintString(s,&game_font,&pos,&string); if(gd.bonus_type!=BT_CATCH) t=5*SECOND; else t=5*SECOND; // Reset the objects for(o=string.start,i=0;iallow_fading=0; SetObjectsHandler(o,HandleBonusLevelObject); SetObjectsAcceleration(o,0,0.2,0); SetObjectsTimer(o,t); o->active=1; o->extra[0]=0; o->extra[1]=0; if(!i) o->extra[0]=1; o=o->next; } return(&string); } // Function : CreateBonusFirework() // Coded by : Scott Evans // Created/Modified : 1/7/98 // Description : Create a firework // Parameters : None // Returns : Pointer to firework object // Notes : None OBJECT *CreateBonusFirework(void) { OBJECT *o; if(gd.paused) o=CreateObject(&paused_objects,GsTILE_OBJECT); else o=CreateObject(&objects_list,GsTILE_OBJECT); if(o) { SetObjectsDefaultProperties(o); SetObjectsHandler(o,HandleBonusFirework); SetObjectsTimer(o,SECOND*3); SetObjectsPosition(o,(rand()%GAME_SCREEN_W),GAME_SCREEN_H+32,0); SetObjectsWidthHeight(o,2,2); SetObjectsBrightness(o,&brightness[(o->tmp=GAME_EFFECTS_BRIGHTNESS+(rand()%7))]); SetObjectsAcceleration(o,0,0.1,0); SetObjectsVelocity(o,0,-((rand()%4)+4),0); if(o->screen.vx>GAME_SCREEN_W>>1) o->velocity.vx=-1*FPN24_8; else o->velocity.vx=1*FPN24_8; o->type.gstl.attribute=TRANSPARENCY_ON; return(o); } #ifdef DEBUG_INFO PrintFM("Failed\n"); #endif return(0); } OBJECT *CreateBeamObject(void) { OBJECT *o; if((o=CreateObject(&objects_list,GsLINE2_OBJECT))) { SetObjectsDefaultProperties(o); SetObjectsHandler(o,HandleBeamObject); SetObjectsBrightness(o,&brightness[GAME_MOVE_BLOKE_BRIGHTNESS]); SetObjectsAcceleration(o,0,0,0); SetObjectsVelocity(o,0,0,0); o->type.gsl2.attribute=TRANSPARENCY_ON|BG_PLUS_SP; return(o); } #ifdef DEBUG_INFO PrintFM("Failed\n"); #endif return(0); } // Function : CreateBonusLevelSprites() // Coded by : Scott Evans // Created/Modified : 1/7/98 // Description : Create the bonus level message // Parameters : None // Returns : Pointer to object string // Notes : None void CreateLevelSprites(long level) { OBJECT_STRING string; VECTOR pos={0,-50,0}; OBJECT *o; u_byte s[12]; u_byte i; sprintf(s,"Level %d",level+1); pos.vx=(GAME_SCREEN_W-(game_font.cw*strlen(s)))>>1; PrintString(s,&game_font,&pos,&string); // Reset the objects for(o=string.start,i=0;itype.gss.attribute=TRANSPARENCY_ON|BG_PLUS_SP; o->active=1; o->extra[0]=0; o->wind_effect=0; o->allow_fading=0; o=o->next; } // Create a shadow #if 0 pos.vx+=2; PrintString(s,&game_font,&pos,&string); // Reset the objects for(o=string.start,i=0;iallow_fading=0; SetObjectsHandler(o,HandleLevelObject); SetObjectsAcceleration(o,0,0.2,0); SetObjectsTimer(o,SECOND); SetObjectsBrightness(o,&brightness[GAME_MIN_BRIGHTNESS]); //o->type.gss.attribute=TRANSPARENCY_ON|BG_PLUS_SP; o->active=1; o->extra[0]=1; o->wind_effect=0; o=o->next; } #endif gd.lspr_clear=1; } void CreateEmptyBlockCounterEffect(long n) { OBJECT *o=CreateObject(&objects_list,NULL_OBJECT); if(o) { SetObjectsHandler(o,HandleEmptyBlockCounter); SetObjectsTimer(o,0); o->tmp=n; o->active=1; } }