/* Emacs style mode select -*- C++ -*-
*-----------------------------------------------------------------------------
*
*
* PrBoom a Doom port merged with LxDoom and LSDLDoom
* based on BOOM, a modified and improved DOOM engine
* Copyright (C) 1999 by
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
* Copyright (C) 1999-2000 by
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* DESCRIPTION:
* Movement, collision handling.
* Shooting and aiming.
*
*-----------------------------------------------------------------------------*/
#include "doomstat.h"
#include "r_main.h"
#include "p_mobj.h"
#include "p_maputl.h"
#include "p_map.h"
#include "p_setup.h"
#include "p_spec.h"
#include "s_sound.h"
#include "sounds.h"
#include "p_inter.h"
#include "m_random.h"
#include "m_bbox.h"
#include "i_system.h"
#include "rockmacros.h"
static mobj_t *tmthing;
static fixed_t tmx;
static fixed_t tmy;
static int pe_x; // Pain Elemental position for Lost Soul checks // phares
static int pe_y; // Pain Elemental position for Lost Soul checks // phares
static int ls_x; // Lost Soul position for Lost Soul checks // phares
static int ls_y; // Lost Soul position for Lost Soul checks // phares
// If "floatok" true, move would be ok
// if within "tmfloorz - tmceilingz".
boolean floatok;
/* killough 11/98: if "felldown" true, object was pushed down ledge */
boolean felldown;
// The tm* items are used to hold information globally, usually for
// line or object intersection checking
fixed_t tmbbox[4]; // bounding box for line intersection checks
fixed_t tmfloorz; // floor you'd hit if free to fall
fixed_t tmceilingz; // ceiling of sector you're in
fixed_t tmdropoffz; // dropoff on other side of line you're crossing
// keep track of the line that lowers the ceiling,
// so missiles don't explode against sky hack walls
line_t *ceilingline;
line_t *blockline; /* killough 8/11/98: blocking linedef */
line_t *floorline; /* killough 8/1/98: Highest touched floor */
static int tmunstuck; /* killough 8/1/98: whether to allow unsticking */
// keep track of special lines as they are hit,
// but don't process them until the move is proven valid
// 1/11/98 killough: removed limit on special lines crossed
line_t **spechit; // new code -- killough
static int spechit_max; // killough
int numspechit;
// Temporary holder for thing_sectorlist threads
msecnode_t* sector_list = NULL; // phares 3/16/98
//
// TELEPORT MOVE
//
//
// PIT_StompThing
//
static boolean telefrag; /* killough 8/9/98: whether to telefrag at exit */
boolean PIT_StompThing (mobj_t* thing)
{
fixed_t blockdist;
// phares 9/10/98: moved this self-check to start of routine
// don't clip against self
if (thing == tmthing)
return true;
if (!(thing->flags & MF_SHOOTABLE)) // Can't shoot it? Can't stomp it!
return true;
blockdist = thing->radius + tmthing->radius;
if (D_abs(thing->x - tmx) >= blockdist || D_abs(thing->y - tmy) >= blockdist)
return true; // didn't hit it
// monsters don't stomp things except on boss level
if (!telefrag) // killough 8/9/98: make consistent across all levels
return false;
P_DamageMobj (thing, tmthing, tmthing, 10000); // Stomp!
return true;
}
/*
* killough 8/28/98:
*
* P_GetFriction()
*
* Returns the friction associated with a particular mobj.
*/
int P_GetFriction(const mobj_t *mo, int *frictionfactor)
{
int friction = ORIG_FRICTION;
int movefactor = ORIG_FRICTION_FACTOR;
const msecnode_t *m;
const sector_t *sec;
/* Assign the friction value to objects on the floor, non-floating,
* and clipped. Normally the object's friction value is kept at
* ORIG_FRICTION and this thinker changes it for icy or muddy floors.
*
* When the object is straddling sectors with the same
* floorheight that have different frictions, use the lowest
* friction value (muddy has precedence over icy).
*/
if (!(mo->flags & (MF_NOCLIP|MF_NOGRAVITY))
&& (mbf_features || (mo->player && !compatibility)) &&
variable_friction)
for (m = mo->touching_sectorlist; m; m = m->m_tnext)
if ((sec = m->m_sector)->special & FRICTION_MASK &&
(sec->friction < friction || friction == ORIG_FRICTION) &&
(mo->z <= sec->floorheight ||
(sec->heightsec != -1 &&
mo->z <= sectors[sec->heightsec].floorheight &&
mbf_features)))
friction = sec->friction, movefactor = sec->movefactor;
if (frictionfactor)
*frictionfactor = movefactor;
return friction;
}
/* phares 3/19/98
* P_GetMoveFactor() returns the value by which the x,y
* movements are multiplied to add to player movement.
*
* killough 8/28/98: rewritten
*/
int P_GetMoveFactor(const mobj_t *mo, int *frictionp)
{
int movefactor, friction;
// If the floor is icy or muddy, it's harder to get moving. This is where
// the different friction factors are applied to 'trying to move'. In
// p_mobj.c, the friction factors are applied as you coast and slow down.
if ((friction = P_GetFriction(mo, &movefactor)) < ORIG_FRICTION)
{
// phares 3/11/98: you start off slowly, then increase as
// you get better footing
int momentum = P_AproxDistance(mo->momx,mo->momy);
if (momentum > MORE_FRICTION_MOMENTUM<<2)
movefactor <<= 3;
else if (momentum > MORE_FRICTION_MOMENTUM<<1)
movefactor <<= 2;
else if (momentum > MORE_FRICTION_MOMENTUM)
movefactor <<= 1;
}
if (frictionp)
*frictionp = friction;
|