Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. // Emacs style mode select   -*- C++ -*-
  2. //-----------------------------------------------------------------------------
  3. //
  4. // $Id:$
  5. //
  6. // Copyright (C) 1993-1996 by id Software, Inc.
  7. //
  8. // This source is available for distribution and/or modification
  9. // only under the terms of the DOOM Source Code License as
  10. // published by id Software. All rights reserved.
  11. //
  12. // The source is distributed in the hope that it will be useful,
  13. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
  15. // for more details.
  16. //
  17. // $Log:$
  18. //
  19. // DESCRIPTION:
  20. //      Weapon sprite animation, weapon objects.
  21. //      Action functions for weapons.
  22. //
  23. //-----------------------------------------------------------------------------
  24.  
  25. static const char
  26. rcsid[] = "$Id: p_pspr.c,v 1.5 1997/02/03 22:45:12 b1 Exp $";
  27.  
  28. #include "doomdef.h"
  29. #include "d_event.h"
  30.  
  31.  
  32. #include "m_random.h"
  33. #include "p_local.h"
  34. #include "s_sound.h"
  35.  
  36. // State.
  37. #include "doomstat.h"
  38.  
  39. // Data.
  40. #include "sounds.h"
  41.  
  42. #include "p_pspr.h"
  43.  
  44. #define LOWERSPEED              FRACUNIT*6
  45. #define RAISESPEED              FRACUNIT*6
  46.  
  47. #define WEAPONBOTTOM    128*FRACUNIT
  48. #define WEAPONTOP               32*FRACUNIT
  49.  
  50.  
  51. // plasma cells for a bfg attack
  52. #define BFGCELLS                40             
  53.  
  54.  
  55. //
  56. // P_SetPsprite
  57. //
  58. void
  59. P_SetPsprite
  60. ( player_t*     player,
  61.   int           position,
  62.   statenum_t    stnum )
  63. {
  64.     pspdef_t*   psp;
  65.     state_t*    state;
  66.        
  67.     psp = &player->psprites[position];
  68.        
  69.     do
  70.     {
  71.         if (!stnum)
  72.         {
  73.             // object removed itself
  74.             psp->state = NULL;
  75.             break;     
  76.         }
  77.        
  78.         state = &states[stnum];
  79.         psp->state = state;
  80.         psp->tics = state->tics;        // could be 0
  81.  
  82.         if (state->misc1)
  83.         {
  84.             // coordinate set
  85.             psp->sx = state->misc1 << FRACBITS;
  86.             psp->sy = state->misc2 << FRACBITS;
  87.         }
  88.        
  89.         // Call action routine.
  90.         // Modified handling.
  91.         if (state->action.acp2)
  92.         {
  93.             state->action.acp2(player, psp);
  94.             if (!psp->state)
  95.                 break;
  96.         }
  97.        
  98.         stnum = psp->state->nextstate;
  99.        
  100.     } while (!psp->tics);
  101.     // an initial state of 0 could cycle through
  102. }
  103.  
  104.  
  105.  
  106. //
  107. // P_CalcSwing
  108. //     
  109. fixed_t         swingx;
  110. fixed_t         swingy;
  111.  
  112. void P_CalcSwing (player_t*     player)
  113. {
  114.     fixed_t     swing;
  115.     int         angle;
  116.        
  117.     // OPTIMIZE: tablify this.
  118.     // A LUT would allow for different modes,
  119.     //  and add flexibility.
  120.  
  121.     swing = player->bob;
  122.  
  123.     angle = (FINEANGLES/70*leveltime)&FINEMASK;
  124.     swingx = FixedMul ( swing, finesine[angle]);
  125.  
  126.     angle = (FINEANGLES/70*leveltime+FINEANGLES/2)&FINEMASK;
  127.     swingy = -FixedMul ( swingx, finesine[angle]);
  128. }
  129.  
  130.  
  131.  
  132. //
  133. // P_BringUpWeapon
  134. // Starts bringing the pending weapon up
  135. // from the bottom of the screen.
  136. // Uses player
  137. //
  138. void P_BringUpWeapon (player_t* player)
  139. {
  140.     statenum_t  newstate;
  141.        
  142.     if (player->pendingweapon == wp_nochange)
  143.         player->pendingweapon = player->readyweapon;
  144.                
  145.     if (player->pendingweapon == wp_chainsaw)
  146.         S_StartSound (player->mo, sfx_sawup);
  147.                
  148.     newstate = weaponinfo[player->pendingweapon].upstate;
  149.  
  150.     player->pendingweapon = wp_nochange;
  151.     player->psprites[ps_weapon].sy = WEAPONBOTTOM;
  152.  
  153.     P_SetPsprite (player, ps_weapon, newstate);
  154. }
  155.  
  156. //
  157. // P_CheckAmmo
  158. // Returns true if there is enough ammo to shoot.
  159. // If not, selects the next weapon to use.
  160. //
  161. boolean P_CheckAmmo (player_t* player)
  162. {
  163.     ammotype_t          ammo;
  164.     int                 count;
  165.  
  166.     ammo = weaponinfo[player->readyweapon].ammo;
  167.  
  168.     // Minimal amount for one shot varies.
  169.     if (player->readyweapon == wp_bfg)
  170.         count = BFGCELLS;
  171.     else if (player->readyweapon == wp_supershotgun)
  172.         count = 2;      // Double barrel.
  173.     else
  174.         count = 1;      // Regular.
  175.  
  176.     // Some do not need ammunition anyway.
  177.     // Return if current ammunition sufficient.
  178.     if (ammo == am_noammo || player->ammo[ammo] >= count)
  179.         return true;
  180.                
  181.     // Out of ammo, pick a weapon to change to.
  182.     // Preferences are set here.
  183.     do
  184.     {
  185.         if (player->weaponowned[wp_plasma]
  186.             && player->ammo[am_cell]
  187.             && (gamemode != shareware) )
  188.         {
  189.             player->pendingweapon = wp_plasma;
  190.         }
  191.         else if (player->weaponowned[wp_supershotgun]
  192.                  && player->ammo[am_shell]>2
  193.                  && (gamemode == commercial) )
  194.         {
  195.             player->pendingweapon = wp_supershotgun;
  196.         }
  197.         else if (player->weaponowned[wp_chaingun]
  198.                  && player->ammo[am_clip])
  199.         {
  200.             player->pendingweapon = wp_chaingun;
  201.         }
  202.         else if (player->weaponowned[wp_shotgun]
  203.                  && player->ammo[am_shell])
  204.         {
  205.             player->pendingweapon = wp_shotgun;
  206.         }
  207.         else if (player->ammo[am_clip])
  208.         {
  209.             player->pendingweapon = wp_pistol;
  210.         }
  211.         else if (player->weaponowned[wp_chainsaw])
  212.         {
  213.             player->pendingweapon = wp_chainsaw;
  214.         }
  215.         else if (player->weaponowned[wp_missile]
  216.                  && player->ammo[am_misl])
  217.         {
  218.             player->pendingweapon = wp_missile;
  219.         }
  220.         else if (player->weaponowned[wp_bfg]
  221.                  && player->ammo[am_cell]>40
  222.                  && (gamemode != shareware) )
  223.         {
  224.             player->pendingweapon = wp_bfg;
  225.         }
  226.         else
  227.         {
  228.             // If everything fails.
  229.             player->pendingweapon = wp_fist;
  230.         }
  231.        
  232.     } while (player->pendingweapon == wp_nochange);
  233.  
  234.     // Now set appropriate weapon overlay.
  235.     P_SetPsprite (player,
  236.                   ps_weapon,
  237.                   weaponinfo[player->readyweapon].downstate);
  238.  
  239.     return false;      
  240. }
  241.  
  242.  
  243. //
  244. // P_FireWeapon.
  245. //
  246. void P_FireWeapon (player_t* player)
  247. {
  248.     statenum_t  newstate;
  249.        
  250.     if (!P_CheckAmmo (player))
  251.         return;
  252.        
  253.     P_SetMobjState (player->mo, S_PLAY_ATK1);
  254.     newstate = weaponinfo[player->readyweapon].atkstate;
  255.     P_SetPsprite (player, ps_weapon, newstate);
  256.     P_NoiseAlert (player->mo, player->mo);
  257. }
  258.  
  259.  
  260.  
  261. //
  262. // P_DropWeapon
  263. // Player died, so put the weapon away.
  264. //
  265. void P_DropWeapon (player_t* player)
  266. {
  267.     P_SetPsprite (player,
  268.                   ps_weapon,
  269.                   weaponinfo[player->readyweapon].downstate);
  270. }
  271.  
  272.  
  273.  
  274. //
  275. // A_WeaponReady
  276. // The player can fire the weapon
  277. // or change to another weapon at this time.
  278. // Follows after getting weapon up,
  279. // or after previous attack/fire sequence.
  280. //
  281. void
  282. A_WeaponReady
  283. ( player_t*     player,
  284.   pspdef_t*     psp )
  285. {      
  286.     statenum_t  newstate;
  287.     int         angle;
  288.    
  289.     // get out of attack state
  290.     if (player->mo->state == &states[S_PLAY_ATK1]
  291.         || player->mo->state == &states[S_PLAY_ATK2] )
  292.     {
  293.         P_SetMobjState (player->mo, S_PLAY);
  294.     }
  295.    
  296.     if (player->readyweapon == wp_chainsaw
  297.         && psp->state == &states[S_SAW])
  298.     {
  299.         S_StartSound (player->mo, sfx_sawidl);
  300.     }
  301.    
  302.     // check for change
  303.     //  if player is dead, put the weapon away
  304.     if (player->pendingweapon != wp_nochange || !player->health)
  305.     {
  306.         // change weapon
  307.         //  (pending weapon should allready be validated)
  308.         newstate = weaponinfo[player->readyweapon].downstate;
  309.         P_SetPsprite (player, ps_weapon, newstate);
  310.         return;
  311.     }
  312.    
  313.     // check for fire
  314.     //  the missile launcher and bfg do not auto fire
  315.     if (player->cmd.buttons & BT_ATTACK)
  316.     {
  317.         if ( !player->attackdown
  318.              || (player->readyweapon != wp_missile
  319.                  && player->readyweapon != wp_bfg) )
  320.         {
  321.             player->attackdown = true;
  322.             P_FireWeapon (player);             
  323.             return;
  324.         }
  325.     }
  326.     else
  327.         player->attackdown = false;
  328.    
  329.     // bob the weapon based on movement speed
  330.     angle = (128*leveltime)&FINEMASK;
  331.     psp->sx = FRACUNIT + FixedMul (player->bob, finecosine[angle]);
  332.     angle &= FINEANGLES/2-1;
  333.     psp->sy = WEAPONTOP + FixedMul (player->bob, finesine[angle]);
  334. }
  335.  
  336.  
  337.  
  338. //
  339. // A_ReFire
  340. // The player can re-fire the weapon
  341. // without lowering it entirely.
  342. //
  343. void A_ReFire
  344. ( player_t*     player,
  345.   pspdef_t*     psp )
  346. {
  347.    
  348.     // check for fire
  349.     //  (if a weaponchange is pending, let it go through instead)
  350.     if ( (player->cmd.buttons & BT_ATTACK)
  351.          && player->pendingweapon == wp_nochange
  352.          && player->health)
  353.     {
  354.         player->refire++;
  355.         P_FireWeapon (player);
  356.     }
  357.     else
  358.     {
  359.         player->refire = 0;
  360.         P_CheckAmmo (player);
  361.     }
  362. }
  363.  
  364.  
  365. void
  366. A_CheckReload
  367. ( player_t*     player,
  368.   pspdef_t*     psp )
  369. {
  370.     P_CheckAmmo (player);
  371. #if 0
  372.     if (player->ammo[am_shell]<2)
  373.         P_SetPsprite (player, ps_weapon, S_DSNR1);
  374. #endif
  375. }
  376.  
  377.  
  378.  
  379. //
  380. // A_Lower
  381. // Lowers current weapon,
  382. //  and changes weapon at bottom.
  383. //
  384. void
  385. A_Lower
  386. ( player_t*     player,
  387.   pspdef_t*     psp )
  388. {      
  389.     psp->sy += LOWERSPEED;
  390.  
  391.     // Is already down.
  392.     if (psp->sy < WEAPONBOTTOM )
  393.         return;
  394.  
  395.     // Player is dead.
  396.     if (player->playerstate == PST_DEAD)
  397.     {
  398.         psp->sy = WEAPONBOTTOM;
  399.  
  400.         // don't bring weapon back up
  401.         return;        
  402.     }
  403.    
  404.     // The old weapon has been lowered off the screen,
  405.     // so change the weapon and start raising it
  406.     if (!player->health)
  407.     {
  408.         // Player is dead, so keep the weapon off screen.
  409.         P_SetPsprite (player,  ps_weapon, S_NULL);
  410.         return;
  411.     }
  412.        
  413.     player->readyweapon = player->pendingweapon;
  414.  
  415.     P_BringUpWeapon (player);
  416. }
  417.  
  418.  
  419. //
  420. // A_Raise
  421. //
  422. void
  423. A_Raise
  424. ( player_t*     player,
  425.   pspdef_t*     psp )
  426. {
  427.     statenum_t  newstate;
  428.        
  429.     psp->sy -= RAISESPEED;
  430.  
  431.     if (psp->sy > WEAPONTOP )
  432.         return;
  433.    
  434.     psp->sy = WEAPONTOP;
  435.    
  436.     // The weapon has been raised all the way,
  437.     //  so change to the ready state.
  438.     newstate = weaponinfo[player->readyweapon].readystate;
  439.  
  440.     P_SetPsprite (player, ps_weapon, newstate);
  441. }
  442.  
  443.  
  444.  
  445. //
  446. // A_GunFlash
  447. //
  448. void
  449. A_GunFlash
  450. ( player_t*     player,
  451.   pspdef_t*     psp )
  452. {
  453.     P_SetMobjState (player->mo, S_PLAY_ATK2);
  454.     P_SetPsprite (player,ps_flash,weaponinfo[player->readyweapon].flashstate);
  455. }
  456.  
  457.  
  458.  
  459. //
  460. // WEAPON ATTACKS
  461. //
  462.  
  463.  
  464. //
  465. // A_Punch
  466. //
  467. void
  468. A_Punch
  469. ( player_t*     player,
  470.   pspdef_t*     psp )
  471. {
  472.     angle_t     angle;
  473.     int         damage;
  474.     int         slope;
  475.        
  476.     damage = (P_Random ()%10+1)<<1;
  477.  
  478.     if (player->powers[pw_strength])   
  479.         damage *= 10;
  480.  
  481.     angle = player->mo->angle;
  482.     angle += (P_Random()-P_Random())<<18;
  483.     slope = P_AimLineAttack (player->mo, angle, MELEERANGE);
  484.     P_LineAttack (player->mo, angle, MELEERANGE, slope, damage);
  485.  
  486.     // turn to face target
  487.     if (linetarget)
  488.     {
  489.         S_StartSound (player->mo, sfx_punch);
  490.         player->mo->angle = R_PointToAngle2 (player->mo->x,
  491.                                              player->mo->y,
  492.                                              linetarget->x,
  493.                                              linetarget->y);
  494.     }
  495. }
  496.  
  497.  
  498. //
  499. // A_Saw
  500. //
  501. void
  502. A_Saw
  503. ( player_t*     player,
  504.   pspdef_t*     psp )
  505. {
  506.     angle_t     angle;
  507.     int         damage;
  508.     int         slope;
  509.  
  510.     damage = 2*(P_Random ()%10+1);
  511.     angle = player->mo->angle;
  512.     angle += (P_Random()-P_Random())<<18;
  513.    
  514.     // use meleerange + 1 se the puff doesn't skip the flash
  515.     slope = P_AimLineAttack (player->mo, angle, MELEERANGE+1);
  516.     P_LineAttack (player->mo, angle, MELEERANGE+1, slope, damage);
  517.  
  518.     if (!linetarget)
  519.     {
  520.         S_StartSound (player->mo, sfx_sawful);
  521.         return;
  522.     }
  523.     S_StartSound (player->mo, sfx_sawhit);
  524.        
  525.     // turn to face target
  526.     angle = R_PointToAngle2 (player->mo->x, player->mo->y,
  527.                              linetarget->x, linetarget->y);
  528.     if (angle - player->mo->angle > ANG180)
  529.     {
  530.         if (angle - player->mo->angle < -ANG90/20)
  531.             player->mo->angle = angle + ANG90/21;
  532.         else
  533.             player->mo->angle -= ANG90/20;
  534.     }
  535.     else
  536.     {
  537.         if (angle - player->mo->angle > ANG90/20)
  538.             player->mo->angle = angle - ANG90/21;
  539.         else
  540.             player->mo->angle += ANG90/20;
  541.     }
  542.     player->mo->flags |= MF_JUSTATTACKED;
  543. }
  544.  
  545.  
  546.  
  547. //
  548. // A_FireMissile
  549. //
  550. void
  551. A_FireMissile
  552. ( player_t*     player,
  553.   pspdef_t*     psp )
  554. {
  555.     player->ammo[weaponinfo[player->readyweapon].ammo]--;
  556.     P_SpawnPlayerMissile (player->mo, MT_ROCKET);
  557. }
  558.  
  559.  
  560. //
  561. // A_FireBFG
  562. //
  563. void
  564. A_FireBFG
  565. ( player_t*     player,
  566.   pspdef_t*     psp )
  567. {
  568.     player->ammo[weaponinfo[player->readyweapon].ammo] -= BFGCELLS;
  569.     P_SpawnPlayerMissile (player->mo, MT_BFG);
  570. }
  571.  
  572.  
  573.  
  574. //
  575. // A_FirePlasma
  576. //
  577. void
  578. A_FirePlasma
  579. ( player_t*     player,
  580.   pspdef_t*     psp )
  581. {
  582.     player->ammo[weaponinfo[player->readyweapon].ammo]--;
  583.  
  584.     P_SetPsprite (player,
  585.                   ps_flash,
  586.                   weaponinfo[player->readyweapon].flashstate+(P_Random ()&1) );
  587.  
  588.     P_SpawnPlayerMissile (player->mo, MT_PLASMA);
  589. }
  590.  
  591.  
  592.  
  593. //
  594. // P_BulletSlope
  595. // Sets a slope so a near miss is at aproximately
  596. // the height of the intended target
  597. //
  598. fixed_t         bulletslope;
  599.  
  600.  
  601. void P_BulletSlope (mobj_t*     mo)
  602. {
  603.     angle_t     an;
  604.    
  605.     // see which target is to be aimed at
  606.     an = mo->angle;
  607.     bulletslope = P_AimLineAttack (mo, an, 16*64*FRACUNIT);
  608.  
  609.     if (!linetarget)
  610.     {
  611.         an += 1<<26;
  612.         bulletslope = P_AimLineAttack (mo, an, 16*64*FRACUNIT);
  613.         if (!linetarget)
  614.         {
  615.             an -= 2<<26;
  616.             bulletslope = P_AimLineAttack (mo, an, 16*64*FRACUNIT);
  617.         }
  618.     }
  619. }
  620.  
  621.  
  622. //
  623. // P_GunShot
  624. //
  625. void
  626. P_GunShot
  627. ( mobj_t*       mo,
  628.   boolean       accurate )
  629. {
  630.     angle_t     angle;
  631.     int         damage;
  632.        
  633.     damage = 5*(P_Random ()%3+1);
  634.     angle = mo->angle;
  635.  
  636.     if (!accurate)
  637.         angle += (P_Random()-P_Random())<<18;
  638.  
  639.     P_LineAttack (mo, angle, MISSILERANGE, bulletslope, damage);
  640. }
  641.  
  642.  
  643. //
  644. // A_FirePistol
  645. //
  646. void
  647. A_FirePistol
  648. ( player_t*     player,
  649.   pspdef_t*     psp )
  650. {
  651.     S_StartSound (player->mo, sfx_pistol);
  652.  
  653.     P_SetMobjState (player->mo, S_PLAY_ATK2);
  654.     player->ammo[weaponinfo[player->readyweapon].ammo]--;
  655.  
  656.     P_SetPsprite (player,
  657.                   ps_flash,
  658.                   weaponinfo[player->readyweapon].flashstate);
  659.  
  660.     P_BulletSlope (player->mo);
  661.     P_GunShot (player->mo, !player->refire);
  662. }
  663.  
  664.  
  665. //
  666. // A_FireShotgun
  667. //
  668. void
  669. A_FireShotgun
  670. ( player_t*     player,
  671.   pspdef_t*     psp )
  672. {
  673.     int         i;
  674.        
  675.     S_StartSound (player->mo, sfx_shotgn);
  676.     P_SetMobjState (player->mo, S_PLAY_ATK2);
  677.  
  678.     player->ammo[weaponinfo[player->readyweapon].ammo]--;
  679.  
  680.     P_SetPsprite (player,
  681.                   ps_flash,
  682.                   weaponinfo[player->readyweapon].flashstate);
  683.  
  684.     P_BulletSlope (player->mo);
  685.        
  686.     for (i=0 ; i<7 ; i++)
  687.         P_GunShot (player->mo, false);
  688. }
  689.  
  690.  
  691.  
  692. //
  693. // A_FireShotgun2
  694. //
  695. void
  696. A_FireShotgun2
  697. ( player_t*     player,
  698.   pspdef_t*     psp )
  699. {
  700.     int         i;
  701.     angle_t     angle;
  702.     int         damage;
  703.                
  704.        
  705.     S_StartSound (player->mo, sfx_dshtgn);
  706.     P_SetMobjState (player->mo, S_PLAY_ATK2);
  707.  
  708.     player->ammo[weaponinfo[player->readyweapon].ammo]-=2;
  709.  
  710.     P_SetPsprite (player,
  711.                   ps_flash,
  712.                   weaponinfo[player->readyweapon].flashstate);
  713.  
  714.     P_BulletSlope (player->mo);
  715.        
  716.     for (i=0 ; i<20 ; i++)
  717.     {
  718.         damage = 5*(P_Random ()%3+1);
  719.         angle = player->mo->angle;
  720.         angle += (P_Random()-P_Random())<<19;
  721.         P_LineAttack (player->mo,
  722.                       angle,
  723.                       MISSILERANGE,
  724.                       bulletslope + ((P_Random()-P_Random())<<5), damage);
  725.     }
  726. }
  727.  
  728.  
  729. //
  730. // A_FireCGun
  731. //
  732. void
  733. A_FireCGun
  734. ( player_t*     player,
  735.   pspdef_t*     psp )
  736. {
  737.     S_StartSound (player->mo, sfx_pistol);
  738.  
  739.     if (!player->ammo[weaponinfo[player->readyweapon].ammo])
  740.         return;
  741.                
  742.     P_SetMobjState (player->mo, S_PLAY_ATK2);
  743.     player->ammo[weaponinfo[player->readyweapon].ammo]--;
  744.  
  745.     P_SetPsprite (player,
  746.                   ps_flash,
  747.                   weaponinfo[player->readyweapon].flashstate
  748.                   + psp->state
  749.                   - &states[S_CHAIN1] );
  750.  
  751.     P_BulletSlope (player->mo);
  752.        
  753.     P_GunShot (player->mo, !player->refire);
  754. }
  755.  
  756.  
  757.  
  758. //
  759. // ?
  760. //
  761. void A_Light0 (player_t *player, pspdef_t *psp)
  762. {
  763.     player->extralight = 0;
  764. }
  765.  
  766. void A_Light1 (player_t *player, pspdef_t *psp)
  767. {
  768.     player->extralight = 1;
  769. }
  770.  
  771. void A_Light2 (player_t *player, pspdef_t *psp)
  772. {
  773.     player->extralight = 2;
  774. }
  775.  
  776.  
  777. //
  778. // A_BFGSpray
  779. // Spawn a BFG explosion on every monster in view
  780. //
  781. void A_BFGSpray (mobj_t* mo)
  782. {
  783.     int                 i;
  784.     int                 j;
  785.     int                 damage;
  786.     angle_t             an;
  787.        
  788.     // offset angles from its attack angle
  789.     for (i=0 ; i<40 ; i++)
  790.     {
  791.         an = mo->angle - ANG90/2 + ANG90/40*i;
  792.  
  793.         // mo->target is the originator (player)
  794.         //  of the missile
  795.         P_AimLineAttack (mo->target, an, 16*64*FRACUNIT);
  796.  
  797.         if (!linetarget)
  798.             continue;
  799.  
  800.         P_SpawnMobj (linetarget->x,
  801.                      linetarget->y,
  802.                      linetarget->z + (linetarget->height>>2),
  803.                      MT_EXTRABFG);
  804.        
  805.         damage = 0;
  806.         for (j=0;j<15;j++)
  807.             damage += (P_Random()&7) + 1;
  808.  
  809.         P_DamageMobj (linetarget, mo->target,mo->target, damage);
  810.     }
  811. }
  812.  
  813.  
  814. //
  815. // A_BFGsound
  816. //
  817. void
  818. A_BFGsound
  819. ( player_t*     player,
  820.   pspdef_t*     psp )
  821. {
  822.     S_StartSound (player->mo, sfx_bfg);
  823. }
  824.  
  825.  
  826.  
  827. //
  828. // P_SetupPsprites
  829. // Called at start of level for each player.
  830. //
  831. void P_SetupPsprites (player_t* player)
  832. {
  833.     int i;
  834.        
  835.     // remove all psprites
  836.     for (i=0 ; i<NUMPSPRITES ; i++)
  837.         player->psprites[i].state = NULL;
  838.                
  839.     // spawn the gun
  840.     player->pendingweapon = player->readyweapon;
  841.     P_BringUpWeapon (player);
  842. }
  843.  
  844.  
  845.  
  846.  
  847. //
  848. // P_MovePsprites
  849. // Called every tic by player thinking routine.
  850. //
  851. void P_MovePsprites (player_t* player)
  852. {
  853.     int         i;
  854.     pspdef_t*   psp;
  855.     state_t*    state;
  856.        
  857.     psp = &player->psprites[0];
  858.     for (i=0 ; i<NUMPSPRITES ; i++, psp++)
  859.     {
  860.         // a null state means not active
  861.         if ( (state = psp->state) )    
  862.         {
  863.             // drop tic count and possibly change state
  864.  
  865.             // a -1 tic count never changes
  866.             if (psp->tics != -1)       
  867.             {
  868.                 psp->tics--;
  869.                 if (!psp->tics)
  870.                     P_SetPsprite (player, i, psp->state->nextstate);
  871.             }                          
  872.         }
  873.     }
  874.    
  875.     player->psprites[ps_flash].sx = player->psprites[ps_weapon].sx;
  876.     player->psprites[ps_flash].sy = player->psprites[ps_weapon].sy;
  877. }
  878.  
  879.  
  880.