@ -1,4 +1,4 @@
/* $Id: field.c,v 1.3 8 2003/07/23 02:10:47 stpohle Exp $ */
/* $Id: field.c,v 1.3 9 2003/07/27 13:29:25 stpohle Exp $ */
/* field.c - procedures which are needed to control the field */
# include "bomberclone.h"
@ -6,9 +6,15 @@
static _point fieldani [ MAX_FIELDANIMATION ] ;
static _point stonelist [ MAX_STONESTODRAW ] ; // keep all stones to draw
static int fieldcheck_to ; // timeout for the next fieldcheck FIELDCHECK_TIMEOUT
static int fieldhurry_to ;
static _point fieldhurrypos ; // x,y for the hurry
static int fieldhurryd ; // direction for the hurry
/* delete the stone entry list */
void stonelist_del ( ) {
void
stonelist_del ( )
{
register int i ;
for ( i = 0 ; i < MAX_STONESTODRAW ; i + + )
@ -17,7 +23,9 @@ void stonelist_del () {
/* stonelist will be draw and cleaned */
void stonelist_draw ( ) {
void
stonelist_draw ( )
{
int i ;
for ( i = 0 ; i < MAX_STONESTODRAW & & stonelist [ i ] . x ! = - 1 & & stonelist [ i ] . y ! = - 1 ; i + + ) {
@ -28,12 +36,15 @@ void stonelist_draw () {
/* add stone to draw */
static void _stonelist_add ( int x , int y , int recursive ) {
static void
_stonelist_add ( int x , int y , int recursive )
{
int i ;
_point * slentry = NULL ;
for ( i = 0 , slentry = NULL ; i < MAX_STONESTODRAW & & slentry = = NULL ; i + + )
if ( stonelist [ i ] . x = = - 1 | | stonelist [ i ] . y = = - 1 | | ( stonelist [ i ] . x = = x & & stonelist [ i ] . y = = y ) )
if ( stonelist [ i ] . x = = - 1 | | stonelist [ i ] . y = = - 1
| | ( stonelist [ i ] . x = = x & & stonelist [ i ] . y = = y ) )
slentry = & stonelist [ i ] ;
if ( slentry = = NULL ) // no space left
@ -47,7 +58,11 @@ static void _stonelist_add (int x, int y, int recursive) {
_stonelist_add ( x , y - 1 , 0 ) ;
}
} ;
inline void stonelist_add ( int x , int y ) { _stonelist_add ( x , y , 1 ) ; } ;
inline void
stonelist_add ( int x , int y )
{
_stonelist_add ( x , y , 1 ) ;
} ;
void
@ -143,12 +158,17 @@ draw_stone (int x, int y)
/* if the current field is half hidden by the lower
field ( y + 1 ) draw this little part too */
if ( y < map . size . y - 1 & & gfx . field [ map . field [ x ] [ y + 1 ] . type ] . h > gfx . field [ map . field [ x ] [ y + 1 ] . type ] . w ) {
if ( y < map . size . y - 1
& & gfx . field [ map . field [ x ] [ y + 1 ] . type ] . h > gfx . field [ map . field [ x ] [ y + 1 ] . type ] . w ) {
src . x = 0 ;
src . y = map . field [ x ] [ y + 1 ] . frame * gfx . field [ map . field [ x ] [ y + 1 ] . type ] . h ;
dest . h = src . h = gfx . field [ map . field [ x ] [ y + 1 ] . type ] . h - gfx . field [ map . field [ x ] [ y + 1 ] . type ] . w ;
dest . h = src . h =
gfx . field [ map . field [ x ] [ y + 1 ] . type ] . h - gfx . field [ map . field [ x ] [ y + 1 ] . type ] . w ;
dest . w = src . w = gfx . field [ map . field [ x ] [ y + 1 ] . type ] . w ;
dest . y = gfx . offset . y + ( ( gfx . block . y * ( y + 1 ) ) - ( gfx . field [ map . field [ x ] [ y + 1 ] . type ] . h - gfx . field [ map . field [ x ] [ y + 1 ] . type ] . w ) ) ;
dest . y =
gfx . offset . y + ( ( gfx . block . y * ( y + 1 ) ) -
( gfx . field [ map . field [ x ] [ y + 1 ] . type ] . h -
gfx . field [ map . field [ x ] [ y + 1 ] . type ] . w ) ) ;
gfx_blit ( gfx . field [ map . field [ x ] [ y + 1 ] . type ] . image , & src , gfx . screen , & dest , ( y < < 8 ) + 5 ) ;
}
@ -189,7 +209,8 @@ field_clear (int x, int y)
void
field_animation ( )
{
int i , j ;
int i ,
j ;
_field * stone ;
for ( i = 0 ; i < MAX_FIELDANIMATION ; i + + )
@ -269,3 +290,165 @@ field_animation_add (int x, int y)
fieldani [ j ] . x = x ;
fieldani [ j ] . y = y ;
} ;
/* check the field, if everything is empty */
int
field_checkisempty ( )
{
register int x ,
y ;
int empty = 1 ;
for ( x = 1 ; ( x < ( map . size . x - 1 ) & & empty ) ; x + + )
for ( y = 1 ; ( y < ( map . size . y - 1 ) & & empty ) ; y + + )
if ( map . field [ x ] [ y ] . type = = FT_stone )
empty = 0 ;
return empty ;
}
/* will check for some gamerelated map informations
check if the map is empty , and so something like a timeout so we won ' t
end up in a endless game */
void
field_loop ( )
{
/* single game or multiplayer master, so check field state */
if ( GT_MP_PTPM | | bman . gametype = = GT_single ) {
/* timeout for rechecking every 5 secs the field */
if ( map . state = = MS_normal & & map . map_selection = = MAPS_randgen
& & ( fieldcheck_to - - > FIELDECHECK_TIMEOUT | | fieldcheck_to < = 0 ) ) {
if ( field_checkisempty ( ) )
bman . timeout = 0 ; // set the gametimeout to 0
}
/* gametimeout is 0 and we are still at more normal set randomly a
way to end the game */
if ( bman . timeout - - < = 0 & & map . state = = MS_normal ) {
int rndmax ;
if ( map . map_selection = = MAPS_randgen )
rndmax = MS_max - 1 ; // generaged map
else
rndmax = MS_max - 2 ; // user defined map
map . state = 1 + s_random ( rndmax ) ;
d_printf ( " Game Timeout 1 over: Random map.state = %d \n " , map . state ) ;
bman . timeout = GAME_TIMEOUTHURRY ;
fieldhurrypos . x = fieldhurrypos . y = 0 ;
}
/* check if we need to small down the map */
if ( map . state = = MS_hurry )
field_hurrysize ( ) ;
if ( map . state = = MS_dropitems )
field_hurrydropitems ( ) ;
}
field_animation ( ) ;
} ;
/* hurrymode drop a item randomly */
void
field_hurrydropitems ( )
{
int x = 0 ,
y = 0 ,
try = 100 ;
if ( fieldhurry_to - - < = 0 | | fieldhurry_to > FIELDHURRYDROPTO ) {
fieldhurry_to = FIELDHURRYDROPTO ;
while ( map . field [ x ] [ y ] . type ! = FT_nothing & & ( try - - ) ) {
x = s_random ( map . size . x - 2 ) + 1 ;
y = s_random ( map . size . y - 2 ) + 1 ;
}
if ( try ) {
map . field [ x ] [ y ] . type = s_random ( FT_mixed - 2 ) + 3 ;
stonelist_add ( x , y ) ;
if ( GT_MP_PTPM )
net_game_send_field ( x , y ) ;
}
}
} ;
/* hurrymode small down the map */
void
field_hurrysize ( )
{
int i ;
if ( fieldhurry_to - - < = 0 | | fieldhurry_to > FIELDHURRYSIZE ) {
fieldhurry_to = FIELDHURRYSIZE ;
if ( fieldhurrypos . x = = 0 ) {
fieldhurrypos . x = fieldhurrypos . y = 1 ;
fieldhurryd = right ;
}
else if ( fieldhurrypos . x > 0 ) {
bman . timeout = GAME_TIMEOUTHURRY - 1 ;
switch ( fieldhurryd ) {
case ( right ) :
if ( fieldhurrypos . x + 1 > = map . size . x - fieldhurrypos . y ) {
fieldhurryd = down ;
fieldhurrypos . y + + ;
}
else
fieldhurrypos . x + + ;
break ;
case ( down ) :
if ( fieldhurrypos . y > = map . size . y - ( map . size . x - fieldhurrypos . x ) ) {
fieldhurryd = left ;
fieldhurrypos . x - - ;
}
else
fieldhurrypos . y + + ;
break ;
case ( left ) :
if ( fieldhurrypos . x < = ( map . size . y - fieldhurrypos . y ) - 1 ) {
fieldhurryd = up ;
fieldhurrypos . y - - ;
}
else
fieldhurrypos . x - - ;
break ;
default :
if ( fieldhurrypos . y - 1 < = fieldhurrypos . x ) {
/* check if this is the end */
i = map . size . x - ( 2 * fieldhurrypos . x ) ;
if ( i > FIELDHURRYSIZEMIN )
i = map . size . y - ( 2 * fieldhurrypos . y ) ;
if ( i < = FIELDHURRYSIZEMIN )
fieldhurrypos . x = fieldhurrypos . y = - 1 ;
else {
fieldhurryd = right ;
fieldhurrypos . x + + ;
}
}
else
fieldhurrypos . y - - ;
break ;
}
}
/* check if we have finished sizing down everything */
if ( fieldhurrypos . x > 0 ) {
/* set the block on the position */
map . field [ fieldhurrypos . x ] [ fieldhurrypos . y ] . type = FT_block ;
stonelist_add ( fieldhurrypos . x , fieldhurrypos . y ) ;
if ( GT_MP_PTPM )
net_game_send_field ( fieldhurrypos . x , fieldhurrypos . y ) ;
}
}
} ;