void CycleSecondary () { int cur_order_slot = SOrderList(Secondary_weapon), desired_weapon = Secondary_weapon, loop=0; const int autoselect_order_slot = SOrderList(255); const int use_restricted_autoselect = (cur_order_slot < autoselect_order_slot) && (1 < autoselect_order_slot); while (loop<(MAX_SECONDARY_WEAPONS+1)) { loop++; cur_order_slot++; // next slot if (cur_order_slot >= MAX_SECONDARY_WEAPONS+1) // loop if necessary cur_order_slot = 0; if (cur_order_slot == autoselect_order_slot) // ignore "do not autoselect" { if (use_restricted_autoselect) cur_order_slot = 0; else continue; } desired_weapon = PlayerCfg.SecondaryOrder[cur_order_slot]; // now that is the weapon next to our current one // select the weapon if we have it if (player_has_weapon(desired_weapon, 1) == HAS_ALL) { select_weapon(desired_weapon, 1, 1, 1); return; } } }
// --------------------------------------------------------------------- //called when one of these weapons is picked up //when you pick up a secondary, you always get the weapon & ammo for it // Returns true if powerup picked up, else returns false. int pick_up_secondary(int weapon_index,int count) { int max; int num_picked_up; int cutpoint; max = Secondary_ammo_max[weapon_index]; if (Players[Player_num].flags & PLAYER_FLAGS_AMMO_RACK) max *= 2; if (Players[Player_num].secondary_ammo[weapon_index] >= max) { HUD_init_message(HM_DEFAULT|HM_REDUNDANT|HM_MAYDUPL, "%s %i %ss!", TXT_ALREADY_HAVE, Players[Player_num].secondary_ammo[weapon_index],SECONDARY_WEAPON_NAMES(weapon_index)); return 0; } Players[Player_num].secondary_weapon_flags |= (1<<weapon_index); Players[Player_num].secondary_ammo[weapon_index] += count; num_picked_up = count; if (Players[Player_num].secondary_ammo[weapon_index] > max) { num_picked_up = count - (Players[Player_num].secondary_ammo[weapon_index] - max); Players[Player_num].secondary_ammo[weapon_index] = max; } if (Players[Player_num].secondary_ammo[weapon_index] == count) // only autoselect if player didn't have any { cutpoint=SOrderList (255); if (((Controls.fire_secondary_state && PlayerCfg.NoFireAutoselect)?0:1) && SOrderList (weapon_index)<cutpoint && ((SOrderList (weapon_index) < SOrderList(Secondary_weapon)) || (Players[Player_num].secondary_ammo[Secondary_weapon] == 0)) ) select_weapon(weapon_index,1, 0, 1); else { //if we don't auto-select this weapon, but it's a proxbomb or smart mine, //we want to do a mini-auto-selection that applies to the drop bomb key if ((weapon_index == PROXIMITY_INDEX || weapon_index == SMART_MINE_INDEX) && !(Secondary_weapon == PROXIMITY_INDEX || Secondary_weapon == SMART_MINE_INDEX)) { int cur; cur = Secondary_last_was_super[PROXIMITY_INDEX]?SMART_MINE_INDEX:PROXIMITY_INDEX; if (SOrderList (weapon_index) < SOrderList(cur)) Secondary_last_was_super[PROXIMITY_INDEX] = (weapon_index == SMART_MINE_INDEX); } } } //note: flash for all but concussion was 7,14,21 if (num_picked_up>1) { PALETTE_FLASH_ADD(15,15,15); HUD_init_message(HM_DEFAULT, "%d %ss (count=%i)!",num_picked_up,SECONDARY_WEAPON_NAMES(weapon_index), Players[Player_num].secondary_ammo[weapon_index]); } else { PALETTE_FLASH_ADD(10,10,10); HUD_init_message(HM_DEFAULT, "%s (count=%i)!",SECONDARY_WEAPON_NAMES(weapon_index), Players[Player_num].secondary_ammo[weapon_index]); } return 1; }
// --------------------------------------------------------------------- //called when one of these weapons is picked up //when you pick up a secondary, you always get the weapon & ammo for it // Returns true if powerup picked up, else returns false. int PickupSecondary (tObject *objP, int nWeaponIndex, int nAmount, int nPlayer) { int nMaxAmount; int nPickedUp; int nCutPoint, bEmpty = 0, bSmokeGrens; tPlayer *playerP = gameData.multiplayer.players + nPlayer; if ((nWeaponIndex == PROXMINE_INDEX) && !COMPETITION && EGI_FLAG (bSmokeGrenades, 0, 0, 0)) { bSmokeGrens = 1; nMaxAmount = 4; } else { bSmokeGrens = 0; nMaxAmount = nMaxSecondaryAmmo [nWeaponIndex]; if (playerP->flags & PLAYER_FLAGS_AMMO_RACK) nMaxAmount *= 2; } if (playerP->secondaryAmmo [nWeaponIndex] >= nMaxAmount) { if (ISLOCALPLAYER (nPlayer)) HUDInitMessage("%s %i %ss!", TXT_ALREADY_HAVE, playerP->secondaryAmmo [nWeaponIndex], bSmokeGrens ? TXT_SMOKE_GRENADE : SECONDARY_WEAPON_NAMES (nWeaponIndex)); return 0; } playerP->secondaryWeaponFlags |= (1 << nWeaponIndex); playerP->secondaryAmmo [nWeaponIndex] += nAmount; nPickedUp = nAmount; if (playerP->secondaryAmmo [nWeaponIndex] > nMaxAmount) { nPickedUp = nAmount - (playerP->secondaryAmmo [nWeaponIndex] - nMaxAmount); playerP->secondaryAmmo [nWeaponIndex] = nMaxAmount; if ((nPickedUp < nAmount) && (nWeaponIndex != PROXMINE_INDEX) && (nWeaponIndex != SMARTMINE_INDEX)) { short nObject = OBJ_IDX (objP); gameData.multiplayer.leftoverPowerups [nObject].nCount = nAmount - nPickedUp; gameData.multiplayer.leftoverPowerups [nObject].nType = secondaryWeaponToPowerup [nWeaponIndex]; gameData.multiplayer.leftoverPowerups [nObject].spitterP = OBJECTS + playerP->nObject; } } if (ISLOCALPLAYER (nPlayer)) { nCutPoint = SOrderList (255); bEmpty = playerP->secondaryAmmo [gameData.weapons.nSecondary] == 0; if (gameOpts->gameplay.nAutoSelectWeapon) { if (gameOpts->gameplay.nAutoSelectWeapon == 1) { if (bEmpty) SelectWeapon (nWeaponIndex, 1, 0, 1); } else if ((SOrderList (nWeaponIndex) < nCutPoint) && (bEmpty || (SOrderList (nWeaponIndex) < SOrderList (gameData.weapons.nSecondary)))) SelectWeapon (nWeaponIndex,1, 0, 1); else { //if we don't auto-select this weapon, but it's a proxbomb or smart mine, //we want to do a mini-auto-selection that applies to the drop bomb key if ((nWeaponIndex == PROXMINE_INDEX || nWeaponIndex == SMARTMINE_INDEX) && !(gameData.weapons.nSecondary == PROXMINE_INDEX || gameData.weapons.nSecondary == SMARTMINE_INDEX)) { int cur = bLastSecondaryWasSuper [PROXMINE_INDEX] ? PROXMINE_INDEX : SMARTMINE_INDEX; if (SOrderList (nWeaponIndex) < SOrderList (cur)) bLastSecondaryWasSuper[PROXMINE_INDEX] = (nWeaponIndex == SMARTMINE_INDEX); } } } //note: flash for all but concussion was 7,14,21 if (nAmount>1) { PALETTE_FLASH_ADD (15,15,15); HUDInitMessage("%d %s%s", nPickedUp, bSmokeGrens ? TXT_SMOKE_GRENADES : SECONDARY_WEAPON_NAMES (nWeaponIndex), TXT_SX); } else { PALETTE_FLASH_ADD (10,10,10); HUDInitMessage("%s!", bSmokeGrens ? TXT_SMOKE_GRENADE : SECONDARY_WEAPON_NAMES (nWeaponIndex)); } } return 1; }
void AutoSelectWeapon (int nWeaponType, int bAutoSelect) { int r; int nCutPoint; int bLooped = 0; if (bAutoSelect && !gameOpts->gameplay.nAutoSelectWeapon) return; if (!nWeaponType) { r = PlayerHasWeapon (WeaponId (gameData.weapons.nPrimary), 0, -1, 0); if ((r != HAS_ALL) || bCycling) { int bTryAgain = 1; int iCurWeapon = POrderList (WeaponId (gameData.weapons.nOverridden)); int iNewWeapon = iCurWeapon; int nCurWeapon, nNewWeapon; nCurWeapon = primaryOrder [iCurWeapon]; nCutPoint = POrderList (255); while (bTryAgain) { if (++iNewWeapon >= nCutPoint) { if (bLooped) { if (bCycling) SelectWeapon (gameData.weapons.nPrimary, 0, 0, 1); else { HUDInitMessage (TXT_NO_PRIMARY); #ifdef TACTILE if (TactileStick) ButtonReflexClear(0); #endif SelectWeapon (0, 0, 0, 1); } return; } iNewWeapon = 0; bLooped = 1; } if (iNewWeapon == MAX_PRIMARY_WEAPONS) iNewWeapon = 0; // Hack alert! Because the fusion uses 0 energy at the end (it's got the weird chargeup) // it looks like it takes 0 to fire, but it doesn't, so never auto-select. // if (primaryOrder [iNewWeapon] == FUSION_INDEX) // continue; nNewWeapon = primaryOrder [iNewWeapon]; if (nNewWeapon == gameData.weapons.nPrimary) { if ((nCurWeapon == SUPER_LASER_INDEX) && (nNewWeapon == LASER_INDEX)) continue; else if (bCycling) SelectWeapon (gameData.weapons.nPrimary, 0, 0, 1); else { HUDInitMessage (TXT_NO_PRIMARY); #ifdef TACTILE if (TactileStick) ButtonReflexClear (0); #endif // if (POrderList(0)<POrderList(255)) SelectWeapon(0, 0, 0, 1); } return; // Tried all weapons! } else { if ((nNewWeapon != 255) && (PlayerHasWeapon (nNewWeapon, 0, -1, 0) == HAS_ALL)) { SelectWeapon ((nNewWeapon == SUPER_LASER_INDEX) ? LASER_INDEX : nNewWeapon, 0, 1, 1); bLastPrimaryWasSuper [nNewWeapon % SUPER_WEAPON] = (nNewWeapon >= SUPER_WEAPON); return; } } } } } else { Assert(nWeaponType==1); r = PlayerHasWeapon (gameData.weapons.nSecondary, 1, -1, 0); if (r != HAS_ALL || bCycling) { int bTryAgain = 1; int iCurWeapon = SOrderList (gameData.weapons.nSecondary); nCutPoint = SOrderList (255); while (bTryAgain) { if (++iCurWeapon >= nCutPoint) { if (bLooped) { if (bCycling) SelectWeapon (gameData.weapons.nSecondary, 1, 0, 1); else HUDInitMessage (TXT_NO_SECSELECT); return; } iCurWeapon = 0; bLooped = 1; } if (iCurWeapon == MAX_SECONDARY_WEAPONS) iCurWeapon = 0; if (secondaryOrder [iCurWeapon] == gameData.weapons.nSecondary) { if (bCycling) SelectWeapon (gameData.weapons.nSecondary, 1, 0, 1); else HUDInitMessage (TXT_NO_SECAVAIL); return; // Tried all weapons! } else if (PlayerHasWeapon (secondaryOrder [iCurWeapon], 1, -1, 0) == HAS_ALL) { SelectWeapon (secondaryOrder [iCurWeapon], 1, 1, 1); bTryAgain = 0; } } } } }
// ---------------------------------------------------------------------------------------- // Automatically select next best weapon if unable to fire current weapon. // Weapon type: 0==primary, 1==secondary void auto_select_weapon(int weapon_type) { int r; int cutpoint; int looped=0; if (weapon_type==0) { r = player_has_weapon(Primary_weapon, 0); if (r != HAS_ALL) { int cur_weapon; int try_again = 1; cur_weapon = POrderList(Primary_weapon); cutpoint = POrderList (255); while (try_again) { cur_weapon++; if (cur_weapon>=cutpoint) { if (looped) { HUD_init_message(HM_DEFAULT, "%s", TXT_NO_PRIMARY); select_weapon(0, 0, 0, 1); try_again = 0; continue; } cur_weapon=0; looped=1; } if (cur_weapon==MAX_PRIMARY_WEAPONS) cur_weapon = 0; // Hack alert! Because the fusion uses 0 energy at the end (it's got the weird chargeup) // it looks like it takes 0 to fire, but it doesn't, so never auto-select. // if (PlayerCfg.PrimaryOrder[cur_weapon] == FUSION_INDEX) // continue; if (PlayerCfg.PrimaryOrder[cur_weapon] == Primary_weapon) { HUD_init_message(HM_DEFAULT, "%s", TXT_NO_PRIMARY); select_weapon(0, 0, 0, 1); try_again = 0; // Tried all weapons! } else if (PlayerCfg.PrimaryOrder[cur_weapon]!=255 && player_has_weapon(PlayerCfg.PrimaryOrder[cur_weapon], 0) == HAS_ALL) { select_weapon(PlayerCfg.PrimaryOrder[cur_weapon], 0, 1, 1 ); try_again = 0; } } } } else { Assert(weapon_type==1); r = player_has_weapon(Secondary_weapon, 1); if (r != HAS_ALL) { int cur_weapon; int try_again = 1; cur_weapon = SOrderList(Secondary_weapon); cutpoint = SOrderList (255); while (try_again) { cur_weapon++; if (cur_weapon>=cutpoint) { if (looped) { HUD_init_message(HM_DEFAULT, "No secondary weapons selected!"); try_again = 0; continue; } cur_weapon=0; looped=1; } if (cur_weapon==MAX_SECONDARY_WEAPONS) cur_weapon = 0; if (PlayerCfg.SecondaryOrder[cur_weapon] == Secondary_weapon) { HUD_init_message(HM_DEFAULT, "No secondary weapons available!"); try_again = 0; // Tried all weapons! } else if (player_has_weapon(PlayerCfg.SecondaryOrder[cur_weapon], 1) == HAS_ALL) { select_weapon(PlayerCfg.SecondaryOrder[cur_weapon], 1, 1, 1 ); try_again = 0; } } } } }