📄 p_pspr.c
字号:
//**************************************************************************//**//** p_pspr.c : Heretic 2 : Raven Software, Corp.//**//** $RCSfile: p_pspr.c,v $//** $Revision: 1.105 $//** $Date: 96/01/06 03:23:35 $//** $Author: bgokey $//**//**************************************************************************// HEADER FILES ------------------------------------------------------------#include "h2def.h"#include "p_local.h"#include "soundst.h"// MACROS ------------------------------------------------------------------#define LOWERSPEED FRACUNIT*6#define RAISESPEED FRACUNIT*6#define WEAPONBOTTOM 128*FRACUNIT#define WEAPONTOP 32*FRACUNIT// TYPES -------------------------------------------------------------------// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------extern void P_ExplodeMissile(mobj_t *mo);extern void A_UnHideThing(mobj_t *actor);// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------// EXTERNAL DATA DECLARATIONS ----------------------------------------------extern fixed_t FloatBobOffsets[64];// PUBLIC DATA DEFINITIONS -------------------------------------------------fixed_t bulletslope;weaponinfo_t WeaponInfo[NUMWEAPONS][NUMCLASSES] ={ { // First Weapons { // Fighter First Weapon - Punch MANA_NONE, // mana S_PUNCHUP, // upstate S_PUNCHDOWN, // downstate S_PUNCHREADY, // readystate S_PUNCHATK1_1, // atkstate S_PUNCHATK1_1, // holdatkstate S_NULL // flashstate }, { // Cleric First Weapon - Mace MANA_NONE, // mana S_CMACEUP, // upstate S_CMACEDOWN, // downstate S_CMACEREADY, // readystate S_CMACEATK_1, // atkstate S_CMACEATK_1, // holdatkstate S_NULL // flashstate }, { // Mage First Weapon - Wand MANA_NONE, S_MWANDUP, S_MWANDDOWN, S_MWANDREADY, S_MWANDATK_1, S_MWANDATK_1, S_NULL }, { // Pig - Snout MANA_NONE, // mana S_SNOUTUP, // upstate S_SNOUTDOWN, // downstate S_SNOUTREADY, // readystate S_SNOUTATK1, // atkstate S_SNOUTATK1, // holdatkstate S_NULL // flashstate } }, { // Second Weapons { // Fighter - Axe MANA_NONE, // mana S_FAXEUP, // upstate S_FAXEDOWN, // downstate S_FAXEREADY, // readystate S_FAXEATK_1, // atkstate S_FAXEATK_1, // holdatkstate S_NULL // flashstate }, { // Cleric - Serpent Staff MANA_1, // mana S_CSTAFFUP, // upstate S_CSTAFFDOWN, // downstate S_CSTAFFREADY, // readystate S_CSTAFFATK_1, // atkstate S_CSTAFFATK_1, // holdatkstate S_NULL // flashstate }, { // Mage - Cone of shards MANA_1, // mana S_CONEUP, // upstate S_CONEDOWN, // downstate S_CONEREADY, // readystate S_CONEATK1_1, // atkstate S_CONEATK1_3, // holdatkstate S_NULL // flashstate }, { // Pig - Snout MANA_NONE, // mana S_SNOUTUP, // upstate S_SNOUTDOWN, // downstate S_SNOUTREADY, // readystate S_SNOUTATK1, // atkstate S_SNOUTATK1, // holdatkstate S_NULL // flashstate } }, { // Third Weapons { // Fighter - Hammer MANA_NONE, // mana S_FHAMMERUP, // upstate S_FHAMMERDOWN, // downstate S_FHAMMERREADY, // readystate S_FHAMMERATK_1, // atkstate S_FHAMMERATK_1, // holdatkstate S_NULL // flashstate }, { // Cleric - Flame Strike MANA_2, // mana S_CFLAMEUP, // upstate S_CFLAMEDOWN, // downstate S_CFLAMEREADY1, // readystate S_CFLAMEATK_1, // atkstate S_CFLAMEATK_1, // holdatkstate S_NULL // flashstate }, { // Mage - Lightning MANA_2, // mana S_MLIGHTNINGUP, // upstate S_MLIGHTNINGDOWN, // downstate S_MLIGHTNINGREADY, // readystate S_MLIGHTNINGATK_1, // atkstate S_MLIGHTNINGATK_1, // holdatkstate S_NULL // flashstate }, { // Pig - Snout MANA_NONE, // mana S_SNOUTUP, // upstate S_SNOUTDOWN, // downstate S_SNOUTREADY, // readystate S_SNOUTATK1, // atkstate S_SNOUTATK1, // holdatkstate S_NULL // flashstate } }, { // Fourth Weapons { // Fighter - Rune Sword MANA_BOTH, // mana S_FSWORDUP, // upstate S_FSWORDDOWN, // downstate S_FSWORDREADY, // readystate S_FSWORDATK_1, // atkstate S_FSWORDATK_1, // holdatkstate S_NULL // flashstate }, { // Cleric - Holy Symbol MANA_BOTH, // mana S_CHOLYUP, // upstate S_CHOLYDOWN, // downstate S_CHOLYREADY, // readystate S_CHOLYATK_1, // atkstate S_CHOLYATK_1, // holdatkstate S_NULL // flashstate }, { // Mage - Staff MANA_BOTH, // mana S_MSTAFFUP, // upstate S_MSTAFFDOWN, // downstate S_MSTAFFREADY, // readystate S_MSTAFFATK_1, // atkstate S_MSTAFFATK_1, // holdatkstate S_NULL // flashstate }, { // Pig - Snout MANA_NONE, // mana S_SNOUTUP, // upstate S_SNOUTDOWN, // downstate S_SNOUTREADY, // readystate S_SNOUTATK1, // atkstate S_SNOUTATK1, // holdatkstate S_NULL // flashstate } }};// PRIVATE DATA DEFINITIONS ------------------------------------------------static int WeaponManaUse[NUMCLASSES][NUMWEAPONS] = { { 0, 2, 3, 14 }, { 0, 1, 4, 18 }, { 0, 3, 5, 15 }, { 0, 0, 0, 0 }};// CODE --------------------------------------------------------------------//---------------------------------------------------------------------------//// PROC 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; } state = &states[stnum]; psp->state = state; psp->tics = state->tics; // could be 0 if(state->misc1) { // Set coordinates. psp->sx = state->misc1<<FRACBITS; } if(state->misc2) { psp->sy = state->misc2<<FRACBITS; } if(state->action) { // Call action routine. state->action(player, psp); if(!psp->state) { break; } } stnum = psp->state->nextstate; } while(!psp->tics); // An initial state of 0 could cycle through.}//---------------------------------------------------------------------------//// PROC P_SetPspriteNF//// Identical to P_SetPsprite, without calling the action function//---------------------------------------------------------------------------void P_SetPspriteNF(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; } state = &states[stnum]; psp->state = state; psp->tics = state->tics; // could be 0 if(state->misc1) { // Set coordinates. psp->sx = state->misc1<<FRACBITS; } if(state->misc2) { psp->sy = state->misc2<<FRACBITS; } stnum = psp->state->nextstate; } while(!psp->tics); // An initial state of 0 could cycle through.}/*=================== P_CalcSwing==================*//*fixed_t swingx, swingy;void P_CalcSwing (player_t *player){ fixed_t swing; int angle;// OPTIMIZE: tablify this 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]);}*///---------------------------------------------------------------------------//// PROC P_ActivateMorphWeapon////---------------------------------------------------------------------------void P_ActivateMorphWeapon(player_t *player){ player->pendingweapon = WP_NOCHANGE; player->psprites[ps_weapon].sy = WEAPONTOP; player->readyweapon = WP_FIRST; // Snout is the first weapon P_SetPsprite(player, ps_weapon, S_SNOUTREADY);}//---------------------------------------------------------------------------//// PROC P_PostMorphWeapon////---------------------------------------------------------------------------void P_PostMorphWeapon(player_t *player, weapontype_t weapon){ player->pendingweapon = WP_NOCHANGE; player->readyweapon = weapon; player->psprites[ps_weapon].sy = WEAPONBOTTOM; P_SetPsprite(player, ps_weapon, WeaponInfo[weapon][player->class].upstate);}//---------------------------------------------------------------------------//// PROC P_BringUpWeapon//// Starts bringing the pending weapon up from the bottom of the screen.////---------------------------------------------------------------------------void P_BringUpWeapon(player_t *player){ statenum_t new; if(player->pendingweapon == WP_NOCHANGE) { player->pendingweapon = player->readyweapon; } if(player->class == PCLASS_FIGHTER && player->pendingweapon == WP_SECOND && player->mana[MANA_1]) { new = S_FAXEUP_G; } else { new = WeaponInfo[player->pendingweapon][player->class].upstate; } player->pendingweapon = WP_NOCHANGE; player->psprites[ps_weapon].sy = WEAPONBOTTOM; P_SetPsprite(player, ps_weapon, new);}//---------------------------------------------------------------------------//// FUNC P_CheckMana//// Returns true if there is enough mana to shoot. If not, selects the// next weapon to use.////---------------------------------------------------------------------------boolean P_CheckMana(player_t *player){ manatype_t mana; int count; mana = WeaponInfo[player->readyweapon][player->class].mana; count = WeaponManaUse[player->class][player->readyweapon]; if(mana == MANA_BOTH) { if(player->mana[MANA_1] >= count && player->mana[MANA_2] >= count) { return true; } } else if(mana == MANA_NONE || player->mana[mana] >= count) { return(true); } // out of mana, pick a weapon to change to do { if(player->weaponowned[WP_THIRD] && player->mana[MANA_2] >= WeaponManaUse[player->class][WP_THIRD]) { player->pendingweapon = WP_THIRD; } else if(player->weaponowned[WP_SECOND] && player->mana[MANA_1] >= WeaponManaUse[player->class][WP_SECOND]) { player->pendingweapon = WP_SECOND; } else if(player->weaponowned[WP_FOURTH] && player->mana[MANA_1] >= WeaponManaUse[player->class][WP_FOURTH] && player->mana[MANA_2] >= WeaponManaUse[player->class][WP_FOURTH]) { player->pendingweapon = WP_FOURTH; } else { player->pendingweapon = WP_FIRST; } } while(player->pendingweapon == WP_NOCHANGE); P_SetPsprite(player, ps_weapon, WeaponInfo[player->readyweapon][player->class].downstate); return(false);}//---------------------------------------------------------------------------//// PROC P_FireWeapon////---------------------------------------------------------------------------void P_FireWeapon(player_t *player){ statenum_t attackState; if(!P_CheckMana(player)) { return; } P_SetMobjState(player->mo, PStateAttack[player->class]); // S_PLAY_ATK1); if(player->class == PCLASS_FIGHTER && player->readyweapon == WP_SECOND && player->mana[MANA_1] > 0) { // Glowing axe attackState = S_FAXEATK_G1; } else { attackState = player->refire ? WeaponInfo[player->readyweapon][player->class].holdatkstate : WeaponInfo[player->readyweapon][player->class].atkstate; } P_SetPsprite(player, ps_weapon, attackState); P_NoiseAlert(player->mo, player->mo);}//---------------------------------------------------------------------------//// PROC P_DropWeapon//// The player died, so put the weapon away.////---------------------------------------------------------------------------void P_DropWeapon(player_t *player){ P_SetPsprite(player, ps_weapon, WeaponInfo[player->readyweapon][player->class].downstate);}//---------------------------------------------------------------------------//// PROC A_WeaponReady//// The player can fire the weapon or change to another weapon at this time.////---------------------------------------------------------------------------void A_WeaponReady(player_t *player, pspdef_t *psp){ int angle; // Change player from attack state if(player->mo->state >= &states[PStateAttack[player->class]] && player->mo->state <= &states[PStateAttackEnd[player->class]]) { P_SetMobjState(player->mo, PStateNormal[player->class]); } // Put the weapon away if the player has a pending weapon or has // died. if(player->pendingweapon != WP_NOCHANGE || !player->health) { P_SetPsprite(player, ps_weapon, WeaponInfo[player->readyweapon][player->class].downstate); return; } // Check for fire. if(player->cmd.buttons&BT_ATTACK) { player->attackdown = true; P_FireWeapon(player); return; } else { player->attackdown = false; } if(!player->morphTics) { // Bob the weapon based on movement speed. angle = (128*leveltime)&FINEMASK; psp->sx = FRACUNIT+FixedMul(player->bob, finecosine[angle]); angle &= FINEANGLES/2-1; psp->sy = WEAPONTOP+FixedMul(player->bob, finesine[angle]); }}//---------------------------------------------------------------------------//// PROC A_ReFire//// The player can re fire the weapon without lowering it entirely.////---------------------------------------------------------------------------void A_ReFire(player_t *player, pspdef_t *psp){ if((player->cmd.buttons&BT_ATTACK) && player->pendingweapon == WP_NOCHANGE && player->health) { player->refire++; P_FireWeapon(player); } else { player->refire = 0; P_CheckMana(player); }}//---------------------------------------------------------------------------//// PROC A_Lower////---------------------------------------------------------------------------void A_Lower(player_t *player, pspdef_t *psp){ if(player->morphTics) { psp->sy = WEAPONBOTTOM; } else { psp->sy += LOWERSPEED; } if(psp->sy < WEAPONBOTTOM) { // Not lowered all the way yet return; } if(player->playerstate == PST_DEAD) { // Player is dead, so don't bring up a pending weapon psp->sy = WEAPONBOTTOM; return; } if(!player->health) { // Player is dead, so keep the weapon off screen P_SetPsprite(player, ps_weapon, S_NULL); return; } player->readyweapon = player->pendingweapon; P_BringUpWeapon(player);}//---------------------------------------------------------------------------//// PROC A_Raise////---------------------------------------------------------------------------void A_Raise(player_t *player, pspdef_t *psp){ psp->sy -= RAISESPEED; if(psp->sy > WEAPONTOP) { // Not raised all the way yet return; } psp->sy = WEAPONTOP; if(player->class == PCLASS_FIGHTER && player->readyweapon == WP_SECOND && player->mana[MANA_1]) { P_SetPsprite(player, ps_weapon, S_FAXEREADY_G); } else { P_SetPsprite(player, ps_weapon, WeaponInfo[player->readyweapon][player->class].readystate); }}/*================= P_BulletSlope== Sets a slope so a near miss is at aproximately the height of the= intended target=
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -