void A_CheckReload(player_t *player, pspdef_t *psp) { if (!P_CheckAmmo(player) && compatibility_level >= prboom_4_compatibility) { /* cph 2002/08/08 - In old Doom, P_CheckAmmo would start the weapon lowering * immediately. This was lost in Boom when the weapon switching logic was * rewritten. But we must tell Doom that we don't need to complete the * reload frames for the weapon here. G_BuildTiccmd will set ->pendingweapon * for us later on. */ P_SetPsprite(player,ps_weapon,weaponinfo[player->readyweapon].downstate); } }
void A_CheckReload (AActor *mo) { player_t *player = mo->player; P_CheckAmmo (player); #if 0 if (player->ammo[am_shell]<2) P_SetPsprite (player, ps_weapon, S_DSNR1); #endif }
static void P_FireWeapon(player_t *player) { statenum_t newstate; if (!P_CheckAmmo(player)) return; P_SetMobjState(player->mo, S_PLAY_ATK1); newstate = weaponinfo[player->readyweapon].atkstate; P_SetPsprite(player, ps_weapon, newstate); P_NoiseAlert(player->mo, player->mo); }
OVERLAY static void P_FireWeapon(player_t *player) { statenum_t newstate; if (!P_CheckAmmo(player)) return; P_SetMobjState(player->mo, S_PLAY_ATK1); newstate = (statenum_t)weaponinfo[player->readyweapon].atkstate; P_SetPsprite(player, ps_weapon, newstate); P_NoiseAlert(player->mo, player->mo); lastshottic = gametic; // killough 3/22/98 }
void P_FireWeapon(player_t *player) { statenum_t newstate; if(!P_CheckAmmo(player)) return; // Psprite state. player->plr->pSprites[0].state = DDPSP_FIRE; P_MobjChangeState(player->plr->mo, PCLASS_INFO(player->class_)->attackState); newstate = weaponInfo[player->readyWeapon][player->class_].mode[0].states[WSN_ATTACK]; P_SetPsprite(player, ps_weapon, newstate); P_NoiseAlert(player->plr->mo, player->plr->mo); }
// // A_ReFire // The player can re-fire the weapon // without lowering it entirely. // void A_ReFire(player_t *player, pspdef_t *psp) { // check for fire // (if a weaponchange is pending, let it go through instead) if ((player->cmd.buttons & BT_ATTACK) && player->pendingweapon == wp_nochange && player->health) { player->refire++; P_FireWeapon(player); } else { player->refire = 0; P_CheckAmmo(player); } }
// // P_FireWeapon. // void P_FireWeapon(player_t *player) { statenum_t newstate; if (!P_CheckAmmo(player) || (automapactive && !followplayer)) return; P_SetMobjState(player->mo, S_PLAY_ATK1); newstate = (statenum_t)weaponinfo[player->readyweapon].atkstate; P_SetPsprite(player, ps_weapon, newstate); if (player->readyweapon == wp_fist && !linetarget) return; P_NoiseAlert(player->mo, player->mo); }
/** * The player can re-fire the weapon without lowering it entirely. */ void C_DECL A_ReFire(player_t *player, pspdef_t *psp) { // Check for fire (if a weaponchange is pending, let it go through // instead). if((player->brain.attack) && player->pendingWeapon == WT_NOCHANGE && player->health) { player->refire++; P_FireWeapon(player); } else { player->refire = 0; P_CheckAmmo(player); } }
static void P_FireWeapon(player_t *player) { statenum_t newstate; if (!P_CheckLoaded(player)) return; if (!P_CheckAmmo(player)) return; P_SetMobjState(player->mo, S_PLAY_ATK1); newstate = weaponinfo[player->readyweapon].atkstate; P_SetPsprite(player, ps_weapon, newstate); P_NoiseAlert(player->mo, player->mo); //Melee doesn't need to be reloaded -jukeri12 18.8.2015 if (player->readyweapon != wp_fist) player->weaponloaded[player->readyweapon] = false; }
// // P_FireWeapon. // void P_FireWeapon(player_t* player) { statenum_t newstate; pspdef_t* psp; if (!P_CheckAmmo (player)) return; psp = &player->psprites[ps_weapon]; P_SetMobjState (player->mo, S_006); newstate = weaponinfo[player->readyweapon].atkstate; if(player->refire && player->readyweapon == wp_pistol) newstate++; P_SetPsprite (player, ps_weapon, newstate); P_NoiseAlert (player->mo, player->mo); psp->sx = FRACUNIT; //villsa psp->sy = WEAPONTOP; }
// // A_ReFire // The player can re-fire the weapon // without lowering it entirely. // void A_ReFire (AActor *mo) { player_t *player = mo->player; // check for fire // (if a weaponchange is pending, let it go through instead) // [AM] Allow warmup to disallow weapon refiring. if ( (player->cmd.ucmd.buttons & BT_ATTACK && warmup.checkfireweapon()) && player->pendingweapon == wp_nochange && player->health) { player->refire++; P_FireWeapon (player); } else { player->refire = 0; P_CheckAmmo (player); } }
// // P_FireWeapon. // void P_FireWeapon (player_t *player) { statenum_t newstate; if (!P_CheckAmmo (player)) return; // [tm512] Send the client the weapon they just fired so // that they can fix any weapon desyncs that they get - apr 14 2012 if (serverside && !clientside) { MSG_WriteMarker (&player->client.reliablebuf, svc_fireweapon); MSG_WriteByte (&player->client.reliablebuf, player->readyweapon); MSG_WriteLong (&player->client.reliablebuf, player->tic); } P_SetMobjState (player->mo, S_PLAY_ATK1); newstate = weaponinfo[player->readyweapon].atkstate; P_SetPsprite (player, ps_weapon, newstate); P_NoiseAlert (player->mo, player->mo); }
OVERLAY void A_CheckReload(player_t *player, pspdef_t *psp) { P_CheckAmmo(player); }
/* ================== iphoneBuildTiccmd Use touch and tilt controls to set up a doom ticcmd_t ================== */ static void iphoneBuildTiccmd(ticcmd_t* cmd) { memset(cmd,0,sizeof*cmd); // cmd->consistancy = consistancy[consoleplayer][maketic & BACKUPTICMASK]; if ( menuState != IPM_GAME ) { // if in the menus, always generate an empty event return; } // the respawn button triggers a use if ( respawnActive ) { cmd->buttons |= BT_USE; respawnActive = false; } if ( gamestate != GS_LEVEL ) { // at intermissions, all taps equal attack // FIXME: better latched value if ( numTouches == numPrevTouches + 1 ) { cmd->buttons |= BT_ATTACK; } return; } // don't allow movement control use during automap if ( automapmode & am_active ) { return; } // don't built a tic when dead, other than the respawn use if ( players[consoleplayer].playerstate == PST_DEAD ) { return; } //------------------------ // No controls during weapon-select screen //------------------------ boolean weaponCycle = false; if ( drawWeaponSelect ) { // if the weaponSelect overlay is up, continue tracking held touches // until the are released for ( ibutton_t *hud = (ibutton_t *)&huds ; hud != (ibutton_t *)(&huds+1) ; hud++ ) { if ( hud->touch || hud == &huds.weaponSelect ) { UpdateHudTouch( hud ); } } // Re-tapping in the weapon select area will cycle to the next weapon. // The action happens on initial touch. touch_t *t = huds.weaponSelect.touch; if ( t && t->down && t->stateCount == 1 ) { drawWeaponSelect = false; t->stateCount++; // ensure it won't bring it back up weaponCycle = true; } else { return; } } //------------------------ // gameplay controls //------------------------ // update all the hud touch states if ( menuState == IPM_GAME ) { UpdateHudTouch( &huds.forwardStick ); UpdateHudTouch( &huds.sideStick ); UpdateHudTouch( &huds.turnStick ); UpdateHudTouch( &huds.turnRotor ); UpdateHudTouch( &huds.weaponSelect ); } // tap in the lower center for weapon switch touch_t *t = huds.weaponSelect.touch; if ( t && t->down && t->stateCount == 1 ) { drawWeaponSelect = true; } // hack to let a single touch control both hud elements on combo sticks // This is dependent on the order in the structure, and probably not a good // way to do things. if ( huds.sideStick.x == huds.forwardStick.x && huds.sideStick.y == huds.forwardStick.y ) { huds.sideStick.touch = huds.forwardStick.touch; huds.sideStick.downX = huds.forwardStick.downX; huds.sideStick.downY = huds.forwardStick.downY; } if ( huds.turnStick.x == huds.forwardStick.x && huds.turnStick.y == huds.forwardStick.y ) { huds.turnStick.touch = huds.forwardStick.touch; huds.turnStick.downX = huds.forwardStick.downX; huds.turnStick.downY = huds.forwardStick.downY; } // the fire button doesn't grab touches { int x = huds.fire.x - ( huds.fire.drawWidth >> 1 ); int y = huds.fire.y - ( huds.fire.drawHeight >> 1 ); int w = huds.fire.drawWidth << 1; int h = huds.fire.drawHeight << 1; if ( AnyTouchInBounds( x, y, w, h ) ) { cmd->buttons |= BT_ATTACK; huds.fire.buttonFlags |= BF_DRAW_ACTIVE; // draw with color } else { huds.fire.buttonFlags &= ~BF_DRAW_ACTIVE; } } int forwardmove; int sidemove; // the edge of the drawn control should give the maximum // legal doom movement speed huds.forwardStick.scale = stickMove->value / 128.0f; huds.sideStick.scale = stickMove->value / 128.0f; forwardmove = -TURBOTHRESHOLD * AxisHit( &huds.forwardStick ); sidemove = TURBOTHRESHOLD * AxisHit( &huds.sideStick ); huds.turnStick.scale = stickTurn->value / 128.0f; cmd->angleturn = -1500.0f * AxisHit( &huds.turnStick ); // rotary wheel cmd->angleturn -= rotorTurn->value * RotorControl( &huds.turnRotor ); // accelerometer tilting sidemove += tiltMove->value * DeadBandAdjust( tilt, tiltDeadBand->value ); cmd->angleturn -= tiltTurn->value * DeadBandAdjust( tilt, tiltDeadBand->value ); // clamp movements cmd->forwardmove = ClampMove( forwardmove ); cmd->sidemove = ClampMove( sidemove ); // tap in the upper center for use if ( TouchPressed( 140, 0, 240, 200 ) ) { cmd->buttons |= BT_USE; } // auto-use if the game thread found a usable line in front of the player if ( autoUse->value && autoUseActive ) { if ( cmd->buttons & BT_USE ) { // Allow a tap to briefly cancel the auto-use, which works around // some issues with incorrectly started auto-uses preventing // a real door from opening. cmd->buttons &= ~BT_USE; } else { cmd->buttons |= BT_USE; } } if ( weaponSelected != -1 ) { cmd->buttons |= BT_CHANGE; cmd->buttons |= weaponSelected<<BT_WEAPONSHIFT; weaponSelected = -1; } else { // auto-cycle weapons when firing on empty if ( players[consoleplayer].attackdown && !P_CheckAmmo(&players[consoleplayer]) ) { weaponCycle = true; } // weapon switch int newweapon = wp_nochange; if ( weaponCycle ) { // witch to next weapon when out of ammo newweapon = P_SwitchWeapon(&players[consoleplayer]); } if (newweapon != wp_nochange) { cmd->buttons |= BT_CHANGE; cmd->buttons |= newweapon<<BT_WEAPONSHIFT; } } }
// Respond to keyboard input events, // intercept cheats. boolean ST_Responder (event_t* ev) { int i; // Filter automap on/off. if (ev->type == ev_keyup && ((ev->data1 & 0xffff0000) == AM_MSGHEADER)) { switch(ev->data1) { case AM_MSGENTERED: st_gamestate = AutomapState; st_firsttime = true; break; case AM_MSGEXITED: // fprintf(stderr, "AM exited\n"); st_gamestate = FirstPersonState; break; } } // if a user keypress... else if (ev->type == ev_keydown) { if (!netgame && gameskill != sk_nightmare) { // 'dqd' cheat for toggleable god mode if (cht_CheckCheat(&cheat_god, ev->data2)) { plyr->cheats ^= CF_GODMODE; if (plyr->cheats & CF_GODMODE) { if (plyr->mo) plyr->mo->health = 100; plyr->health = deh_god_mode_health; plyr->message = DEH_String(STSTR_DQDON); } else plyr->message = DEH_String(STSTR_DQDOFF); } // 'fa' cheat for killer f*****g arsenal else if (cht_CheckCheat(&cheat_ammonokey, ev->data2)) { plyr->armorpoints = deh_idfa_armor; plyr->armortype = deh_idfa_armor_class; // [crispy] give backpack if (!plyr->backpack) { for (i=0 ; i<NUMAMMO ; i++) plyr->maxammo[i] *= 2; plyr->backpack = true; } for (i=0;i<NUMWEAPONS;i++) plyr->weaponowned[i] = true; for (i=0;i<NUMAMMO;i++) plyr->ammo[i] = plyr->maxammo[i]; plyr->message = DEH_String(STSTR_FAADDED); } // 'kfa' cheat for key full ammo else if (cht_CheckCheat(&cheat_ammo, ev->data2)) { plyr->armorpoints = deh_idkfa_armor; plyr->armortype = deh_idkfa_armor_class; // [crispy] give backpack if (!plyr->backpack) { for (i=0 ; i<NUMAMMO ; i++) plyr->maxammo[i] *= 2; plyr->backpack = true; } for (i=0;i<NUMWEAPONS;i++) plyr->weaponowned[i] = true; for (i=0;i<NUMAMMO;i++) plyr->ammo[i] = plyr->maxammo[i]; for (i=0;i<NUMCARDS;i++) plyr->cards[i] = true; plyr->message = DEH_String(STSTR_KFAADDED); } // [crispy] implement Boom's "tntem" cheat else if (cht_CheckCheat(&cheat_massacre, ev->data2)) { static char msg[32]; int killcount = ST_cheat_massacre(); M_snprintf(msg, sizeof(msg), "\x1b%c%d \x1b%cMonster%s Killed", '0' + CR_GOLD, killcount, '0' + CR_RED, (killcount == 1) ? "" : "s"); plyr->message = msg; } // [crispy] implement Crispy Doom's "spechits" cheat else if (cht_CheckCheat(&cheat_spechits, ev->data2)) { static char msg[32]; int triggeredlines = ST_cheat_spechits(); M_snprintf(msg, sizeof(msg), "\x1b%c%d \x1b%cSpecial Line%s Triggered", '0' + CR_GOLD, triggeredlines, '0' + CR_RED, (triggeredlines == 1) ? "" : "s"); plyr->message = msg; } // [crispy] implement Boom's "tnthom" cheat else if (cht_CheckCheat(&cheat_hom, ev->data2)) { static char msg[32]; crispy_flashinghom = !crispy_flashinghom; M_snprintf(msg, sizeof(msg), "HOM Detection \x1b%c%s", '0' + CR_GREEN, (crispy_flashinghom) ? "ON" : "OFF"); plyr->message = msg; } // 'mus' cheat for changing music else if (cht_CheckCheat(&cheat_mus, ev->data2)) { char buf[3]; int musnum; plyr->message = DEH_String(STSTR_MUS); cht_GetParam(&cheat_mus, buf); // Note: The original v1.9 had a bug that tried to play back // the Doom II music regardless of gamemode. This was fixed // in the Ultimate Doom executable so that it would work for // the Doom 1 music as well. if (gamemode == commercial || gameversion < exe_ultimate) { musnum = mus_runnin + (buf[0]-'0')*10 + buf[1]-'0' - 1; // [crispy] prevent crash with IDMUS00 if (((buf[0]-'0')*10 + buf[1]-'0') > 35 || musnum < mus_runnin) plyr->message = DEH_String(STSTR_NOMUS); else S_ChangeMusic(musnum, 1); } else { musnum = mus_e1m1 + (buf[0]-'1')*9 + (buf[1]-'1'); // [crispy] prevent crash with IDMUS0x or IDMUSx0 if (((buf[0]-'1')*9 + buf[1]-'1') > 31 || buf[0] < '1' || buf[1] < '1') plyr->message = DEH_String(STSTR_NOMUS); else S_ChangeMusic(musnum, 1); } } // [crispy] allow both idspispopd and idclip cheats in all gamemissions else if ( ( /* logical_gamemission == doom && */ cht_CheckCheat(&cheat_noclip, ev->data2)) || ( /* logical_gamemission != doom && */ cht_CheckCheat(&cheat_commercial_noclip,ev->data2))) { // Noclip cheat. // For Doom 1, use the idspipsopd cheat; for all others, use // idclip plyr->cheats ^= CF_NOCLIP; if (plyr->cheats & CF_NOCLIP) plyr->message = DEH_String(STSTR_NCON); else plyr->message = DEH_String(STSTR_NCOFF); } // [crispy] implement PrBoom+'s "notarget" cheat else if (cht_CheckCheat(&cheat_notarget, ev->data2)) { static char msg[32]; plyr->cheats ^= CF_NOTARGET; M_snprintf(msg, sizeof(msg), "Notarget Mode \x1b%c%s", '0' + CR_GREEN, (plyr->cheats & CF_NOTARGET) ? "ON" : "OFF"); plyr->message = msg; } // 'behold?' power-up cheats for (i=0;i<6;i++) { if (cht_CheckCheat(&cheat_powerup[i], ev->data2)) { if (!plyr->powers[i]) P_GivePower( plyr, i); else if (i!=pw_strength) plyr->powers[i] = 1; else plyr->powers[i] = 0; plyr->message = DEH_String(STSTR_BEHOLDX); } } // 'behold' power-up menu if (cht_CheckCheat(&cheat_powerup[6], ev->data2)) { plyr->message = DEH_String(STSTR_BEHOLD); } // [crispy] implement Boom's "tntweap?" weapon cheats else if (cht_CheckCheat(&cheat_weapon, ev->data2)) { char buf[2]; int w; static char msg[32]; cht_GetParam(&cheat_weapon, buf); w = *buf - '1'; if (w < 0 || w >= NUMWEAPONS) return false; if (w == wp_supershotgun && !crispy_havessg) return false; if ((w == wp_bfg || w == wp_plasma) && gamemode == shareware) return false; // make '1' apply beserker strength toggle if (w == wp_fist) { if (!plyr->powers[pw_strength]) P_GivePower(plyr, pw_strength); else plyr->powers[pw_strength] = 0; M_snprintf(msg, sizeof(msg), DEH_String(STSTR_BEHOLDX)); } else { if ((plyr->weaponowned[w] = !plyr->weaponowned[w])) M_snprintf(msg, sizeof(msg), "Weapon \x1b%c%d\x1b%c Added", '0' + CR_GOLD, w + 1, '0' + CR_RED); else { M_snprintf(msg, sizeof(msg), "Weapon \x1b%c%d\x1b%c Removed", '0' + CR_GOLD, w + 1, '0' + CR_RED); // [crispy] removed current weapon, select another one if (w == plyr->readyweapon) { extern boolean P_CheckAmmo (player_t* player); P_CheckAmmo(plyr); } } } plyr->message = msg; } // 'choppers' invulnerability & chainsaw else if (cht_CheckCheat(&cheat_choppers, ev->data2)) { plyr->weaponowned[wp_chainsaw] = true; plyr->powers[pw_invulnerability] = true; plyr->message = DEH_String(STSTR_CHOPPERS); } // 'mypos' for player position else if (cht_CheckCheat(&cheat_mypos, ev->data2)) { // [crispy] show (human readable) map coordinates // in the upper right corner (like automap stats) /* static char buf[ST_MSGWIDTH]; M_snprintf(buf, sizeof(buf), "ang=0x%x;x,y=(0x%x,0x%x)", players[consoleplayer].mo->angle, players[consoleplayer].mo->x, players[consoleplayer].mo->y); plyr->message = buf; */ p2fromp(plyr)->mapcoords ^= 1; } } // 'clev' change-level cheat if (!netgame && cht_CheckCheat(&cheat_clev, ev->data2)) { char buf[3]; int epsd; int map; cht_GetParam(&cheat_clev, buf); if (gamemission == pack_nerve) { epsd = 2; map = (buf[0] - '0')*10 + buf[1] - '0'; } else if (gamemode == commercial) { epsd = 1; map = (buf[0] - '0')*10 + buf[1] - '0'; } else { epsd = buf[0] - '0'; map = buf[1] - '0'; } // Chex.exe always warps to episode 1. if (gameversion == exe_chex) { epsd = 1; } // Catch invalid maps. if (epsd == 0) // [crispy] allow IDCLEV0x to work in Doom 1 epsd = gameepisode; else if (epsd < 1) return false; if ((map == 0) && (buf[0] - '0' == 0)) // [crispy] IDCLEV00 restarts current map map = gamemap; else if (map < 1) return false; // Ohmygod - this is not going to work. if ((gamemode == retail) && ((epsd > 4) || (map > 9))) return false; if ((gamemode == registered) && ((epsd > 3) || (map > 9))) return false; if ((gamemode == shareware) && ((epsd > 1) || (map > 9))) return false; // The source release has this check as map > 34. However, Vanilla // Doom allows IDCLEV up to MAP40 even though it normally crashes. if ((gamemode == commercial && gamemission != pack_nerve) && (( epsd > 1) || (map > 40))) return false; if ((gamemission == pack_nerve) && (( epsd > 2) || (map > 9))) return false; // So be it. plyr->message = DEH_String(STSTR_CLEV); G_DeferedInitNew(gameskill, epsd, map); // [crispy] eat key press, i.e. don't change weapon upon level change return true; } } return false; }
void C_DECL A_CheckReload(player_t *player, pspdef_t *psp) { P_CheckAmmo(player); }