/** * \brief Try to move push-wall. * \param[in] x coordinates in tile map. * \param[in] y coordinates in tile map. * \param[in] dir Direction in which push-wall is intended to move. * \return Returns true if push successful, otherwise false. * \note Called whenever someone tries to push a secret wall. */ PUBLIC _boolean PushWall_Push( int x, int y, dir4type dir ) { int dx, dy; if( PWall.active ) { return false; // another PWall is moving [only one at a time!] } dx = dx4dir[ dir ]; dy = dy4dir[ dir ]; if( r_world->tilemap[ x + dx ][ y + dy ] & (SOLID_TILE | DOOR_TILE) ) { // noway (smth is blocking) return true; } // remove secret flag & make everything needed when pushwall used! r_world->tilemap[ x ][ y ] &= (~SECRET_TILE); r_world->tilemap[ x ][ y ] &= (~WALL_TILE); r_world->tilemap[ x ][ y ] |= PUSHWALL_TILE; Com_Printf( "You have found a secret!\n" ); levelstate.found_secrets++; if( g_version->value == SPEAROFDESTINY ) { Sound_StartSound( NULL, 1, CHAN_AUTO, Sound_RegisterSound( "sfx/030.wav" ), 1, ATTN_STATIC, 0 ); } else { Sound_StartSound( NULL, 1, CHAN_AUTO, Sound_RegisterSound( "sfx/034.wav" ), 1, ATTN_STATIC, 0 ); } // good way to avoid stuckness; [un]comment one more down! // it makes a tile behind pushwall unpassable r_world->tilemap[ x + dx ][ y + dy ] |= PUSHWALL_TILE; r_world->wall_tex_x[ x + dx ][ y + dy ] = r_world->wall_tex_x[ x ][ y ]; r_world->wall_tex_y[ x + dx ][ y + dy ] = r_world->wall_tex_y[ x ][ y ]; // write down PWall info PWall.active = true; PWall.PWtilesmoved = PWall.PWpointsmoved = 0; PWall.dir = dir; PWall.x = x; PWall.y = y; PWall.dx = dx; PWall.dy = dy; PWall.tex_x = r_world->wall_tex_x[ x ][ y ]; PWall.tex_y = r_world->wall_tex_y[ x ][ y ]; return true; }
/* ----------------------------------------------------------------------------- Function: PushWall_Push() -Try to move push-wall. Parameters: x, y -[in] Coordinates in tilemap. dir -[in] Direction in which push-wall is intended to move. Returns: true if push successful, otherwise false. Notes: Called whenever someone tries to push a secret wall. ----------------------------------------------------------------------------- */ PUBLIC _boolean PushWall_Push( int x, int y, dir4type dir ) { int dx, dy; if( PWall.active ) { return false; // another PWall is moving [only one at a time!] } dx = dx4dir[ dir ]; dy = dy4dir[ dir ]; if( r_world->tilemap[ x + dx ][ y + dy ] & (SOLID_TILE | DOOR_TILE) ) { // noway (smth is blocking) return true; } // remove secret flag & make everything needed when pushwall used! r_world->tilemap[ x ][ y ] &= (~SECRET_TILE); r_world->tilemap[ x ][ y ] &= (~WALL_TILE); r_world->tilemap[ x ][ y ] |= PUSHWALL_TILE; if ( ++levelstate.found_secrets == levelstate.total_secrets ) { iphoneSetNotifyText( "You found the last secret!" ); } else { iphoneSetNotifyText( "You found a secret!" ); } if( g_version->value == SPEAROFDESTINY && currentMap.episode >= 6 && currentMap.episode < 9)//added the episode check... gsh ).. TODO: fix sfx and other media { Sound_StartSound( NULL, 1, CHAN_AUTO, Sound_RegisterSound( "sfx/030.wav" ), 1, ATTN_STATIC, 0 ); } else { Sound_StartSound( NULL, 1, CHAN_AUTO, Sound_RegisterSound( "sfx/034.wav" ), 1, ATTN_STATIC, 0 ); } // good way to avoid stuckness; [un]comment one more down! // it makes a tile behind pushwall unpassable r_world->tilemap[ x + dx ][ y + dy ] |= PUSHWALL_TILE; r_world->wall_tex_x[ x + dx ][ y + dy ] = r_world->wall_tex_x[ x ][ y ]; r_world->wall_tex_y[ x + dx ][ y + dy ] = r_world->wall_tex_y[ x ][ y ]; // write down PWall info PWall.active = true; PWall.PWtilesmoved = PWall.PWpointsmoved = 0; PWall.dir = dir; PWall.x = x; PWall.y = y; PWall.dx = dx; PWall.dy = dy; PWall.tex_x = r_world->wall_tex_x[ x ][ y ]; PWall.tex_y = r_world->wall_tex_y[ x ][ y ]; return true; }
/** * \brief Called when a player pressed the USE button * \param[in] self Player * \param[in] lvl Level data structure * \return true if player used something, otherwise false */ PRIVATE _boolean PL_Use( player_t *self, LevelData_t *lvl ) { int x, y, dir; dir = Get4dir( self->position.angle ); x = self->tilex + dx4dir[ dir ]; y = self->tiley + dy4dir[ dir ]; if( lvl->tilemap[ x ][ y ] & DOOR_TILE ) { Door_Use( &lvl->Doors.DoorMap[ x ][ y ], Player.items ); return true; } if( lvl->tilemap[ x ][ y ] & SECRET_TILE ) { return PushWall_Push( x, y, dir ); } if( lvl->tilemap[ x ][ y ] & ELEVATOR_TILE ) { int newtex; switch( dir ) { case dir4_east: case dir4_west: newtex = lvl->wall_tex_x[ x ][ y ] += 2; break; case dir4_north: case dir4_south: return false; // don't allow to press elevator rails } if( lvl->tilemap[ self->tilex ][ self->tiley ] & SECRETLEVEL_TILE ) { self->playstate = ex_secretlevel; elevatorSwitchTime = ClientStatic.realtime; } else { self->playstate = ex_complete; elevatorSwitchTime = ClientStatic.realtime; } Sound_StartSound( NULL, 0, CHAN_BODY, Sound_RegisterSound( "lsfx/040.wav" ), 1, ATTN_NORM, 0 ); return true; } //Sound_StartSound( NULL, 0, CHAN_BODY, Sound_RegisterSound( "lsfx/020.wav" ), 1, ATTN_NORM, 0 ); return false; }
/* ----------------------------------------------------------------------------- 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: 1 if powerup is picked up, otherwise 0. Notes: ----------------------------------------------------------------------------- */ PRIVATE int Pow_Give( pow_t type ) { static const char *keynames[] = { "Gold", "Silver", "?", "?" }; switch( type ) { // // Keys // case pow_key1: case pow_key2: case pow_key3: case pow_key4: type -= pow_key1; PL_GiveKey( &Player, type ); Sound_StartSound( NULL, 0, CHAN_ITEM, Sound_RegisterSound( "lsfx/012.wav" ), 1, ATTN_NORM, 0 ); iphoneSetNotifyText( "%s key\n", keynames[ type ] ); break; // // Treasure // case pow_cross: PL_GiveHealth( &Player, 1, 150 ); // iphone -- trasure acts as health crumbs PL_GivePoints( &Player, 100 ); Sound_StartSound( NULL, 0, CHAN_ITEM, Sound_RegisterSound( "lsfx/035.wav" ), 1, ATTN_NORM, 0 ); if ( ++levelstate.found_treasure == levelstate.total_treasure ) { iphoneSetNotifyText( "You found the last treasure!" ); } break; case pow_chalice: PL_GiveHealth( &Player, 1, 150 ); // iphone -- trasure acts as health crumbs PL_GivePoints( &Player, 500 ); Sound_StartSound( NULL, 0, CHAN_ITEM, Sound_RegisterSound( "lsfx/036.wav" ), 1, ATTN_NORM, 0 ); if ( ++levelstate.found_treasure == levelstate.total_treasure ) { iphoneSetNotifyText( "You found the last treasure!" ); } break; case pow_bible: PL_GiveHealth( &Player, 1, 150 ); // iphone -- trasure acts as health crumbs PL_GivePoints( &Player, 1000 ); Sound_StartSound( NULL, 0, CHAN_ITEM, Sound_RegisterSound( "lsfx/037.wav" ), 1, ATTN_NORM, 0 ); if ( ++levelstate.found_treasure == levelstate.total_treasure ) { iphoneSetNotifyText( "You found the last treasure!" ); } break; case pow_crown: PL_GiveHealth( &Player, 1, 150 ); // iphone -- trasure acts as health crumbs PL_GivePoints( &Player, 5000 ); Sound_StartSound( NULL, 0, CHAN_ITEM, Sound_RegisterSound( "lsfx/045.wav" ), 1, ATTN_NORM, 0 ); if ( ++levelstate.found_treasure == levelstate.total_treasure ) { iphoneSetNotifyText( "You found the last treasure!" ); } break; // // Health // case pow_gibs: if( ! PL_GiveHealth( &Player, 1, 11 ) ) { return 0; } Sound_StartSound( NULL, 0, CHAN_ITEM, Sound_RegisterSound( "lsfx/061.wav" ), 1, ATTN_NORM, 0 ); break; case pow_alpo: if( ! PL_GiveHealth( &Player, 4, 0 ) ) { return 0; } Sound_StartSound( NULL, 0, CHAN_ITEM, Sound_RegisterSound( "lsfx/033.wav" ), 1, ATTN_NORM, 0 ); break; case pow_food: if( ! PL_GiveHealth( &Player, 10, 0 ) ) { return 0; } Sound_StartSound( NULL, 0, CHAN_ITEM, Sound_RegisterSound( "lsfx/033.wav" ), 1, ATTN_NORM, 0 ); break; case pow_firstaid: if( ! PL_GiveHealth( &Player, 25, 0 ) ) { return 0; } Sound_StartSound( NULL, 0, CHAN_ITEM, Sound_RegisterSound( "lsfx/034.wav" ), 1, ATTN_NORM, 0 ); break; // // Weapon & Ammo // case pow_clip: if( ! PL_GiveAmmo( &Player, AMMO_BULLETS, 8 ) ) { return 0; } Sound_StartSound( NULL, 0, CHAN_ITEM, Sound_RegisterSound( "lsfx/031.wav" ), 1, ATTN_NORM, 0 ); break; case pow_clip2: if( ! PL_GiveAmmo( &Player, AMMO_BULLETS, 4 ) ) { return 0; } Sound_StartSound( NULL, 0, CHAN_ITEM, Sound_RegisterSound( "lsfx/031.wav" ), 1, ATTN_NORM, 0 ); break; case pow_25clip: if( ! PL_GiveAmmo( &Player, AMMO_BULLETS, 25 ) ) { return 0; } Sound_StartSound( NULL, 0, CHAN_ITEM, Sound_RegisterSound( "lsfx/064.wav" ), 1, ATTN_NORM, 0 ); break; case pow_machinegun: PL_GiveWeapon( &Player, WEAPON_AUTO ); Sound_StartSound( NULL, 0, CHAN_ITEM, Sound_RegisterSound( "lsfx/030.wav" ), 1, ATTN_NORM, 0 ); iphoneSetNotifyText( "Machinegun" ); break; case pow_chaingun: PL_GiveWeapon( &Player, WEAPON_CHAIN ); Sound_StartSound( NULL, 0, CHAN_ITEM, Sound_RegisterSound( "lsfx/038.wav" ), 1, ATTN_NORM, 0 ); iphoneSetNotifyText( "Chaingun" ); Player.facecount = -100; Player.face_gotgun = true; break; // // Artifacts // case pow_fullheal: PL_GiveHealth( &Player, 999, 0 ); PL_GiveAmmo( &Player, AMMO_BULLETS, 25 ); PL_GiveLife( &Player ); if ( ++levelstate.found_treasure == levelstate.total_treasure ) { iphoneSetNotifyText( "You found the last treasure!" ); } else { iphoneSetNotifyText( "Full Heal" ); } // no extra lives on iPhone Com_Printf( "Extra life!\n" ); break; case pow_spear: { char szTextMsg[ 256 ]; Sound_StartSound( NULL, 0, CHAN_ITEM, Sound_RegisterSound( "sodsfx/109.wav" ), 1, ATTN_NORM, 0 ); iphoneSetNotifyText( "Spear of Destiny" ); my_snprintf( szTextMsg, sizeof( szTextMsg ), "loading ; map s%.2d.map\n", 20 ); Cbuf_AddText( szTextMsg ); } break; default: Com_DPrintf( "Warning: Unknown item type: %d\n", type ); break; } iphoneStartBonusFlash(); return 1; }
/** * \brief Doors to process * \param[in] lvldoors Doors to process * \param[in] t_tk Clock tics */ PUBLIC void Door_Process( LevelDoors_t *lvldoors, int t_tk ) { int n; for( n = 0 ; n < lvldoors->doornum ; ++n ) { switch( lvldoors->Doors[ n ]->action ) { case dr_closed: // this door is closed! continue; case dr_opening: if( lvldoors->Doors[ n ]->ticcount >= DOOR_FULLOPEN ) // door fully opened! { lvldoors->Doors[ n ]->action = dr_open; lvldoors->Doors[ n ]->ticcount = 0; } else // opening! { if( lvldoors->Doors[ n ]->ticcount == 0 ) { // door is just starting to open, so connect the areas Areas_Join( lvldoors->Doors[ n ]->area1, lvldoors->Doors[ n ]->area2 ); Areas_Connect( Player.areanumber ); if( areabyplayer[ lvldoors->Doors[ n ]->area1 ] ) // Door Opening sound! { Sound_StartSound( NULL, 1, CHAN_AUTO, Sound_RegisterSound( "sfx/010.wav" ), 1, ATTN_STATIC, 0 ); } } lvldoors->Doors[n]->ticcount += t_tk; if( lvldoors->Doors[ n ]->ticcount > DOOR_FULLOPEN ) { lvldoors->Doors[ n ]->ticcount = DOOR_FULLOPEN; } } break; case dr_closing: if( lvldoors->Doors[ n ]->ticcount <= 0 ) // door fully closed! disconnect areas! { Areas_Disconnect( lvldoors->Doors[ n ]->area1, lvldoors->Doors[ n ]->area2 ); Areas_Connect( Player.areanumber ); lvldoors->Doors[ n ]->ticcount = 0; lvldoors->Doors[ n ]->action = dr_closed; } else // closing! { if( lvldoors->Doors[ n ]->ticcount == DOOR_FULLOPEN ) { if( areabyplayer[ lvldoors->Doors[ n ]->area1 ] ) // Door Closing sound! { Sound_StartSound( NULL, 1, CHAN_AUTO, Sound_RegisterSound( "sfx/007.wav" ), 1, ATTN_STATIC, 0 ); } } lvldoors->Doors[ n ]->ticcount -= t_tk; if( lvldoors->Doors[ n ]->ticcount < 0 ) { lvldoors->Doors[ n ]->ticcount = 0; } } break; case dr_open: if( lvldoors->Doors[ n ]->ticcount > DOOR_MINOPEN ) { // If player or something is in door do not close it! if( ! CanCloseDoor( lvldoors->Doors[ n ]->tilex, lvldoors->Doors[ n ]->tiley, lvldoors->Doors[ n ]->vertical ) ) { lvldoors->Doors[ n ]->ticcount = DOOR_MINOPEN; // do not close door immediately! } } if( lvldoors->Doors[ n ]->ticcount >= DOOR_TIMEOUT ) { // Door timeout, time to close it! lvldoors->Doors[ n ]->action = dr_closing; lvldoors->Doors[ n ]->ticcount = DOOR_FULLOPEN; } else { // Increase timeout! lvldoors->Doors[ n ]->ticcount += t_tk; } break; } // End switch lvldoors->Doors[ n ].action } // End for n = 0 ; n < lvldoors->doornum ; ++n }
/* ----------------------------------------------------------------------------- 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 ); }
/* ----------------------------------------------------------------------------- Function: Parameters: Returns: Notes: ----------------------------------------------------------------------------- */ void T_BJYell( entity_t *Guard ) { Sound_StartSound( NULL, 0, CHAN_VOICE, Sound_RegisterSound( "sfx/082.wav" ), 1, ATTN_NORM, 0 ); }