aboutsummaryrefslogtreecommitdiff
path: root/src/p_user.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/p_user.c')
-rw-r--r--src/p_user.c452
1 files changed, 452 insertions, 0 deletions
diff --git a/src/p_user.c b/src/p_user.c
new file mode 100644
index 0000000..d280e55
--- /dev/null
+++ b/src/p_user.c
@@ -0,0 +1,452 @@
1/* Emacs style mode select -*- C++ -*-
2 *-----------------------------------------------------------------------------
3 *
4 *
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
11 * Copyright 2005, 2006 by
12 * Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
27 * 02111-1307, USA.
28 *
29 * DESCRIPTION:
30 * Player related stuff.
31 * Bobbing POV/weapon, movement.
32 * Pending weapon.
33 *
34 *-----------------------------------------------------------------------------*/
35
36#include "doomstat.h"
37#include "d_event.h"
38#include "r_main.h"
39#include "p_map.h"
40#include "p_spec.h"
41#include "p_user.h"
42#include "r_demo.h"
43#include "r_fps.h"
44
45// Index of the special effects (INVUL inverse) map.
46
47#define INVERSECOLORMAP 32
48
49//
50// Movement.
51//
52
53// 16 pixels of bob
54
55#define MAXBOB 0x100000
56
57boolean onground; // whether player is on ground or in air
58
59//
60// P_Thrust
61// Moves the given origin along a given angle.
62//
63
64void P_Thrust(player_t* player,angle_t angle,fixed_t move)
65 {
66 angle >>= ANGLETOFINESHIFT;
67 player->mo->momx += FixedMul(move,finecosine[angle]);
68 player->mo->momy += FixedMul(move,finesine[angle]);
69 }
70
71
72/*
73 * P_Bob
74 * Same as P_Thrust, but only affects bobbing.
75 *
76 * killough 10/98: We apply thrust separately between the real physical player
77 * and the part which affects bobbing. This way, bobbing only comes from player
78 * motion, nothing external, avoiding many problems, e.g. bobbing should not
79 * occur on conveyors, unless the player walks on one, and bobbing should be
80 * reduced at a regular rate, even on ice (where the player coasts).
81 */
82
83static void P_Bob(player_t *player, angle_t angle, fixed_t move)
84{
85 //e6y
86 if (!mbf_features)
87 return;
88
89 player->momx += FixedMul(move,finecosine[angle >>= ANGLETOFINESHIFT]);
90 player->momy += FixedMul(move,finesine[angle]);
91}
92
93//
94// P_CalcHeight
95// Calculate the walking / running height adjustment
96//
97
98void P_CalcHeight (player_t* player)
99 {
100 int angle;
101 fixed_t bob;
102
103 // Regular movement bobbing
104 // (needs to be calculated for gun swing
105 // even if not on ground)
106 // OPTIMIZE: tablify angle
107 // Note: a LUT allows for effects
108 // like a ramp with low health.
109
110
111 /* killough 10/98: Make bobbing depend only on player-applied motion.
112 *
113 * Note: don't reduce bobbing here if on ice: if you reduce bobbing here,
114 * it causes bobbing jerkiness when the player moves from ice to non-ice,
115 * and vice-versa.
116 */
117 player->bob = !mbf_features ?
118 (FixedMul (player->mo->momx, player->mo->momx)
119 + FixedMul (player->mo->momy,player->mo->momy))>>2 :
120 player_bobbing ? (FixedMul(player->momx,player->momx) +
121 FixedMul(player->momy,player->momy))>>2 : 0;
122
123 //e6y
124 if (compatibility_level >= boom_202_compatibility &&
125 compatibility_level <= lxdoom_1_compatibility &&
126 player->mo->friction > ORIG_FRICTION) // ice?
127 {
128 if (player->bob > (MAXBOB>>2))
129 player->bob = MAXBOB>>2;
130 }
131 else
132
133 if (player->bob > MAXBOB)
134 player->bob = MAXBOB;
135
136 if (!onground || player->cheats & CF_NOMOMENTUM)
137 {
138 player->viewz = player->mo->z + VIEWHEIGHT;
139
140 if (player->viewz > player->mo->ceilingz-4*FRACUNIT)
141 player->viewz = player->mo->ceilingz-4*FRACUNIT;
142
143// The following line was in the Id source and appears // phares 2/25/98
144// to be a bug. player->viewz is checked in a similar
145// manner at a different exit below.
146
147// player->viewz = player->mo->z + player->viewheight;
148 return;
149 }
150
151 angle = (FINEANGLES/20*leveltime)&FINEMASK;
152 bob = FixedMul(player->bob/2,finesine[angle]);
153
154 // move viewheight
155
156 if (player->playerstate == PST_LIVE)
157 {
158 player->viewheight += player->deltaviewheight;
159
160 if (player->viewheight > VIEWHEIGHT)
161 {
162 player->viewheight = VIEWHEIGHT;
163 player->deltaviewheight = 0;
164 }
165
166 if (player->viewheight < VIEWHEIGHT/2)
167 {
168 player->viewheight = VIEWHEIGHT/2;
169 if (player->deltaviewheight <= 0)
170 player->deltaviewheight = 1;
171 }
172
173 if (player->deltaviewheight)
174 {
175 player->deltaviewheight += FRACUNIT/4;
176 if (!player->deltaviewheight)
177 player->deltaviewheight = 1;
178 }
179 }
180
181 player->viewz = player->mo->z + player->viewheight + bob;
182
183 if (player->viewz > player->mo->ceilingz-4*FRACUNIT)
184 player->viewz = player->mo->ceilingz-4*FRACUNIT;
185 }
186
187
188//
189// P_MovePlayer
190//
191// Adds momentum if the player is not in the air
192//
193// killough 10/98: simplified
194
195void P_MovePlayer (player_t* player)
196{
197 ticcmd_t *cmd = &player->cmd;
198 mobj_t *mo = player->mo;
199
200 mo->angle += cmd->angleturn << 16;
201 onground = mo->z <= mo->floorz;
202
203 // e6y
204 if (demo_smoothturns && player == &players[displayplayer])
205 R_SmoothPlaying_Add(cmd->angleturn << 16);
206
207 // killough 10/98:
208 //
209 // We must apply thrust to the player and bobbing separately, to avoid
210 // anomalies. The thrust applied to bobbing is always the same strength on
211 // ice, because the player still "works just as hard" to move, while the
212 // thrust applied to the movement varies with 'movefactor'.
213
214 //e6y
215 if ((!demo_compatibility && !mbf_features) || (cmd->forwardmove | cmd->sidemove)) // killough 10/98
216 {
217 if (onground || mo->flags & MF_BOUNCES) // killough 8/9/98
218 {
219 int friction, movefactor = P_GetMoveFactor(mo, &friction);
220
221 // killough 11/98:
222 // On sludge, make bobbing depend on efficiency.
223 // On ice, make it depend on effort.
224
225 int bobfactor =
226 friction < ORIG_FRICTION ? movefactor : ORIG_FRICTION_FACTOR;
227
228 if (cmd->forwardmove)
229 {
230 P_Bob(player,mo->angle,cmd->forwardmove*bobfactor);
231 P_Thrust(player,mo->angle,cmd->forwardmove*movefactor);
232 }
233
234 if (cmd->sidemove)
235 {
236 P_Bob(player,mo->angle-ANG90,cmd->sidemove*bobfactor);
237 P_Thrust(player,mo->angle-ANG90,cmd->sidemove*movefactor);
238 }
239 }
240 if (mo->state == states+S_PLAY)
241 P_SetMobjState(mo,S_PLAY_RUN1);
242 }
243}
244
245#define ANG5 (ANG90/18)
246
247//
248// P_DeathThink
249// Fall on your face when dying.
250// Decrease POV height to floor height.
251//
252
253void P_DeathThink (player_t* player)
254 {
255 angle_t angle;
256 angle_t delta;
257
258 P_MovePsprites (player);
259
260 // fall to the ground
261
262 if (player->viewheight > 6*FRACUNIT)
263 player->viewheight -= FRACUNIT;
264
265 if (player->viewheight < 6*FRACUNIT)
266 player->viewheight = 6*FRACUNIT;
267
268 player->deltaviewheight = 0;
269 onground = (player->mo->z <= player->mo->floorz);
270 P_CalcHeight (player);
271
272 if (player->attacker && player->attacker != player->mo)
273 {
274 angle = R_PointToAngle2 (player->mo->x,
275 player->mo->y,
276 player->attacker->x,
277 player->attacker->y);
278
279 delta = angle - player->mo->angle;
280
281 if (delta < ANG5 || delta > (unsigned)-ANG5)
282 {
283 // Looking at killer,
284 // so fade damage flash down.
285
286 player->mo->angle = angle;
287
288 if (player->damagecount)
289 player->damagecount--;
290 }
291 else if (delta < ANG180)
292 player->mo->angle += ANG5;
293 else
294 player->mo->angle -= ANG5;
295 }
296 else if (player->damagecount)
297 player->damagecount--;
298
299 if (player->cmd.buttons & BT_USE)
300 player->playerstate = PST_REBORN;
301 R_SmoothPlaying_Reset(player); // e6y
302 }
303
304
305//
306// P_PlayerThink
307//
308
309void P_PlayerThink (player_t* player)
310 {
311 ticcmd_t* cmd;
312 weapontype_t newweapon;
313
314 if (movement_smooth && players && &players[displayplayer] == player)
315 {
316 original_view_vars.viewx = player->mo->x;
317 original_view_vars.viewy = player->mo->y;
318 original_view_vars.viewz = player->viewz;
319 original_view_vars.viewangle = R_SmoothPlaying_Get(player->mo->angle) + viewangleoffset;
320 }
321
322 // killough 2/8/98, 3/21/98:
323 if (player->cheats & CF_NOCLIP)
324 player->mo->flags |= MF_NOCLIP;
325 else
326 player->mo->flags &= ~MF_NOCLIP;
327
328 // chain saw run forward
329
330 cmd = &player->cmd;
331 if (player->mo->flags & MF_JUSTATTACKED)
332 {
333 cmd->angleturn = 0;
334 cmd->forwardmove = 0xc800/512;
335 cmd->sidemove = 0;
336 player->mo->flags &= ~MF_JUSTATTACKED;
337 }
338
339 if (player->playerstate == PST_DEAD)
340 {
341 P_DeathThink (player);
342 return;
343 }
344
345 // Move around.
346 // Reactiontime is used to prevent movement
347 // for a bit after a teleport.
348
349 if (player->mo->reactiontime)
350 player->mo->reactiontime--;
351 else
352 P_MovePlayer (player);
353
354 P_CalcHeight (player); // Determines view height and bobbing
355
356 // Determine if there's anything about the sector you're in that's
357 // going to affect you, like painful floors.
358
359 if (player->mo->subsector->sector->special)
360 P_PlayerInSpecialSector (player);
361
362 // Check for weapon change.
363
364 if (cmd->buttons & BT_CHANGE)
365 {
366 // The actual changing of the weapon is done
367 // when the weapon psprite can do it
368 // (read: not in the middle of an attack).
369
370 newweapon = (cmd->buttons & BT_WEAPONMASK)>>BT_WEAPONSHIFT;
371
372 // killough 3/22/98: For demo compatibility we must perform the fist
373 // and SSG weapons switches here, rather than in G_BuildTiccmd(). For
374 // other games which rely on user preferences, we must use the latter.
375
376 if (demo_compatibility)
377 { // compatibility mode -- required for old demos -- killough
378 if (newweapon == wp_fist && player->weaponowned[wp_chainsaw] &&
379 (player->readyweapon != wp_chainsaw ||
380 !player->powers[pw_strength]))
381 newweapon = wp_chainsaw;
382 if (gamemode == commercial &&
383 newweapon == wp_shotgun &&
384 player->weaponowned[wp_supershotgun] &&
385 player->readyweapon != wp_supershotgun)
386 newweapon = wp_supershotgun;
387 }
388
389 // killough 2/8/98, 3/22/98 -- end of weapon selection changes
390
391 if (player->weaponowned[newweapon] && newweapon != player->readyweapon)
392
393 // Do not go to plasma or BFG in shareware,
394 // even if cheated.
395
396 if ((newweapon != wp_plasma && newweapon != wp_bfg)
397 || (gamemode != shareware) )
398 player->pendingweapon = newweapon;
399 }
400
401 // check for use
402
403 if (cmd->buttons & BT_USE)
404 {
405 if (!player->usedown)
406 {
407 P_UseLines (player);
408 player->usedown = true;
409 }
410 }
411 else
412 player->usedown = false;
413
414 // cycle psprites
415
416 P_MovePsprites (player);
417
418 // Counters, time dependent power ups.
419
420 // Strength counts up to diminish fade.
421
422 if (player->powers[pw_strength])
423 player->powers[pw_strength]++;
424
425 // killough 1/98: Make idbeholdx toggle:
426
427 if (player->powers[pw_invulnerability] > 0) // killough
428 player->powers[pw_invulnerability]--;
429
430 if (player->powers[pw_invisibility] > 0) // killough
431 if (! --player->powers[pw_invisibility] )
432 player->mo->flags &= ~MF_SHADOW;
433
434 if (player->powers[pw_infrared] > 0) // killough
435 player->powers[pw_infrared]--;
436
437 if (player->powers[pw_ironfeet] > 0) // killough
438 player->powers[pw_ironfeet]--;
439
440 if (player->damagecount)
441 player->damagecount--;
442
443 if (player->bonuscount)
444 player->bonuscount--;
445
446 // Handling colormaps.
447 // killough 3/20/98: reformat to terse C syntax
448
449 player->fixedcolormap = player->powers[pw_invulnerability] > 4*32 ||
450 player->powers[pw_invulnerability] & 8 ? INVERSECOLORMAP :
451 player->powers[pw_infrared] > 4*32 || player->powers[pw_infrared] & 8;
452 }