/* ----------------------------------------------------------------------------- Function: Parameters: Nothing. Returns: Nothing. Notes: ----------------------------------------------------------------------------- */ PUBLIC void PL_Spawn( placeonplane_t location, LevelData_t *lvl ) { Player.position = location; Player.tilex = POS2TILE( location.origin[ 0 ] ); Player.tiley = POS2TILE( location.origin[ 1 ] ); Player.areanumber = lvl->areas[ Player.tilex ][ Player.tiley ]; assert( Player.areanumber >= 0 && Player.areanumber < NUMAREAS ); if( Player.areanumber < 0 ) { Player.areanumber = 36; } Areas_ConnectAreas( Player.areanumber ); //gsh iphoneSetLevelNotifyText(); #if 0 char str[128]; //sprintf( str, "Entering level E%iM%i", currentMap.episode + 1, currentMap.map + 1 ); //gsh if (currentMap.episode < 6) sprintf( str, "Entering level E%iM%i", currentMap.episode+1, currentMap.map+1 ); else if (currentMap.episode < 10) { int currentLevel = currentMap.episode * 10 + currentMap.map; switch (currentLevel) { case 60: case 61: case 62: case 63: case 64: sprintf( str, "Entering Tunnels %i", currentLevel-60+1); break; case 78: sprintf( str, "Entering Tunnels %i", 6); break; case 65: case 66: case 67: case 68: case 69: sprintf( str, "Entering Dungeons %i", currentLevel-65+1); break; case 79: sprintf( str, "Entering Dungeons %i", 6); break; case 70: case 71: case 72: case 73: case 74: case 75: sprintf( str, "Entering Castle"); break; case 76: sprintf( str, "Entering Ramparts"); break; case 77: sprintf( str, "Entering Death Knight"); break; case 80: sprintf( str, "Entering Dungeon Dimension"); break; default: sprintf( str, " "); break; } } else sprintf( str, "Entering level custom %i", /*currentMap.episode+1,*/ currentMap.map+1 ); iphoneSetNotifyText( str ); #endif }
/* ----------------------------------------------------------------------------- Function: Parameters: Returns: returns true if move ok Notes: ----------------------------------------------------------------------------- */ PRIVATE _boolean PL_TryMove( player_t *self, LevelData_t *lvl ) { int xl, yl, xh, yh, x, y; int d, n; xl = POS2TILE( Player.position.origin[ 0 ] - PLAYERSIZE ); yl = POS2TILE( Player.position.origin[ 1 ] - PLAYERSIZE ); xh = POS2TILE( Player.position.origin[ 0 ] + PLAYERSIZE ); yh = POS2TILE( Player.position.origin[ 1 ] + PLAYERSIZE ); // Cheching for solid walls: for( y = yl ; y <= yh ; ++y ) for( x = xl ; x <= xh ; ++x ) { if( lvl->tilemap[ x ][ y ] & SOLID_TILE ) return 0; if( lvl->tilemap[ x ][ y ] & DOOR_TILE && Door_Opened( &lvl->Doors, x, y) != DOOR_FULLOPEN ) { // iphone hack to allow player to move halfway into door tiles // if the player bounds doesn't cross the middle of the tile, let the move continue if ( abs( Player.position.origin[0] - TILE2POS( x ) ) <= 0x9000 && abs( Player.position.origin[1] - TILE2POS( y ) ) <= 0x9000 ) { return 0; } } } // check for actors for( n = 0 ; n < NumGuards ; ++n ) { if( Guards[ n ].state >= st_die1 ) continue; d = self->position.origin[ 0 ] - Guards[ n ].x; if( d < -MINACTORDIST || d > MINACTORDIST ) continue; d = self->position.origin[ 1 ] - Guards[ n ].y; if( d < -MINACTORDIST || d > MINACTORDIST) continue; return false; } return true; }
/* ----------------------------------------------------------------------------- Function: Parameters: Returns: Notes: ----------------------------------------------------------------------------- */ void SpawnBJVictory( void ) { entity_t *bj; bj = SpawnActor( en_bj, POS2TILE(Player.position.origin[0]), POS2TILE(Player.position.origin[1]), dir4_north, r_world ); if( ! bj ) { return; } bj->x = Player.position.origin[ 0 ]; bj->y = Player.position.origin[ 1 ]; bj->state = st_path1; bj->speed = BJRUNSPEED; bj->flags = FL_NONMARK; // FL_NEVERMARK; bj->temp2 = 6; }
/** * \brief Called when a player pressed the USE button * \param[in] self Player * \param[in] lvl Level data structure * \return true if move is successful, otherwise false. */ PUBLIC _boolean PL_TryMove( player_t *self, LevelData_t *lvl ) { int xl, yl, xh, yh, x, y; int d, n; xl = POS2TILE( Player.position.origin[ 0 ] - PLAYERSIZE ); yl = POS2TILE( Player.position.origin[ 1 ] - PLAYERSIZE ); xh = POS2TILE( Player.position.origin[ 0 ] + PLAYERSIZE ); yh = POS2TILE( Player.position.origin[ 1 ] + PLAYERSIZE ); // Cheching for solid walls: for( y = yl ; y <= yh ; ++y ) for( x = xl ; x <= xh ; ++x ) { if( lvl->tilemap[ x ][ y ] & SOLID_TILE ) return false; if( lvl->tilemap[ x ][ y ] & DOOR_TILE && Door_Opened( &lvl->Doors, x, y) != DOOR_FULLOPEN ) return false; } // check for actors for( n = 0 ; n < NumGuards ; ++n ) { if( Guards[ n ].state >= st_die1 ) continue; d = self->position.origin[ 0 ] - Guards[ n ].x; if( d < -MINACTORDIST || d > MINACTORDIST ) continue; d = self->position.origin[ 1 ] - Guards[ n ].y; if( d < -MINACTORDIST || d > MINACTORDIST) continue; return false; } return true; }
/** * \brief Place player in level */ PUBLIC void PL_Spawn( placeonplane_t location, LevelData_t *lvl ) { r_damageflash = 0; Player.position = location; Player.tilex = POS2TILE( location.origin[ 0 ] ); Player.tiley = POS2TILE( location.origin[ 1 ] ); Player.areanumber = lvl->areas[ Player.tilex ][ Player.tiley ]; if( Player.areanumber < 0 ) { Player.areanumber = 36; } Areas_Connect( Player.areanumber ); ClientState.viewangles[ YAW ] = RAD2FINE(location.angle); ClientState.viewangles[ PITCH ] = 0; Player.playstate = ex_playing; }
/* ----------------------------------------------------------------------------- Function: Changes player's angle and position Parameters: Returns: Notes: ----------------------------------------------------------------------------- */ PRIVATE void PL_ControlMovement( player_t *self, LevelData_t *lvl ) { int angle, speed; // rotation angle = self->position.angle; // if(cmd->forwardmove || cmd->sidemove) self->movx = self->movy = 0; // clear accumulated movement if( Player.cmd.forwardmove ) { speed = tics * Player.cmd.forwardmove; self->movx+=(int)(speed * CosTable[ angle ] ); self->movy+=(int)(speed * SinTable[ angle ] ); } if( Player.cmd.sidemove ) { speed = tics * Player.cmd.sidemove; self->movx += (int)( speed * SinTable[ angle ] ); self->movy -= (int)( speed * CosTable[ angle ] ); } if( ! self->movx && ! self->movy ) return; #ifdef SPEAR funnyticount = 0; // ZERO FUNNY COUNTER IF MOVED! // FIXME! #endif self->speed = self->movx + self->movy; // bound movement if( self->movx > MAXMOVE ) self->movx = MAXMOVE; else if( self->movx < -MAXMOVE ) self->movx = -MAXMOVE; if( self->movy > MAXMOVE ) self->movy = MAXMOVE; else if( self->movy < -MAXMOVE ) self->movy = -MAXMOVE; // move player and clip movement to walls (check for no-clip mode here) PL_ClipMove( self, self->movx, self->movy ); self->tilex = POS2TILE( self->position.origin[ 0 ] ); self->tiley = POS2TILE( self->position.origin[ 1 ] ); // pick up items easier -- any tile you touch, instead of // just the midpoint tile { int x, y; for ( x = -1 ; x <= 1 ; x+= 2 ) { int tilex = POS2TILE( self->position.origin[0] + x * PLAYERSIZE ); for ( y = -1 ; y <= 1 ; y+= 2 ) { int tiley = POS2TILE( self->position.origin[1] + y * PLAYERSIZE ); Powerup_PickUp( tilex, tiley ); } } } // Powerup_PickUp( self->tilex, self->tiley ); // Checking for area change, ambush tiles and doors will have negative values if( lvl->areas[ self->tilex ][ self->tiley ] >= 0 && lvl->areas[ self->tilex ][ self->tiley ] != Player.areanumber ) { Player.areanumber = lvl->areas[ self->tilex ][ self->tiley ]; assert( Player.areanumber >= 0 && Player.areanumber < NUMAREAS ); Areas_ConnectAreas( Player.areanumber ); } if( lvl->tilemap[ self->tilex ][ self->tiley ] & EXIT_TILE ) { iphoneStartIntermission( 0 ); } }
/** * \brief Changes player's angle and position * \param[in] self Player * \param[in] lvl Level data structure */ PRIVATE void PL_ControlMovement( player_t *self, LevelData_t *lvl ) { int speed; float angle; // rotation angle = self->position.angle; // if(cmd->forwardmove || cmd->sidemove) self->movx = self->movy = 0; // clear accumulated movement if( ClientState.cmd.forwardmove ) { speed = tics * ClientState.cmd.forwardmove; self->movx += (int)(speed * cos( angle ) ); self->movy += (int)(speed * sin( angle ) ); } if( ClientState.cmd.sidemove ) { speed = tics * ClientState.cmd.sidemove; self->movx += (int)( speed * sin( angle ) ); self->movy -= (int)( speed * cos( angle ) ); } if( !self->movx && !self->movy ) return; #ifdef SPEAR funnyticount = 0; // ZERO FUNNY COUNTER IF MOVED! // FIXME! #endif self->speed = self->movx + self->movy; // bound movement if( self->movx > MAXMOVE ) { self->movx = MAXMOVE; } else if( self->movx < -MAXMOVE ) { self->movx = -MAXMOVE; } if( self->movy > MAXMOVE ) { self->movy = MAXMOVE; } else if( self->movy < -MAXMOVE ) { self->movy = -MAXMOVE; } // move player and clip movement to walls (check for no-clip mode here) PL_ClipMove( self, self->movx, self->movy ); self->tilex = POS2TILE( self->position.origin[ 0 ] ); self->tiley = POS2TILE( self->position.origin[ 1 ] ); Powerup_PickUp( self->tilex, self->tiley ); // Checking for area change if( lvl->areas[ self->tilex ][ self->tiley ] >= 0 && lvl->areas[ self->tilex ][ self->tiley ] != Player.areanumber ) { Player.areanumber = lvl->areas[ self->tilex ][ self->tiley ]; Areas_Connect( Player.areanumber ); } if( lvl->tilemap[ self->tilex ][ self->tiley ] & EXIT_TILE ) { SpawnBJVictory(); } }
/** * \brief Can this door be closed * \param[in] x X position in tile map * \param[in] y Y position in tile map * \param[in] vertical Set to true if door is vertical, false if horizontal. * \return 0 if door can not be closed, otherwise 1. */ PRIVATE W8 CanCloseDoor( int x, int y, _boolean vertical ) { int n; if( POS2TILE( Player.position.origin[ 0 ] ) == x && POS2TILE( Player.position.origin[ 1 ] ) == y ) { return 0; } if( vertical ) { if( POS2TILE( Player.position.origin[ 1 ] ) == y ) { if( POS2TILE( Player.position.origin[ 0 ] + CLOSEWALL ) == x ) { return 0; } if( POS2TILE( Player.position.origin[ 0 ] - CLOSEWALL ) == x ) { return 0; } } for( n = 0 ; n < NumGuards ; ++n ) { if( Guards[ n ].tilex == x && Guards[ n ].tiley == y ) { return 0; // guard in door } if( Guards[ n ].tilex == x - 1 && Guards[ n ].tiley == y && POS2TILE( Guards[ n ].x + CLOSEWALL ) == x ) { return 0; // guard in door } if( Guards[ n ].tilex == x + 1 && Guards[ n ].tiley == y && POS2TILE( Guards[ n ].x - CLOSEWALL ) == x ) { return 0; // guard in door } } } else { if( POS2TILE( Player.position.origin[ 0 ] ) == x ) { if( POS2TILE( Player.position.origin[ 1 ] + CLOSEWALL ) == y ) { return 0; } if( POS2TILE( Player.position.origin[ 1 ] - CLOSEWALL ) == y ) { return 0; } } for( n = 0 ; n < NumGuards ; ++n ) { if( Guards[ n ].tilex == x && Guards[ n ].tiley == y ) { return 0; // guard in door } if( Guards[ n ].tilex == x && Guards[ n ].tiley == y - 1 && POS2TILE( Guards[ n ].y + CLOSEWALL ) == y ) { return 0; // guard in door } if( Guards[ n ].tilex == x && Guards[ n ].tiley == y + 1 && POS2TILE( Guards[ n ].y - CLOSEWALL ) == y ) { return 0; // guard in door } } } return 1; }