/** * Check to see if any player hit a key. */ void IN_CheckForSkip() { for(int i = 0; i < MAXPLAYERS; ++i) { player_t *player = &players[i]; if(player->plr->inGame) { if(player->brain.attack) { if(!player->attackDown) { if(IS_CLIENT) { NetCl_PlayerActionRequest(player, GPA_FIRE, 0); } else { IN_SkipToNext(); } } player->attackDown = true; } else { player->attackDown = false; } if(player->brain.use) { if(!player->useDown) { if(IS_CLIENT) { NetCl_PlayerActionRequest(player, GPA_USE, 0); } else { IN_SkipToNext(); } } player->useDown = true; } else { player->useDown = false; } } } }
/** * Check to see if any player hit a key. */ void IN_CheckForSkip(void) { int i; player_t *player; for(i = 0, player = players; i < MAXPLAYERS; ++i, player++) { if(player->plr->inGame) { if(player->brain.attack) { if(!player->attackDown) { if(IS_CLIENT) NetCl_PlayerActionRequest(player, GPA_FIRE, 0); else IN_SkipToNext(); } player->attackDown = true; } else { player->attackDown = false; } if(player->brain.use) { if(!player->useDown) { if(IS_CLIENT) NetCl_PlayerActionRequest(player, GPA_USE, 0); else IN_SkipToNext(); } player->useDown = true; } else { player->useDown = false; } } } }
/// Check for button presses to skip delays. static void maybeAdvanceState(void) { player_t* player; int i; for(i = 0, player = players; i < MAXPLAYERS; ++i, player++) { if(!players[i].plr->inGame) continue; if(player->brain.attack) { if(!player->attackDown) { if(IS_CLIENT) NetCl_PlayerActionRequest(player, GPA_FIRE, 0); else IN_SkipToNext(); } player->attackDown = true; } else { player->attackDown = false; } if(player->brain.use) { if(!player->useDown) { if(IS_CLIENT) NetCl_PlayerActionRequest(player, GPA_USE, 0); else IN_SkipToNext(); } player->useDown = true; } else { player->useDown = false; } } }
/** * Decides if an automatic weapon change should occur and does it. * * Called when: * A) the player has ran out of ammo for the readied weapon. * B) the player has been given a NEW weapon. * C) the player is ABOUT TO be given some ammo. * * If "weapon" is non-zero then we'll always try to change weapon. * If "ammo" is non-zero then we'll consider the ammo level of weapons that * use this ammo type. * If both non-zero - no more ammo for the current weapon. * * \todo Should be called AFTER ammo is given but we need to * remember the old count before the change. * * @param player The player given the weapon. * @param weapon The weapon given to the player (if any). * @param ammo The ammo given to the player (if any). * @param force @c true = Force a weapon change. * * @return The weapon we changed to OR WT_NOCHANGE. */ weapontype_t P_MaybeChangeWeapon(player_t *player, weapontype_t weapon, ammotype_t ammo, boolean force) { int i, lvl, pclass; ammotype_t ammotype; weapontype_t candidate; weapontype_t returnval = WT_NOCHANGE; weaponinfo_t *winf; boolean found; if(IS_NETWORK_SERVER) { // This is done on clientside. NetSv_MaybeChangeWeapon(player - players, weapon, ammo, force); return WT_NOCHANGE; } #ifdef _DEBUG Con_Message("P_MaybeChangeWeapon: plr %i, weapon %i, ammo %i, force %i", (int)(player - players), weapon, ammo, force); #endif // Assume weapon power level zero. lvl = 0; pclass = player->class_; #if __JHERETIC__ if(player->powers[PT_WEAPONLEVEL2]) lvl = 1; #endif if(weapon == WT_NOCHANGE && ammo == AT_NOAMMO) // Out of ammo. { boolean good; // Note we have no auto-logical choice for a forced change. // Preferences are set by the user. found = false; for(i = 0; i < NUM_WEAPON_TYPES && !found; ++i) { candidate = cfg.weaponOrder[i]; winf = &weaponInfo[candidate][pclass]; // Is candidate available in this game mode? if(!(winf->mode[lvl].gameModeBits & gameModeBits)) continue; // Does the player actually own this candidate? if(!player->weapons[candidate].owned) continue; // Is there sufficent ammo for the candidate weapon? // Check amount for each used ammo type. good = true; for(ammotype = 0; ammotype < NUM_AMMO_TYPES && good; ++ammotype) { if(!winf->mode[lvl].ammoType[ammotype]) continue; // Weapon does not take this type of ammo. #if __JHERETIC__ // Heretic always uses lvl 0 ammo requirements in deathmatch if(deathmatch && player->ammo[ammotype].owned < winf->mode[0].perShot[ammotype]) { // Not enough ammo of this type. Candidate is NOT good. good = false; } else #endif if(player->ammo[ammotype].owned < winf->mode[lvl].perShot[ammotype]) { // Not enough ammo of this type. Candidate is NOT good. good = false; } } if(good) { // Candidate weapon meets the criteria. returnval = candidate; found = true; } } } else if(weapon != WT_NOCHANGE) // Player was given a NEW weapon. { // A forced weapon change? if(force) { returnval = weapon; } // Is the player currently firing? else if(!((player->brain.attack) && cfg.noWeaponAutoSwitchIfFiring)) { // Should we change weapon automatically? if(cfg.weaponAutoSwitch == 2) { // Always change weapon mode returnval = weapon; } else if(cfg.weaponAutoSwitch == 1) { // Change if better mode // Iterate the weapon order array and see if a weapon change // should be made. Preferences are user selectable. for(i = 0; i < NUM_WEAPON_TYPES; ++i) { candidate = cfg.weaponOrder[i]; winf = &weaponInfo[candidate][pclass]; // Is candidate available in this game mode? if(!(winf->mode[lvl].gameModeBits & gameModeBits)) continue; if(weapon == candidate) { // weapon has a higher priority than the readyweapon. returnval = weapon; } else if(player->readyWeapon == candidate) { // readyweapon has a higher priority so don't change. break; } } } } } else if(ammo != AT_NOAMMO) // Player is about to be given some ammo. { if((!(player->ammo[ammo].owned > 0) && cfg.ammoAutoSwitch != 0) || force) { // We were down to zero, so select a new weapon. // Iterate the weapon order array and see if the player owns a // weapon that can be used now they have this ammo. // Preferences are user selectable. for(i = 0; i < NUM_WEAPON_TYPES; ++i) { candidate = cfg.weaponOrder[i]; winf = &weaponInfo[candidate][pclass]; // Is candidate available in this game mode? if(!(winf->mode[lvl].gameModeBits & gameModeBits)) continue; // Does the player actually own this candidate? if(!player->weapons[candidate].owned) continue; // Does the weapon use this type of ammo? if(!(winf->mode[lvl].ammoType[ammo])) continue; /** * @todo Have we got enough of ALL used ammo types? * Problem, since the ammo has not been given yet (could * be an object that gives several ammo types eg backpack) * we can't test for this with what we know! * * This routine should be called AFTER the new ammo has * been given. Somewhat complex logic to decipher first... */ if(cfg.ammoAutoSwitch == 2) { // Always change weapon mode. returnval = candidate; break; } else if(cfg.ammoAutoSwitch == 1 && player->readyWeapon == candidate) { // readyweapon has a higher priority so don't change. break; } } } } // Don't change to the existing weapon. if(returnval == player->readyWeapon) returnval = WT_NOCHANGE; // Choosen a weapon to change to? if(returnval != WT_NOCHANGE) { #ifdef _DEBUG Con_Message("P_MaybeChangeWeapon: Decided to change to weapon %i.", returnval); #endif player->pendingWeapon = returnval; if(IS_CLIENT) { // Tell the server. NetCl_PlayerActionRequest(player, GPA_CHANGE_WEAPON, player->pendingWeapon); } } return returnval; }