123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387 |
- // Emacs style mode select -*- C++ -*-
- //-----------------------------------------------------------------------------
- //
- // $Id:$
- //
- // Copyright (C) 1993-1996 by id Software, Inc.
- //
- // This source is available for distribution and/or modification
- // only under the terms of the DOOM Source Code License as
- // published by id Software. All rights reserved.
- //
- // The source is distributed in the hope that it will be useful,
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
- // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
- // for more details.
- //
- // $Log:$
- //
- // DESCRIPTION:
- // Player related stuff.
- // Bobbing POV/weapon, movement.
- // Pending weapon.
- //
- //-----------------------------------------------------------------------------
- static const char
- rcsid[] = "$Id: p_user.c,v 1.3 1997/01/28 22:08:29 b1 Exp $";
- #include "doomdef.h"
- #include "d_event.h"
- #include "p_local.h"
- #include "doomstat.h"
- // Index of the special effects (INVUL inverse) map.
- #define INVERSECOLORMAP 32
- //
- // Movement.
- //
- // 16 pixels of bob
- #define MAXBOB 0x100000
- boolean onground;
- //
- // P_Thrust
- // Moves the given origin along a given angle.
- //
- void
- P_Thrust
- ( player_t* player,
- angle_t angle,
- fixed_t move )
- {
- angle >>= ANGLETOFINESHIFT;
-
- player->mo->momx += FixedMul(move,finecosine[angle]);
- player->mo->momy += FixedMul(move,finesine[angle]);
- }
- //
- // P_CalcHeight
- // Calculate the walking / running height adjustment
- //
- void P_CalcHeight (player_t* player)
- {
- int angle;
- fixed_t bob;
-
- // Regular movement bobbing
- // (needs to be calculated for gun swing
- // even if not on ground)
- // OPTIMIZE: tablify angle
- // Note: a LUT allows for effects
- // like a ramp with low health.
- player->bob =
- FixedMul (player->mo->momx, player->mo->momx)
- + FixedMul (player->mo->momy,player->mo->momy);
-
- player->bob >>= 2;
- if (player->bob>MAXBOB)
- player->bob = MAXBOB;
- if ((player->cheats & CF_NOMOMENTUM) || !onground)
- {
- player->viewz = player->mo->z + VIEWHEIGHT;
- if (player->viewz > player->mo->ceilingz-4*FRACUNIT)
- player->viewz = player->mo->ceilingz-4*FRACUNIT;
- player->viewz = player->mo->z + player->viewheight;
- return;
- }
-
- angle = (FINEANGLES/20*leveltime)&FINEMASK;
- bob = FixedMul ( player->bob/2, finesine[angle]);
-
- // move viewheight
- if (player->playerstate == PST_LIVE)
- {
- player->viewheight += player->deltaviewheight;
- if (player->viewheight > VIEWHEIGHT)
- {
- player->viewheight = VIEWHEIGHT;
- player->deltaviewheight = 0;
- }
- if (player->viewheight < VIEWHEIGHT/2)
- {
- player->viewheight = VIEWHEIGHT/2;
- if (player->deltaviewheight <= 0)
- player->deltaviewheight = 1;
- }
-
- if (player->deltaviewheight)
- {
- player->deltaviewheight += FRACUNIT/4;
- if (!player->deltaviewheight)
- player->deltaviewheight = 1;
- }
- }
- player->viewz = player->mo->z + player->viewheight + bob;
- if (player->viewz > player->mo->ceilingz-4*FRACUNIT)
- player->viewz = player->mo->ceilingz-4*FRACUNIT;
- }
- //
- // P_MovePlayer
- //
- void P_MovePlayer (player_t* player)
- {
- ticcmd_t* cmd;
-
- cmd = &player->cmd;
-
- player->mo->angle += (cmd->angleturn<<16);
- // Do not let the player control movement
- // if not onground.
- onground = (player->mo->z <= player->mo->floorz);
-
- if (cmd->forwardmove && onground)
- P_Thrust (player, player->mo->angle, cmd->forwardmove*2048);
-
- if (cmd->sidemove && onground)
- P_Thrust (player, player->mo->angle-ANG90, cmd->sidemove*2048);
- if ( (cmd->forwardmove || cmd->sidemove)
- && player->mo->state == &states[S_PLAY] )
- {
- P_SetMobjState (player->mo, S_PLAY_RUN1);
- }
- }
- //
- // P_DeathThink
- // Fall on your face when dying.
- // Decrease POV height to floor height.
- //
- #define ANG5 (ANG90/18)
- void P_DeathThink (player_t* player)
- {
- angle_t angle;
- angle_t delta;
- P_MovePsprites (player);
-
- // fall to the ground
- if (player->viewheight > 6*FRACUNIT)
- player->viewheight -= FRACUNIT;
- if (player->viewheight < 6*FRACUNIT)
- player->viewheight = 6*FRACUNIT;
- player->deltaviewheight = 0;
- onground = (player->mo->z <= player->mo->floorz);
- P_CalcHeight (player);
-
- if (player->attacker && player->attacker != player->mo)
- {
- angle = R_PointToAngle2 (player->mo->x,
- player->mo->y,
- player->attacker->x,
- player->attacker->y);
-
- delta = angle - player->mo->angle;
-
- if (delta < ANG5 || delta > (unsigned)-ANG5)
- {
- // Looking at killer,
- // so fade damage flash down.
- player->mo->angle = angle;
- if (player->damagecount)
- player->damagecount--;
- }
- else if (delta < ANG180)
- player->mo->angle += ANG5;
- else
- player->mo->angle -= ANG5;
- }
- else if (player->damagecount)
- player->damagecount--;
-
- if (player->cmd.buttons & BT_USE)
- player->playerstate = PST_REBORN;
- }
- //
- // P_PlayerThink
- //
- void P_PlayerThink (player_t* player)
- {
- ticcmd_t* cmd;
- weapontype_t newweapon;
-
- // fixme: do this in the cheat code
- if (player->cheats & CF_NOCLIP)
- player->mo->flags |= MF_NOCLIP;
- else
- player->mo->flags &= ~MF_NOCLIP;
-
- // chain saw run forward
- cmd = &player->cmd;
- if (player->mo->flags & MF_JUSTATTACKED)
- {
- cmd->angleturn = 0;
- cmd->forwardmove = 0xc800/512;
- cmd->sidemove = 0;
- player->mo->flags &= ~MF_JUSTATTACKED;
- }
-
-
- if (player->playerstate == PST_DEAD)
- {
- P_DeathThink (player);
- return;
- }
-
- // Move around.
- // Reactiontime is used to prevent movement
- // for a bit after a teleport.
- if (player->mo->reactiontime)
- player->mo->reactiontime--;
- else
- P_MovePlayer (player);
-
- P_CalcHeight (player);
- if (player->mo->subsector->sector->special)
- P_PlayerInSpecialSector (player);
-
- // Check for weapon change.
- // A special event has no other buttons.
- if (cmd->buttons & BT_SPECIAL)
- cmd->buttons = 0;
-
- if (cmd->buttons & BT_CHANGE)
- {
- // The actual changing of the weapon is done
- // when the weapon psprite can do it
- // (read: not in the middle of an attack).
- newweapon = (cmd->buttons&BT_WEAPONMASK)>>BT_WEAPONSHIFT;
-
- if (newweapon == wp_fist
- && player->weaponowned[wp_chainsaw]
- && !(player->readyweapon == wp_chainsaw
- && player->powers[pw_strength]))
- {
- newweapon = wp_chainsaw;
- }
-
- if ( (gamemode == commercial)
- && newweapon == wp_shotgun
- && player->weaponowned[wp_supershotgun]
- && player->readyweapon != wp_supershotgun)
- {
- newweapon = wp_supershotgun;
- }
-
- if (player->weaponowned[newweapon]
- && newweapon != player->readyweapon)
- {
- // Do not go to plasma or BFG in shareware,
- // even if cheated.
- if ((newweapon != wp_plasma
- && newweapon != wp_bfg)
- || (gamemode != shareware) )
- {
- player->pendingweapon = newweapon;
- }
- }
- }
-
- // check for use
- if (cmd->buttons & BT_USE)
- {
- if (!player->usedown)
- {
- P_UseLines (player);
- player->usedown = true;
- }
- }
- else
- player->usedown = false;
-
- // cycle psprites
- P_MovePsprites (player);
-
- // Counters, time dependend power ups.
- // Strength counts up to diminish fade.
- if (player->powers[pw_strength])
- player->powers[pw_strength]++;
-
- if (player->powers[pw_invulnerability])
- player->powers[pw_invulnerability]--;
- if (player->powers[pw_invisibility])
- if (! --player->powers[pw_invisibility] )
- player->mo->flags &= ~MF_SHADOW;
-
- if (player->powers[pw_infrared])
- player->powers[pw_infrared]--;
-
- if (player->powers[pw_ironfeet])
- player->powers[pw_ironfeet]--;
-
- if (player->damagecount)
- player->damagecount--;
-
- if (player->bonuscount)
- player->bonuscount--;
-
- // Handling colormaps.
- if (player->powers[pw_invulnerability])
- {
- if (player->powers[pw_invulnerability] > 4*32
- || (player->powers[pw_invulnerability]&8) )
- player->fixedcolormap = INVERSECOLORMAP;
- else
- player->fixedcolormap = 0;
- }
- else if (player->powers[pw_infrared])
- {
- if (player->powers[pw_infrared] > 4*32
- || (player->powers[pw_infrared]&8) )
- {
- // almost full bright
- player->fixedcolormap = 1;
- }
- else
- player->fixedcolormap = 0;
- }
- else
- player->fixedcolormap = 0;
- }
|