1 /* Emacs style mode select -*- C++ -*-
2 *-----------------------------------------------------------------------------
5 * PrBoom a Doom port merged with LxDoom and LSDLDoom
6 * based on BOOM, a modified and improved DOOM engine
7 * Copyright (C) 1999 by
8 * id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
9 * Copyright (C) 1999-2000 by
10 * Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
28 * Player related stuff.
29 * Bobbing POV/weapon, movement.
32 *-----------------------------------------------------------------------------*/
40 #include "rockmacros.h"
41 // Index of the special effects (INVUL inverse) map.
43 #define INVERSECOLORMAP 32
51 #define MAXBOB 0x100000
53 boolean onground
; // whether player is on ground or in air
57 // Moves the given origin along a given angle.
60 void P_Thrust(player_t
* player
,angle_t angle
,fixed_t move
)
62 angle
>>= ANGLETOFINESHIFT
;
63 player
->mo
->momx
+= FixedMul(move
,finecosine
[angle
]);
64 player
->mo
->momy
+= FixedMul(move
,finesine
[angle
]);
70 * Same as P_Thrust, but only affects bobbing.
72 * killough 10/98: We apply thrust separately between the real physical player
73 * and the part which affects bobbing. This way, bobbing only comes from player
74 * motion, nothing external, avoiding many problems, e.g. bobbing should not
75 * occur on conveyors, unless the player walks on one, and bobbing should be
76 * reduced at a regular rate, even on ice (where the player coasts).
79 void P_Bob(player_t
*player
, angle_t angle
, fixed_t move
)
81 player
->momx
+= FixedMul(move
,finecosine
[angle
>>= ANGLETOFINESHIFT
]);
82 player
->momy
+= FixedMul(move
,finesine
[angle
]);
87 // Calculate the walking / running height adjustment
90 void P_CalcHeight (player_t
* player
)
95 // Regular movement bobbing
96 // (needs to be calculated for gun swing
97 // even if not on ground)
98 // OPTIMIZE: tablify angle
99 // Note: a LUT allows for effects
100 // like a ramp with low health.
103 /* killough 10/98: Make bobbing depend only on player-applied motion.
105 * Note: don't reduce bobbing here if on ice: if you reduce bobbing here,
106 * it causes bobbing jerkiness when the player moves from ice to non-ice,
109 player
->bob
= !mbf_features
?
110 (FixedMul (player
->mo
->momx
, player
->mo
->momx
)
111 + FixedMul (player
->mo
->momy
,player
->mo
->momy
))>>2 :
112 player_bobbing
? (FixedMul(player
->momx
,player
->momx
) +
113 FixedMul(player
->momy
,player
->momy
))>>2 : 0;
115 if (player
->bob
> MAXBOB
)
116 player
->bob
= MAXBOB
;
118 if (!onground
|| player
->cheats
& CF_NOMOMENTUM
)
120 player
->viewz
= player
->mo
->z
+ VIEWHEIGHT
;
122 if (player
->viewz
> player
->mo
->ceilingz
-4*FRACUNIT
)
123 player
->viewz
= player
->mo
->ceilingz
-4*FRACUNIT
;
125 // The following line was in the Id source and appears // phares 2/25/98
126 // to be a bug. player->viewz is checked in a similar
127 // manner at a different exit below.
129 // player->viewz = player->mo->z + player->viewheight;
133 angle
= (FINEANGLES
/20*leveltime
)&FINEMASK
;
134 bob
= FixedMul(player
->bob
/2,finesine
[angle
]);
138 if (player
->playerstate
== PST_LIVE
)
140 player
->viewheight
+= player
->deltaviewheight
;
142 if (player
->viewheight
> VIEWHEIGHT
)
144 player
->viewheight
= VIEWHEIGHT
;
145 player
->deltaviewheight
= 0;
148 if (player
->viewheight
< VIEWHEIGHT
/2)
150 player
->viewheight
= VIEWHEIGHT
/2;
151 if (player
->deltaviewheight
<= 0)
152 player
->deltaviewheight
= 1;
155 if (player
->deltaviewheight
)
157 player
->deltaviewheight
+= FRACUNIT
/4;
158 if (!player
->deltaviewheight
)
159 player
->deltaviewheight
= 1;
163 player
->viewz
= player
->mo
->z
+ player
->viewheight
+ bob
;
165 if (player
->viewz
> player
->mo
->ceilingz
-4*FRACUNIT
)
166 player
->viewz
= player
->mo
->ceilingz
-4*FRACUNIT
;
173 // Adds momentum if the player is not in the air
175 // killough 10/98: simplified
177 void P_MovePlayer (player_t
* player
)
179 ticcmd_t
*cmd
= &player
->cmd
;
180 mobj_t
*mo
= player
->mo
;
182 mo
->angle
+= cmd
->angleturn
<< 16;
183 onground
= mo
->z
<= mo
->floorz
;
187 // We must apply thrust to the player and bobbing separately, to avoid
188 // anomalies. The thrust applied to bobbing is always the same strength on
189 // ice, because the player still "works just as hard" to move, while the
190 // thrust applied to the movement varies with 'movefactor'.
192 if (cmd
->forwardmove
| cmd
->sidemove
) // killough 10/98
194 if (onground
|| mo
->flags
& MF_BOUNCES
) // killough 8/9/98
196 int friction
, movefactor
= P_GetMoveFactor(mo
, &friction
);
199 // On sludge, make bobbing depend on efficiency.
200 // On ice, make it depend on effort.
203 friction
< ORIG_FRICTION
? movefactor
: ORIG_FRICTION_FACTOR
;
205 if (cmd
->forwardmove
)
207 P_Bob(player
,mo
->angle
,cmd
->forwardmove
*bobfactor
);
208 P_Thrust(player
,mo
->angle
,cmd
->forwardmove
*movefactor
);
213 P_Bob(player
,mo
->angle
-ANG90
,cmd
->sidemove
*bobfactor
);
214 P_Thrust(player
,mo
->angle
-ANG90
,cmd
->sidemove
*movefactor
);
217 if (mo
->state
== states
+S_PLAY
)
218 P_SetMobjState(mo
,S_PLAY_RUN1
);
222 #define ANG5 (ANG90/18)
226 // Fall on your face when dying.
227 // Decrease POV height to floor height.
230 void P_DeathThink (player_t
* player
)
235 P_MovePsprites (player
);
237 // fall to the ground
239 if (player
->viewheight
> 6*FRACUNIT
)
240 player
->viewheight
-= FRACUNIT
;
242 if (player
->viewheight
< 6*FRACUNIT
)
243 player
->viewheight
= 6*FRACUNIT
;
245 player
->deltaviewheight
= 0;
246 onground
= (player
->mo
->z
<= player
->mo
->floorz
);
247 P_CalcHeight (player
);
249 if (player
->attacker
&& player
->attacker
!= player
->mo
)
251 angle
= R_PointToAngle2 (player
->mo
->x
,
254 player
->attacker
->y
);
256 delta
= angle
- player
->mo
->angle
;
258 if (delta
< ANG5
|| delta
> (unsigned)-ANG5
)
260 // Looking at killer,
261 // so fade damage flash down.
263 player
->mo
->angle
= angle
;
265 if (player
->damagecount
)
266 player
->damagecount
--;
268 else if (delta
< ANG180
)
269 player
->mo
->angle
+= ANG5
;
271 player
->mo
->angle
-= ANG5
;
273 else if (player
->damagecount
)
274 player
->damagecount
--;
276 if (player
->cmd
.buttons
& BT_USE
)
277 player
->playerstate
= PST_REBORN
;
285 void P_PlayerThink (player_t
* player
)
288 weapontype_t newweapon
;
290 // killough 2/8/98, 3/21/98:
291 if (player
->cheats
& CF_NOCLIP
)
292 player
->mo
->flags
|= MF_NOCLIP
;
294 player
->mo
->flags
&= ~MF_NOCLIP
;
296 // chain saw run forward
299 if (player
->mo
->flags
& MF_JUSTATTACKED
)
302 cmd
->forwardmove
= 0xc800/512;
304 player
->mo
->flags
&= ~MF_JUSTATTACKED
;
307 if (player
->playerstate
== PST_DEAD
)
309 P_DeathThink (player
);
314 // Reactiontime is used to prevent movement
315 // for a bit after a teleport.
317 if (player
->mo
->reactiontime
)
318 player
->mo
->reactiontime
--;
320 P_MovePlayer (player
);
322 P_CalcHeight (player
); // Determines view height and bobbing
324 // Determine if there's anything about the sector you're in that's
325 // going to affect you, like painful floors.
327 if (player
->mo
->subsector
->sector
->special
)
328 P_PlayerInSpecialSector (player
);
330 // Check for weapon change.
332 if (cmd
->buttons
& BT_CHANGE
)
334 // The actual changing of the weapon is done
335 // when the weapon psprite can do it
336 // (read: not in the middle of an attack).
338 newweapon
= (cmd
->buttons
& BT_WEAPONMASK
)>>BT_WEAPONSHIFT
;
340 // killough 3/22/98: For demo compatibility we must perform the fist
341 // and SSG weapons switches here, rather than in G_BuildTiccmd(). For
342 // other games which rely on user preferences, we must use the latter.
344 if (demo_compatibility
)
345 { // compatibility mode -- required for old demos -- killough
346 if (newweapon
== wp_fist
&& player
->weaponowned
[wp_chainsaw
] &&
347 (player
->readyweapon
!= wp_chainsaw
||
348 !player
->powers
[pw_strength
]))
349 newweapon
= wp_chainsaw
;
350 if (gamemode
== commercial
&&
351 newweapon
== wp_shotgun
&&
352 player
->weaponowned
[wp_supershotgun
] &&
353 player
->readyweapon
!= wp_supershotgun
)
354 newweapon
= wp_supershotgun
;
357 // killough 2/8/98, 3/22/98 -- end of weapon selection changes
359 if (player
->weaponowned
[newweapon
] && newweapon
!= player
->readyweapon
)
361 // Do not go to plasma or BFG in shareware,
364 if ((newweapon
!= wp_plasma
&& newweapon
!= wp_bfg
)
365 || (gamemode
!= shareware
) )
366 player
->pendingweapon
= newweapon
;
371 if (cmd
->buttons
& BT_USE
)
373 if (!player
->usedown
)
376 player
->usedown
= true;
380 player
->usedown
= false;
384 P_MovePsprites (player
);
386 // Counters, time dependent power ups.
388 // Strength counts up to diminish fade.
390 if (player
->powers
[pw_strength
])
391 player
->powers
[pw_strength
]++;
393 // killough 1/98: Make idbeholdx toggle:
395 if (player
->powers
[pw_invulnerability
] > 0) // killough
396 player
->powers
[pw_invulnerability
]--;
398 if (player
->powers
[pw_invisibility
] > 0) // killough
399 if (! --player
->powers
[pw_invisibility
] )
400 player
->mo
->flags
&= ~MF_SHADOW
;
402 if (player
->powers
[pw_infrared
] > 0) // killough
403 player
->powers
[pw_infrared
]--;
405 if (player
->powers
[pw_ironfeet
] > 0) // killough
406 player
->powers
[pw_ironfeet
]--;
408 if (player
->damagecount
)
409 player
->damagecount
--;
411 if (player
->bonuscount
)
412 player
->bonuscount
--;
414 // Handling colormaps.
415 // killough 3/20/98: reformat to terse C syntax
417 player
->fixedcolormap
= player
->powers
[pw_invulnerability
] > 4*32 ||
418 player
->powers
[pw_invulnerability
] & 8 ? INVERSECOLORMAP
:
419 player
->powers
[pw_infrared
] > 4*32 || player
->powers
[pw_infrared
] & 8;