p_user.c 8.1 KB

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