📄 p_pspr.c
字号:
// Emacs style mode select -*- C++ -*- //-----------------------------------------------------------------------------//// $Id: p_pspr.c,v 1.7 2001/04/04 20:24:21 judgecutor Exp $//// Copyright (C) 1993-1996 by id Software, Inc.// Portions Copyright (C) 1998-2000 by DooM Legacy Team.//// This program is free software; you can redistribute it and/or// modify it under the terms of the GNU General Public License// as published by the Free Software Foundation; either version 2// of the License, or (at your option) any later version.//// This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details.////// $Log: p_pspr.c,v $// Revision 1.7 2001/04/04 20:24:21 judgecutor// Added support for the 3D Sound//// Revision 1.6 2001/01/25 22:15:43 bpereira// added heretic support//// Revision 1.5 2000/10/21 08:43:30 bpereira// no message//// Revision 1.4 2000/10/01 10:18:18 bpereira// no message//// Revision 1.3 2000/08/31 14:30:56 bpereira// no message//// Revision 1.2 2000/02/27 00:42:10 hurdler// fix CR+LF problem//// Revision 1.1.1.1 2000/02/22 20:32:32 hurdler// Initial import into CVS (v1.29 pr3)////// DESCRIPTION:// Weapon sprite animation, weapon objects.// Action functions for weapons.////-----------------------------------------------------------------------------#include "doomdef.h"#include "d_event.h"#include "p_local.h"#include "p_pspr.h"#include "p_inter.h"#include "s_sound.h"#include "g_game.h"#include "g_input.h"#include "r_main.h"#include "m_random.h"#include "p_inter.h"#ifdef HW3SOUND#include "hardware/hw3sound.h"#endif#define LOWERSPEED FRACUNIT*6#define RAISESPEED FRACUNIT*6#define WEAPONBOTTOM 128*FRACUNIT#define WEAPONTOP 32*FRACUNIT#define FLAME_THROWER_TICS (10*TICRATE)#define MAGIC_JUNK 1234#define MAX_MACE_SPOTS 8//// P_SetPsprite//void P_SetPsprite ( player_t* player, int position, statenum_t stnum ){ pspdef_t* psp; state_t* state; psp = &player->psprites[position]; do { if (!stnum) { // object removed itself psp->state = NULL; break; }#ifdef PARANOIA if(stnum>=NUMSTATES) I_Error("P_SetPsprite : state %d unknown\n",stnum);#endif state = &states[stnum]; psp->state = state; psp->tics = state->tics; // could be 0/* UNUSED if (state->misc1) { // coordinate set psp->sx = state->misc1 << FRACBITS; psp->sy = state->misc2 << FRACBITS; }*/ // Call action routine. // Modified handling. if (state->action.acp2) { state->action.acp2(player, psp); if (!psp->state) break; } stnum = psp->state->nextstate; } while (!psp->tics); // an initial state of 0 could cycle through}//// P_CalcSwing///* BP: UNUSEDfixed_t swingx;fixed_t swingy;void P_CalcSwing (player_t* player){ fixed_t swing; int angle; // OPTIMIZE: tablify this. // A LUT would allow for different modes, // and add flexibility. swing = player->bob; angle = (FINEANGLES/70*leveltime)&FINEMASK; swingx = FixedMul ( swing, finesine[angle]); angle = (FINEANGLES/70*leveltime+FINEANGLES/2)&FINEMASK; swingy = -FixedMul ( swingx, finesine[angle]);}*///// P_BringUpWeapon// Starts bringing the pending weapon up// from the bottom of the screen.// Uses player//void P_BringUpWeapon (player_t* player){ statenum_t newstate; if (player->pendingweapon == wp_nochange) player->pendingweapon = player->readyweapon; if (player->pendingweapon == wp_chainsaw)#ifdef HW3SOUND S_StartAttackSound(player->mo, sfx_sawup);#else S_StartSound (player->mo, sfx_sawup);#endif#ifdef PARANOIA if(player->pendingweapon>=NUMWEAPONS) { I_Error("P_BringUpWeapon : pendingweapon %d\n",player->pendingweapon); }#endif newstate = player->weaponinfo[player->pendingweapon].upstate; player->pendingweapon = wp_nochange; player->psprites[ps_weapon].sy = WEAPONBOTTOM; P_SetPsprite (player, ps_weapon, newstate);}//// P_CheckAmmo// Returns true if there is enough ammo to shoot.// If not, selects the next weapon to use.//boolean P_CheckAmmo (player_t* player){ ammotype_t ammo; int count; ammo = player->weaponinfo[player->readyweapon].ammo; // Minimal amount for one shot varies. count = player->weaponinfo[player->readyweapon].ammopershoot; // Some do not need ammunition anyway. // Return if current ammunition sufficient. if (ammo == am_noammo || player->ammo[ammo] >= count) return true; // Out of ammo, pick a weapon to change to. // Preferences are set here. // added by Boris : preferred weapons order if(!player->originalweaponswitch) VerifFavoritWeapon(player); else // eof Boris if( gamemode == heretic ) do { if(player->weaponowned[wp_skullrod] && player->ammo[am_skullrod] > player->weaponinfo[wp_skullrod].ammopershoot) { player->pendingweapon = wp_skullrod; } else if(player->weaponowned[wp_blaster] && player->ammo[am_blaster] > player->weaponinfo[wp_blaster].ammopershoot) { player->pendingweapon = wp_blaster; } else if(player->weaponowned[wp_crossbow] && player->ammo[am_crossbow] > player->weaponinfo[wp_crossbow].ammopershoot) { player->pendingweapon = wp_crossbow; } else if(player->weaponowned[wp_mace] && player->ammo[am_mace] > player->weaponinfo[wp_mace].ammopershoot) { player->pendingweapon = wp_mace; } else if(player->ammo[am_goldwand] > player->weaponinfo[wp_goldwand].ammopershoot) { player->pendingweapon = wp_goldwand; } else if(player->weaponowned[wp_gauntlets]) { player->pendingweapon = wp_gauntlets; } else if(player->weaponowned[wp_phoenixrod] && player->ammo[am_phoenixrod] > player->weaponinfo[wp_phoenixrod].ammopershoot) { player->pendingweapon = wp_phoenixrod; } else { player->pendingweapon = wp_staff; } } while(player->pendingweapon == wp_nochange); else do { if (player->weaponowned[wp_plasma] && player->ammo[am_cell]>=player->weaponinfo[wp_plasma].ammopershoot && (gamemode != shareware) ) { player->pendingweapon = wp_plasma; } else if (player->weaponowned[wp_supershotgun] && player->ammo[am_shell]>=player->weaponinfo[wp_supershotgun].ammopershoot && (gamemode == commercial) ) { player->pendingweapon = wp_supershotgun; } else if (player->weaponowned[wp_chaingun] && player->ammo[am_clip]>=player->weaponinfo[wp_chaingun].ammopershoot) { player->pendingweapon = wp_chaingun; } else if (player->weaponowned[wp_shotgun] && player->ammo[am_shell]>=player->weaponinfo[wp_shotgun].ammopershoot) { player->pendingweapon = wp_shotgun; } else if (player->ammo[am_clip]>=player->weaponinfo[wp_pistol].ammopershoot) { player->pendingweapon = wp_pistol; } else if (player->weaponowned[wp_chainsaw]) { player->pendingweapon = wp_chainsaw; } else if (player->weaponowned[wp_missile] && player->ammo[am_misl]>=player->weaponinfo[wp_missile].ammopershoot) { player->pendingweapon = wp_missile; } else if (player->weaponowned[wp_bfg] && player->ammo[am_cell]>=player->weaponinfo[wp_bfg].ammopershoot && (gamemode != shareware) ) { player->pendingweapon = wp_bfg; } else { // If everything fails. player->pendingweapon = wp_fist; } } while (player->pendingweapon == wp_nochange); // Now set appropriate weapon overlay. P_SetPsprite (player, ps_weapon, player->weaponinfo[player->readyweapon].downstate); return false;}//// P_FireWeapon.//void P_FireWeapon (player_t* player){ statenum_t newstate; if (!P_CheckAmmo (player)) return; if( gamemode == heretic ) { P_SetMobjState(player->mo, S_PLAY_ATK2); newstate = player->refire ? player->weaponinfo[player->readyweapon].holdatkstate : player->weaponinfo[player->readyweapon].atkstate; // Play the sound for the initial gauntlet attack if( player->readyweapon == wp_gauntlets && !player->refire ) S_StartSound(player->mo, sfx_gntuse); } else { P_SetMobjState (player->mo, S_PLAY_ATK1); newstate = player->weaponinfo[player->readyweapon].atkstate; } P_SetPsprite (player, ps_weapon, newstate); P_NoiseAlert (player->mo, player->mo);}//// P_DropWeapon// Player died, so put the weapon away.//void P_DropWeapon (player_t* player){ P_SetPsprite (player, ps_weapon, player->weaponinfo[player->readyweapon].downstate);}//// A_WeaponReady// The player can fire the weapon// or change to another weapon at this time.// Follows after getting weapon up,// or after previous attack/fire sequence.//void A_WeaponReady ( player_t* player, pspdef_t* psp ){ if(player->chickenTics) { // Change to the chicken beak P_ActivateBeak(player); return; } // get out of attack state if (player->mo->state == &states[S_PLAY_ATK1] || player->mo->state == &states[S_PLAY_ATK2] ) { P_SetMobjState (player->mo, S_PLAY); } if (player->readyweapon == wp_chainsaw && psp->state == &states[S_SAW]) {#ifdef HW3SOUND S_StartAttackSound(player->mo, sfx_sawidl);#else S_StartSound (player->mo, sfx_sawidl);#endif } // Check for staff PL2 active sound if((player->readyweapon == wp_staff) && (psp->state == &states[S_STAFFREADY2_1]) && P_Random() < 128) {#ifdef HW3SOUND S_StartAttackSound(player->mo, sfx_stfcrk);#else S_StartSound(player->mo, sfx_stfcrk);#endif } // check for change // if player is dead, put the weapon away if (player->pendingweapon != wp_nochange || !player->health) { // change weapon // (pending weapon should allready be validated) P_SetPsprite (player, ps_weapon, player->weaponinfo[player->readyweapon].downstate); return; } // check for fire // the missile launcher and bfg do not auto fire if (player->cmd.buttons & BT_ATTACK) { if ( !player->attackdown || (player->readyweapon != wp_missile && (player->readyweapon != wp_bfg || gamemode == heretic)) ) { player->attackdown = true; P_FireWeapon (player); return; } } else player->attackdown = false;#ifndef CLIENTPREDICTION2 { int angle; // bob the weapon based on movement speed angle = (128*leveltime/NEWTICRATERATIO)&FINEMASK; psp->sx = FRACUNIT + FixedMul (player->bob, finecosine[angle]); angle &= FINEANGLES/2-1; psp->sy = WEAPONTOP + FixedMul (player->bob, finesine[angle]); }#endif}// client prediction stuffvoid A_TicWeapon(player_t* player, pspdef_t* psp ){ if( (void*)psp->state->action.acp2 == (void*)A_WeaponReady && psp->tics == psp->state->tics ) { int angle; // bob the weapon based on movement speed angle = (128*localgametic/NEWTICRATERATIO)&FINEMASK; psp->sx = FRACUNIT + FixedMul (player->bob, finecosine[angle]); angle &= FINEANGLES/2-1; psp->sy = WEAPONTOP + FixedMul (player->bob, finesine[angle]); }}//// 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); }}voidA_CheckReload( player_t* player, pspdef_t* psp ){ P_CheckAmmo (player);#if 0 if (player->ammo[am_shell]<2) P_SetPsprite (player, ps_weapon, S_DSNR1);#endif}//// A_Lower// Lowers current weapon,// and changes weapon at bottom.//void A_Lower ( player_t* player, pspdef_t* psp ){ if(player->chickenTics) psp->sy = WEAPONBOTTOM; else psp->sy += LOWERSPEED; // Is already down. if (psp->sy < WEAPONBOTTOM ) return; // Player is dead. if (player->playerstate == PST_DEAD) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -