p_user.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451
  1. /*
  2. ===========================================================================
  3. Doom 3 BFG Edition GPL Source Code
  4. Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
  5. This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
  6. Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation, either version 3 of the License, or
  9. (at your option) any later version.
  10. Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>.
  16. In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below.
  17. If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
  18. ===========================================================================
  19. */
  20. #include "Precompiled.h"
  21. #include "globaldata.h"
  22. #include "doomdef.h"
  23. #include "d_event.h"
  24. #include "p_local.h"
  25. #include "doomstat.h"
  26. // Index of the special effects (INVUL inverse) map.
  27. //
  28. // Movement.
  29. //
  30. // 16 pixels of bob
  31. //
  32. // P_Thrust
  33. // Moves the given origin along a given angle.
  34. //
  35. void
  36. P_Thrust
  37. ( player_t* player,
  38. angle_t angle,
  39. fixed_t move )
  40. {
  41. angle >>= ANGLETOFINESHIFT;
  42. player->mo->momx += FixedMul(move,finecosine[angle]);
  43. player->mo->momy += FixedMul(move,finesine[angle]);
  44. }
  45. //
  46. // P_CalcHeight
  47. // Calculate the walking / running height adjustment
  48. //
  49. void P_CalcHeight (player_t* player)
  50. {
  51. int angle;
  52. fixed_t bob;
  53. // Regular movement bobbing
  54. // (needs to be calculated for gun swing
  55. // even if not on ground)
  56. // OPTIMIZE: tablify angle
  57. // Note: a LUT allows for effects
  58. // like a ramp with low health.
  59. player->bob =
  60. FixedMul (player->mo->momx, player->mo->momx)
  61. + FixedMul (player->mo->momy,player->mo->momy);
  62. player->bob >>= 2;
  63. // DHM - NERVE :: player bob reduced by 25%, MAXBOB reduced by 25% as well
  64. player->bob = (fixed_t)( (float)(player->bob) * 0.75f );
  65. if (player->bob>MAXBOB)
  66. player->bob = MAXBOB;
  67. if ((player->cheats & CF_NOMOMENTUM) || !::g->onground)
  68. {
  69. player->viewz = player->mo->z + VIEWHEIGHT;
  70. if (player->viewz > player->mo->ceilingz-4*FRACUNIT)
  71. player->viewz = player->mo->ceilingz-4*FRACUNIT;
  72. player->viewz = player->mo->z + player->viewheight;
  73. return;
  74. }
  75. angle = (FINEANGLES/20*::g->leveltime)&FINEMASK;
  76. bob = FixedMul ( player->bob/2, finesine[angle]);
  77. // move ::g->viewheight
  78. if (player->playerstate == PST_LIVE)
  79. {
  80. player->viewheight += player->deltaviewheight;
  81. if (player->viewheight > VIEWHEIGHT)
  82. {
  83. player->viewheight = VIEWHEIGHT;
  84. player->deltaviewheight = 0;
  85. }
  86. if (player->viewheight < VIEWHEIGHT/2)
  87. {
  88. player->viewheight = VIEWHEIGHT/2;
  89. if (player->deltaviewheight <= 0)
  90. player->deltaviewheight = 1;
  91. }
  92. if (player->deltaviewheight)
  93. {
  94. player->deltaviewheight += FRACUNIT/4;
  95. if (!player->deltaviewheight)
  96. player->deltaviewheight = 1;
  97. }
  98. }
  99. player->viewz = player->mo->z + player->viewheight + bob;
  100. if (player->viewz > player->mo->ceilingz-4*FRACUNIT)
  101. player->viewz = player->mo->ceilingz-4*FRACUNIT;
  102. }
  103. //
  104. // P_MovePlayer
  105. //
  106. void P_MovePlayer (player_t* player)
  107. {
  108. ticcmd_t* cmd;
  109. cmd = &player->cmd;
  110. player->mo->angle += (cmd->angleturn<<16);
  111. // Do not let the player control movement
  112. // if not ::g->onground.
  113. ::g->onground = (player->mo->z <= player->mo->floorz);
  114. if (cmd->forwardmove && ::g->onground)
  115. P_Thrust (player, player->mo->angle, cmd->forwardmove*2048);
  116. if (cmd->sidemove && ::g->onground)
  117. P_Thrust (player, player->mo->angle-ANG90, cmd->sidemove*2048);
  118. if ( (cmd->forwardmove || cmd->sidemove)
  119. && player->mo->state == &::g->states[S_PLAY] )
  120. {
  121. P_SetMobjState (player->mo, S_PLAY_RUN1);
  122. }
  123. }
  124. //
  125. // P_DeathThink
  126. // Fall on your face when dying.
  127. // Decrease POV height to floor height.
  128. //
  129. extern byte demoversion;
  130. void P_DeathThink (player_t* player)
  131. {
  132. angle_t angle;
  133. angle_t delta;
  134. P_MovePsprites (player);
  135. // fall to the ground
  136. if (player->viewheight > 6*FRACUNIT)
  137. player->viewheight -= FRACUNIT;
  138. if (player->viewheight < 6*FRACUNIT)
  139. player->viewheight = 6*FRACUNIT;
  140. player->deltaviewheight = 0;
  141. ::g->onground = (player->mo->z <= player->mo->floorz);
  142. P_CalcHeight (player);
  143. if (player->attacker && player->attacker != player->mo)
  144. {
  145. angle = R_PointToAngle2 (player->mo->x,
  146. player->mo->y,
  147. player->attacker->x,
  148. player->attacker->y);
  149. delta = angle - player->mo->angle;
  150. if (delta < ANG5 || delta > (unsigned)-ANG5)
  151. {
  152. // Looking at killer,
  153. // so fade damage flash down.
  154. player->mo->angle = angle;
  155. if (player->damagecount)
  156. player->damagecount--;
  157. }
  158. else if (delta < ANG180)
  159. player->mo->angle += ANG5;
  160. else
  161. player->mo->angle -= ANG5;
  162. }
  163. else if (player->damagecount)
  164. player->damagecount--;
  165. if (player->cmd.buttons & BT_USE)
  166. player->playerstate = PST_REBORN;
  167. }
  168. //
  169. // P_PlayerThink
  170. //
  171. void P_PlayerThink (player_t* player)
  172. {
  173. ticcmd_t* cmd;
  174. weapontype_t newweapon = wp_fist;
  175. // fixme: do this in the cheat code
  176. if (player->cheats & CF_NOCLIP)
  177. player->mo->flags |= MF_NOCLIP;
  178. else
  179. player->mo->flags &= ~MF_NOCLIP;
  180. // chain saw run forward
  181. cmd = &player->cmd;
  182. if (player->mo->flags & MF_JUSTATTACKED)
  183. {
  184. cmd->angleturn = 0;
  185. cmd->forwardmove = 0xc800/512;
  186. cmd->sidemove = 0;
  187. player->mo->flags &= ~MF_JUSTATTACKED;
  188. }
  189. if (player->playerstate == PST_DEAD)
  190. {
  191. P_DeathThink (player);
  192. return;
  193. }
  194. // Move around.
  195. // Reactiontime is used to prevent movement
  196. // for a bit after a teleport.
  197. if (player->mo->reactiontime)
  198. player->mo->reactiontime--;
  199. else
  200. P_MovePlayer (player);
  201. P_CalcHeight (player);
  202. if (player->mo->subsector->sector->special)
  203. P_PlayerInSpecialSector (player);
  204. // Check for weapon change.
  205. // A special event has no other buttons.
  206. if (cmd->buttons & BT_SPECIAL)
  207. cmd->buttons = 0;
  208. if (::g->demoplayback && demoversion < VERSION )
  209. {
  210. if ( cmd->buttons & BT_CHANGE)
  211. {
  212. // The actual changing of the weapon is done
  213. // when the weapon psprite can do it
  214. // (read: not in the middle of an attack).
  215. newweapon = (weapontype_t)((cmd->buttons&BT_WEAPONMASK)>>BT_WEAPONSHIFT);
  216. if (newweapon == wp_fist
  217. && player->weaponowned[wp_chainsaw]
  218. && !(player->readyweapon == wp_chainsaw
  219. && player->powers[pw_strength]))
  220. {
  221. newweapon = wp_chainsaw;
  222. }
  223. if ( (::g->gamemode == commercial)
  224. && newweapon == wp_shotgun
  225. && player->weaponowned[wp_supershotgun]
  226. && player->readyweapon != wp_supershotgun)
  227. {
  228. newweapon = wp_supershotgun;
  229. }
  230. if (player->weaponowned[newweapon]
  231. && newweapon != player->readyweapon)
  232. {
  233. // Do not go to plasma or BFG in shareware,
  234. // even if cheated.
  235. if ((newweapon != wp_plasma
  236. && newweapon != wp_bfg)
  237. || (::g->gamemode != shareware) )
  238. {
  239. player->pendingweapon = newweapon;
  240. }
  241. }
  242. }
  243. }
  244. else if ( cmd->buttons & BT_CHANGE )
  245. {
  246. int k, which;
  247. // The actual changing of the weapon is done
  248. // when the weapon psprite can do it
  249. // (read: not in the middle of an attack).
  250. which = ((cmd->buttons&BT_WEAPONMASK)>>BT_WEAPONSHIFT);
  251. if ( cmd->nextPrevWeapon > 0) {
  252. newweapon = player->readyweapon;
  253. for ( k = 0; k < NUMWEAPONS; ++k)
  254. {
  255. newweapon = (weapontype_t)( (cmd->nextPrevWeapon - 1) ? (newweapon + 1) : (newweapon - 1));
  256. if (newweapon == wp_nochange)
  257. continue;
  258. weapontype_t maxweapon = (::g->gamemode == retail) ? wp_chainsaw : wp_supershotgun;
  259. if (newweapon < 0)
  260. newweapon = maxweapon;
  261. if (newweapon > maxweapon)
  262. newweapon = wp_fist;
  263. if (player->weaponowned[newweapon] && newweapon != player->readyweapon)
  264. {
  265. player->pendingweapon = newweapon;
  266. break;
  267. }
  268. }
  269. }
  270. else {
  271. newweapon = (weapontype_t)((cmd->buttons&BT_WEAPONMASK)>>BT_WEAPONSHIFT);
  272. if (newweapon == wp_fist
  273. && player->weaponowned[wp_chainsaw]
  274. && !(player->readyweapon == wp_chainsaw
  275. && player->powers[pw_strength]))
  276. {
  277. newweapon = wp_chainsaw;
  278. }
  279. if ( (::g->gamemode == commercial)
  280. && newweapon == wp_shotgun
  281. && player->weaponowned[wp_supershotgun]
  282. && player->readyweapon != wp_supershotgun)
  283. {
  284. newweapon = wp_supershotgun;
  285. }
  286. if ( player->weaponowned[ newweapon ] && newweapon != player->readyweapon ) {
  287. player->pendingweapon = newweapon;
  288. }
  289. }
  290. }
  291. // check for use
  292. if (cmd->buttons & BT_USE)
  293. {
  294. if (!player->usedown)
  295. {
  296. P_UseLines (player);
  297. player->usedown = true;
  298. }
  299. }
  300. else
  301. player->usedown = false;
  302. // cycle psprites
  303. P_MovePsprites (player);
  304. // Counters, time dependend power ups.
  305. // Strength counts up to diminish fade.
  306. if (player->powers[pw_strength])
  307. player->powers[pw_strength]++;
  308. if (player->powers[pw_invulnerability])
  309. player->powers[pw_invulnerability]--;
  310. if (player->powers[pw_invisibility])
  311. if (! --player->powers[pw_invisibility] )
  312. player->mo->flags &= ~MF_SHADOW;
  313. if (player->powers[pw_infrared])
  314. player->powers[pw_infrared]--;
  315. if (player->powers[pw_ironfeet])
  316. player->powers[pw_ironfeet]--;
  317. if (player->damagecount)
  318. player->damagecount--;
  319. if (player->bonuscount)
  320. player->bonuscount--;
  321. // Handling ::g->colormaps.
  322. if (player->powers[pw_invulnerability])
  323. {
  324. if (player->powers[pw_invulnerability] > 4*32
  325. || (player->powers[pw_invulnerability]&8) )
  326. player->fixedcolormap = INVERSECOLORMAP;
  327. else
  328. player->fixedcolormap = 0;
  329. }
  330. else if (player->powers[pw_infrared])
  331. {
  332. if (player->powers[pw_infrared] > 4*32
  333. || (player->powers[pw_infrared]&8) )
  334. {
  335. // almost full bright
  336. player->fixedcolormap = 1;
  337. }
  338. else
  339. player->fixedcolormap = 0;
  340. }
  341. else
  342. player->fixedcolormap = 0;
  343. }