home *** CD-ROM | disk | FTP | other *** search
/ ST-Computer Leser-CD 2000 January / LCD_01_2000.iso / games / doom / pmdoom / src / p_user.c < prev    next >
C/C++ Source or Header  |  1999-12-17  |  9KB  |  386 lines

  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. /*     Player related stuff. */
  21. /*     Bobbing POV/weapon, movement. */
  22. /*     Pending weapon. */
  23. /*  */
  24. /* ----------------------------------------------------------------------------- */
  25.  
  26.  
  27. static const char
  28. rcsid[] = "$Id: p_user.c,v 1.3 1997/01/28 22:08:29 b1 Exp $";
  29.  
  30.  
  31. #include "doomdef.h"
  32. #include "d_event.h"
  33.  
  34. #include "p_local.h"
  35.  
  36. #include "doomstat.h"
  37.  
  38.  
  39.  
  40. /*  Index of the special effects (INVUL inverse) map. */
  41. #define INVERSECOLORMAP        32
  42.  
  43. /*  */
  44. /*  Movement. */
  45. /*  */
  46.  
  47. /*  16 pixels of bob */
  48. #define MAXBOB    0x100000    
  49.  
  50. boolean        onground;
  51.  
  52.  
  53. /*  */
  54. /*  P_Thrust */
  55. /*  Moves the given origin along a given angle. */
  56. /*  */
  57. void
  58. P_Thrust
  59. ( player_t*    player,
  60.   angle_t    angle,
  61.   fixed_t    move ) 
  62. {
  63.     angle >>= ANGLETOFINESHIFT;
  64.     
  65.     player->mo->momx += FixedMul(move,finecosine[angle]); 
  66.     player->mo->momy += FixedMul(move,finesine[angle]);
  67. }
  68.  
  69.  
  70.  
  71.  
  72. /*  */
  73. /*  P_CalcHeight */
  74. /*  Calculate the walking / running height adjustment */
  75. /*  */
  76. void P_CalcHeight (player_t* player) 
  77. {
  78.     int        angle;
  79.     fixed_t    bob;
  80.     
  81.     /*  Regular movement bobbing */
  82.     /*  (needs to be calculated for gun swing */
  83.     /*  even if not on ground) */
  84.     /*  OPTIMIZE: tablify angle */
  85.     /*  Note: a LUT allows for effects */
  86.     /*   like a ramp with low health. */
  87.     player->bob =
  88.     FixedMul (player->mo->momx, player->mo->momx)
  89.     + FixedMul (player->mo->momy,player->mo->momy);
  90.     
  91.     player->bob >>= 2;
  92.  
  93.     if (player->bob>MAXBOB)
  94.     player->bob = MAXBOB;
  95.  
  96.     if ((player->cheats & CF_NOMOMENTUM) || !onground)
  97.     {
  98.     player->viewz = player->mo->z + VIEWHEIGHT;
  99.  
  100.     if (player->viewz > player->mo->ceilingz-4*FRACUNIT)
  101.         player->viewz = player->mo->ceilingz-4*FRACUNIT;
  102.  
  103.     player->viewz = player->mo->z + player->viewheight;
  104.     return;
  105.     }
  106.         
  107.     angle = (FINEANGLES/20*leveltime)&FINEMASK;
  108.     bob = FixedMul ( player->bob/2, finesine[angle]);
  109.  
  110.     
  111.     /*  move viewheight */
  112.     if (player->playerstate == PST_LIVE)
  113.     {
  114.     player->viewheight += player->deltaviewheight;
  115.  
  116.     if (player->viewheight > VIEWHEIGHT)
  117.     {
  118.         player->viewheight = VIEWHEIGHT;
  119.         player->deltaviewheight = 0;
  120.     }
  121.  
  122.     if (player->viewheight < VIEWHEIGHT/2)
  123.     {
  124.         player->viewheight = VIEWHEIGHT/2;
  125.         if (player->deltaviewheight <= 0)
  126.         player->deltaviewheight = 1;
  127.     }
  128.     
  129.     if (player->deltaviewheight)    
  130.     {
  131.         player->deltaviewheight += FRACUNIT/4;
  132.         if (!player->deltaviewheight)
  133.         player->deltaviewheight = 1;
  134.     }
  135.     }
  136.     player->viewz = player->mo->z + player->viewheight + bob;
  137.  
  138.     if (player->viewz > player->mo->ceilingz-4*FRACUNIT)
  139.     player->viewz = player->mo->ceilingz-4*FRACUNIT;
  140. }
  141.  
  142.  
  143.  
  144. /*  */
  145. /*  P_MovePlayer */
  146. /*  */
  147. void P_MovePlayer (player_t* player)
  148. {
  149.     ticcmd_t*        cmd;
  150.     
  151.     cmd = &player->cmd;
  152.     
  153.     player->mo->angle += (cmd->angleturn<<16);
  154.  
  155.     /*  Do not let the player control movement */
  156.     /*   if not onground. */
  157.     onground = (player->mo->z <= player->mo->floorz);
  158.     
  159.     if (cmd->forwardmove && onground)
  160.     P_Thrust (player, player->mo->angle, cmd->forwardmove*2048);
  161.     
  162.     if (cmd->sidemove && onground)
  163.     P_Thrust (player, player->mo->angle-ANG90, cmd->sidemove*2048);
  164.  
  165.     if ( (cmd->forwardmove || cmd->sidemove) 
  166.      && player->mo->state == &states[S_PLAY] )
  167.     {
  168.     P_SetMobjState (player->mo, S_PLAY_RUN1);
  169.     }
  170. }    
  171.  
  172.  
  173.  
  174. /*  */
  175. /*  P_DeathThink */
  176. /*  Fall on your face when dying. */
  177. /*  Decrease POV height to floor height. */
  178. /*  */
  179. #define ANG5       (ANG90/18)
  180.  
  181. void P_DeathThink (player_t* player)
  182. {
  183.     angle_t        angle;
  184.     angle_t        delta;
  185.  
  186.     P_MovePsprites (player);
  187.     
  188.     /*  fall to the ground */
  189.     if (player->viewheight > 6*FRACUNIT)
  190.     player->viewheight -= FRACUNIT;
  191.  
  192.     if (player->viewheight < 6*FRACUNIT)
  193.     player->viewheight = 6*FRACUNIT;
  194.  
  195.     player->deltaviewheight = 0;
  196.     onground = (player->mo->z <= player->mo->floorz);
  197.     P_CalcHeight (player);
  198.     
  199.     if (player->attacker && player->attacker != player->mo)
  200.     {
  201.     angle = R_PointToAngle2 (player->mo->x,
  202.                  player->mo->y,
  203.                  player->attacker->x,
  204.                  player->attacker->y);
  205.     
  206.     delta = angle - player->mo->angle;
  207.     
  208.     if (delta < ANG5 || delta > (unsigned)-ANG5)
  209.     {
  210.         /*  Looking at killer, */
  211.         /*   so fade damage flash down. */
  212.         player->mo->angle = angle;
  213.  
  214.         if (player->damagecount)
  215.         player->damagecount--;
  216.     }
  217.     else if (delta < ANG180)
  218.         player->mo->angle += ANG5;
  219.     else
  220.         player->mo->angle -= ANG5;
  221.     }
  222.     else if (player->damagecount)
  223.     player->damagecount--;
  224.     
  225.  
  226.     if (player->cmd.buttons & BT_USE)
  227.     player->playerstate = PST_REBORN;
  228. }
  229.  
  230.  
  231.  
  232. /*  */
  233. /*  P_PlayerThink */
  234. /*  */
  235. void P_PlayerThink (player_t* player)
  236. {
  237.     ticcmd_t*        cmd;
  238.     weapontype_t    newweapon;
  239.     
  240.     /*  fixme: do this in the cheat code */
  241.     if (player->cheats & CF_NOCLIP)
  242.     player->mo->flags |= MF_NOCLIP;
  243.     else
  244.     player->mo->flags &= ~MF_NOCLIP;
  245.     
  246.     /*  chain saw run forward */
  247.     cmd = &player->cmd;
  248.     if (player->mo->flags & MF_JUSTATTACKED)
  249.     {
  250.     cmd->angleturn = 0;
  251.     cmd->forwardmove = 0xc800/512;
  252.     cmd->sidemove = 0;
  253.     player->mo->flags &= ~MF_JUSTATTACKED;
  254.     }
  255.             
  256.     
  257.     if (player->playerstate == PST_DEAD)
  258.     {
  259.     P_DeathThink (player);
  260.     return;
  261.     }
  262.     
  263.     /*  Move around. */
  264.     /*  Reactiontime is used to prevent movement */
  265.     /*   for a bit after a teleport. */
  266.     if (player->mo->reactiontime)
  267.     player->mo->reactiontime--;
  268.     else
  269.     P_MovePlayer (player);
  270.     
  271.     P_CalcHeight (player);
  272.  
  273.     if (player->mo->subsector->sector->special)
  274.     P_PlayerInSpecialSector (player);
  275.     
  276.     /*  Check for weapon change. */
  277.  
  278.     /*  A special event has no other buttons. */
  279.     if (cmd->buttons & BT_SPECIAL)
  280.     cmd->buttons = 0;            
  281.         
  282.     if (cmd->buttons & BT_CHANGE)
  283.     {
  284.     /*  The actual changing of the weapon is done */
  285.     /*   when the weapon psprite can do it */
  286.     /*   (read: not in the middle of an attack). */
  287.     newweapon = (cmd->buttons&BT_WEAPONMASK)>>BT_WEAPONSHIFT;
  288.     
  289.     if (newweapon == wp_fist
  290.         && player->weaponowned[wp_chainsaw]
  291.         && !(player->readyweapon == wp_chainsaw
  292.          && player->powers[pw_strength]))
  293.     {
  294.         newweapon = wp_chainsaw;
  295.     }
  296.     
  297.     if ( (gamemode == commercial)
  298.         && newweapon == wp_shotgun 
  299.         && player->weaponowned[wp_supershotgun]
  300.         && player->readyweapon != wp_supershotgun)
  301.     {
  302.         newweapon = wp_supershotgun;
  303.     }
  304.     
  305.  
  306.     if (player->weaponowned[newweapon]
  307.         && newweapon != player->readyweapon)
  308.     {
  309.         /*  Do not go to plasma or BFG in shareware, */
  310.         /*   even if cheated. */
  311.         if ((newweapon != wp_plasma
  312.          && newweapon != wp_bfg)
  313.         || (gamemode != shareware) )
  314.         {
  315.         player->pendingweapon = newweapon;
  316.         }
  317.     }
  318.     }
  319.     
  320.     /*  check for use */
  321.     if (cmd->buttons & BT_USE)
  322.     {
  323.     if (!player->usedown)
  324.     {
  325.         P_UseLines (player);
  326.         player->usedown = true;
  327.     }
  328.     }
  329.     else
  330.     player->usedown = false;
  331.     
  332.     /*  cycle psprites */
  333.     P_MovePsprites (player);
  334.     
  335.     /*  Counters, time dependend power ups. */
  336.  
  337.     /*  Strength counts up to diminish fade. */
  338.     if (player->powers[pw_strength])
  339.     player->powers[pw_strength]++;    
  340.         
  341.     if (player->powers[pw_invulnerability])
  342.     player->powers[pw_invulnerability]--;
  343.  
  344.     if (player->powers[pw_invisibility])
  345.     if (! --player->powers[pw_invisibility] )
  346.         player->mo->flags &= ~MF_SHADOW;
  347.             
  348.     if (player->powers[pw_infrared])
  349.     player->powers[pw_infrared]--;
  350.         
  351.     if (player->powers[pw_ironfeet])
  352.     player->powers[pw_ironfeet]--;
  353.         
  354.     if (player->damagecount)
  355.     player->damagecount--;
  356.         
  357.     if (player->bonuscount)
  358.     player->bonuscount--;
  359.  
  360.     
  361.     /*  Handling colormaps. */
  362.     if (player->powers[pw_invulnerability])
  363.     {
  364.     if (player->powers[pw_invulnerability] > 4*32
  365.         || (player->powers[pw_invulnerability]&8) )
  366.         player->fixedcolormap = INVERSECOLORMAP;
  367.     else
  368.         player->fixedcolormap = 0;
  369.     }
  370.     else if (player->powers[pw_infrared])    
  371.     {
  372.     if (player->powers[pw_infrared] > 4*32
  373.         || (player->powers[pw_infrared]&8) )
  374.     {
  375.         /*  almost full bright */
  376.         player->fixedcolormap = 1;
  377.     }
  378.     else
  379.         player->fixedcolormap = 0;
  380.     }
  381.     else
  382.     player->fixedcolormap = 0;
  383. }
  384.  
  385.  
  386.