Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Iskhodnyy_kod_Doom

.pdf
Скачиваний:
7
Добавлен:
13.02.2015
Размер:
1.01 Mб
Скачать

#define

MAXHEALTH

100

#define

VIEWHEIGHT

(41*FRACUNIT)

//mapblocks are used to check movement

//against lines and things

#define MAPBLOCKUNITS

128

#define MAPBLOCKSIZE

(MAPBLOCKUNITS*FRACUNIT)

#define MAPBLOCKSHIFT

(FRACBITS+7)

#define MAPBMASK

(MAPBLOCKSIZE-1)

#define MAPBTOFRAC

(MAPBLOCKSHIFT-FRACBITS)

// player radius for movement checking

#define PLAYERRADIUS

16*FRACUNIT

//MAXRADIUS is for precalculated sector block boxes

//the spider demon is larger,

//but we do not have any moving sectors nearby

#define MAXRADIUS

32*FRACUNIT

#define GRAVITY

 

FRACUNIT

#define MAXMOVE

 

(30*FRACUNIT)

#define USERANGE

(64*FRACUNIT)

#define MELEERANGE

(64*FRACUNIT)

#define MISSILERANGE

(32*64*FRACUNIT)

// follow a player exlusively for 3 seconds

#define

BASETHRESHOLD

100

//

//P_TICK

//both the head and tail of the thinker list

extern

thinker_t

thinkercap;

void P_InitThinkers (void);

 

void

P_AddThinker (thinker_t* thinker);

void

P_RemoveThinker (thinker_t* thinker);

//

// P_PSPR

//

void P_SetupPsprites (player_t* curplayer); void P_MovePsprites (player_t* curplayer); void P_DropWeapon (player_t* player);

//

 

 

// P_USER

 

 

//

 

 

void

P_PlayerThink (player_t* player);

//

 

 

// P_MOBJ

 

 

//

 

 

#define ONFLOORZ

MININT

441

#define ONCEILINGZ

MAXINT

// Time interval for item respawning.

#define ITEMQUESIZE

128

extern mapthing_t

itemrespawnque[ITEMQUESIZE];

extern int

itemrespawntime[ITEMQUESIZE];

extern int

iquehead;

extern int

iquetail;

void P_RespawnSpecials (void);

mobj_t* P_SpawnMobj

(fixed_t x, fixed_t y, fixed_t z,

mobjtype_t

type );

void

P_RemoveMobj (mobj_t* th);

boolean

P_SetMobjState (mobj_t* mobj, statenum_t state);

void

P_MobjThinker (mobj_t* mobj);

void

P_SpawnPuff (fixed_t x, fixed_t y, fixed_t z);

void

P_SpawnBlood (fixed_t x, fixed_t y, fixed_t z, int damage);

mobj_t* P_SpawnMissile (mobj_t* source, mobj_t* dest, mobjtype_t type);

void P_SpawnPlayerMissile (mobj_t* source, mobjtype_t type);

//

// P_ENEMY

//

void P_NoiseAlert (mobj_t* target, mobj_t* emmiter);

//

 

 

// P_MAPUTL

 

 

//

 

 

typedef struct

 

 

{

 

 

fixed_t

x;

 

fixed_t

y;

 

fixed_t

dx;

 

fixed_t

dy;

 

} divline_t;

 

 

typedef struct

 

 

{

 

 

fixed_t

frac;

// along trace line

boolean

isaline;

 

union {

 

 

mobj_t*

thing;

line_t*

line;

}

d;

} intercept_t;

 

#define MAXINTERCEPTS

128

extern intercept_t

intercepts[MAXINTERCEPTS];

extern intercept_t*

intercept_p;

typedef boolean (*traverser_t) (intercept_t *in);

442

fixed_t P_AproxDistance (fixed_t dx, fixed_t dy);

 

int

P_PointOnLineSide (fixed_t x, fixed_t y,

line_t* line);

int

P_PointOnDivlineSide (fixed_t x, fixed_t

y, divline_t* line);

void

P_MakeDivline (line_t* li, divline_t* dl);

fixed_t P_InterceptVector (divline_t* v2, divline_t*

v1);

int

P_BoxOnLineSide (fixed_t* tmbox, line_t*

ld);

extern fixed_t

opentop;

 

extern fixed_t

openbottom;

 

extern fixed_t

openrange;

 

extern fixed_t

lowfloor;

 

void

P_LineOpening (line_t* linedef);

 

boolean P_BlockLinesIterator (int x, int y, boolean(*func)(line_t*) ); boolean P_BlockThingsIterator (int x, int y, boolean(*func)(mobj_t*) );

#define PT_ADDLINES

1

#define PT_ADDTHINGS

2

#define PT_EARLYOUT

4

extern divline_t

trace;

boolean P_PathTraverse

(fixed_t x1, fixed_t y1, fixed_t x2,

fixed_t

y2,

int

flags,

boolean

(*trav) (intercept_t *));

void P_UnsetThingPosition (mobj_t* thing); void P_SetThingPosition (mobj_t* thing);

//

//P_MAP

//If "floatok" true, move would be ok

//if within "tmfloorz - tmceilingz".

extern boolean

floatok;

extern

fixed_t

tmfloorz;

extern

fixed_t

tmceilingz;

extern line_t* ceilingline;

boolean P_CheckPosition (mobj_t *thing, fixed_t x, fixed_t y); boolean P_TryMove (mobj_t* thing, fixed_t x, fixed_t y); boolean P_TeleportMove (mobj_t* thing, fixed_t x, fixed_t y);

void

P_SlideMove (mobj_t* mo);

 

boolean P_CheckSight (mobj_t* t1, mobj_t* t2);

void

P_UseLines (player_t* player);

boolean P_ChangeSector (sector_t* sector, boolean crunch);

extern mobj_t*

linetarget;

// who got hit (or NULL)

fixed_t

 

 

 

P_AimLineAttack

 

 

(mobj_t* t1, angle_t angle,

fixed_t

distance );

443

void

 

 

P_LineAttack

 

 

( mobj_t*

t1,

 

angle_t

angle,

 

fixed_t

distance,

 

fixed_t

slope,

 

int

damage );

 

void

 

 

P_RadiusAttack

 

 

( mobj_t*

spot,

 

mobj_t*

source,

 

int

damage );

 

//

 

 

// P_SETUP

 

 

//

 

 

extern byte*

rejectmatrix;

// for fast sight rejection

extern short*

blockmaplump;

// offsets in blockmap are from here

extern short*

blockmap;

 

extern int

bmapwidth;

 

extern int

bmapheight;

// in mapblocks

extern fixed_t

bmaporgx;

 

extern fixed_t

bmaporgy;

// origin of block map

extern mobj_t**

blocklinks;

// for thing chains

//

 

 

// P_INTER

 

 

//

 

 

extern int

maxammo[NUMAMMO];

 

extern int

clipammo[NUMAMMO];

 

void P_TouchSpecialThing

( mobj_t* special, mobj_t* toucher );

void P_DamageMobj

(mobj_t* target, mobj_t* inflictor,

mobj_t*

source,

int

damage );

//

// P_SPEC

//

#include "p_spec.h"

#endif

// __P_LOCAL__

//-----------------------------------------------------------------------------

 

//

 

// $Log:$

 

//

 

//-----------------------------------------------------------------------------

 

444

9.11 p map.c

// Emacs style mode select -*- C++ -*- //-----------------------------------------------------------------------------

//

//$Id:$

//Copyright (C) 1993-1996 by id Software, Inc.

//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.

//

//$Log:$

//DESCRIPTION:

//Movement, collision handling.

//Shooting and aiming.

//

//-----------------------------------------------------------------------------

static const char

rcsid[] = "$Id: p_map.c,v 1.5 1997/02/03 22:45:11 b1 Exp $";

#include

<stdlib.h>

#include

"m_bbox.h"

#include

"m_random.h"

#include

"i_system.h"

#include

"doomdef.h"

#include

"p_local.h"

#include

"s_sound.h"

// State.

 

#include

"doomstat.h"

#include

"r_state.h"

// Data.

 

#include

"sounds.h"

fixed_t

tmbbox[4];

mobj_t*

tmthing;

int

tmflags;

fixed_t

tmx;

fixed_t

tmy;

//If "floatok" true, move would be ok

//if within "tmfloorz - tmceilingz".

boolean

floatok;

fixed_t

tmfloorz;

fixed_t

tmceilingz;

fixed_t

tmdropoffz;

//keep track of the line that lowers the ceiling,

//so missiles don’t explode against sky hack walls

line_t*

ceilingline;

445

//keep track of special lines as they are hit,

//but don’t process them until the move is proven valid

#define MAXSPECIALCROSS

8

line_t*

 

spechit[MAXSPECIALCROSS];

int

numspechit;

//

// TELEPORT MOVE

//

//

// PIT_StompThing

//

boolean PIT_StompThing (mobj_t* thing)

{

fixed_t blockdist;

if (!(thing->flags & MF_SHOOTABLE) ) return true;

blockdist = thing->radius + tmthing->radius;

if ( abs(thing->x - tmx) >= blockdist

|| abs(thing->y - tmy) >= blockdist )

{

// didn’t hit it return true;

}

//don’t clip against self if (thing == tmthing)

return true;

//monsters don’t stomp things except on boss level if ( !tmthing->player && gamemap != 30)

return false;

P_DamageMobj (thing, tmthing, tmthing, 10000);

return true;

}

 

//

 

// P_TeleportMove

 

//

 

boolean

 

P_TeleportMove

 

( mobj_t*

thing,

fixed_t

x,

fixed_t

y )

{

 

int

xl;

int

xh;

int

yl;

int

yh;

int

bx;

int

by;

subsector_t*

newsubsec;

446

// kill

anything occupying the position

tmthing

= thing;

tmflags

= thing->flags;

tmx = x; tmy = y;

tmbbox[BOXTOP] = y + tmthing->radius; tmbbox[BOXBOTTOM] = y - tmthing->radius; tmbbox[BOXRIGHT] = x + tmthing->radius; tmbbox[BOXLEFT] = x - tmthing->radius;

newsubsec = R_PointInSubsector (x,y); ceilingline = NULL;

//The base floor/ceiling is from the subsector

//that contains the point.

//Any contacted lines the step closer together

//will adjust them.

tmfloorz = tmdropoffz = newsubsec->sector->floorheight; tmceilingz = newsubsec->sector->ceilingheight;

validcount++; numspechit = 0;

// stomp on any things contacted

xl = (tmbbox[BOXLEFT] - bmaporgx - MAXRADIUS)>>MAPBLOCKSHIFT; xh = (tmbbox[BOXRIGHT] - bmaporgx + MAXRADIUS)>>MAPBLOCKSHIFT; yl = (tmbbox[BOXBOTTOM] - bmaporgy - MAXRADIUS)>>MAPBLOCKSHIFT; yh = (tmbbox[BOXTOP] - bmaporgy + MAXRADIUS)>>MAPBLOCKSHIFT;

for (bx=xl ; bx<=xh ; bx++)

for (by=yl ; by<=yh ; by++)

if (!P_BlockThingsIterator(bx,by,PIT_StompThing)) return false;

//the move is ok,

//so link the thing into its new position P_UnsetThingPosition (thing);

thing->floorz = tmfloorz; thing->ceilingz = tmceilingz; thing->x = x;

thing->y = y;

P_SetThingPosition (thing);

return true;

}

//

// MOVEMENT ITERATOR FUNCTIONS

//

//

//PIT_CheckLine

//Adjusts tmfloorz and tmceilingz as lines are contacted

boolean PIT_CheckLine (line_t* ld)

{

if (tmbbox[BOXRIGHT] <= ld->bbox[BOXLEFT]

||tmbbox[BOXLEFT] >= ld->bbox[BOXRIGHT]

||tmbbox[BOXTOP] <= ld->bbox[BOXBOTTOM]

447

|| tmbbox[BOXBOTTOM] >= ld->bbox[BOXTOP] ) return true;

if (P_BoxOnLineSide (tmbbox, ld) != -1) return true;

//A line has been hit

//The moving thing’s destination position will cross

//the given line.

//If this should not be allowed, return false.

//If the line is special, keep track of it

//to process later if the move is proven ok.

//NOTE: specials are NOT sorted by order,

//so two special lines that are only 8 pixels apart

//could be crossed in either order.

if (!ld->backsector)

 

return false;

// one sided line

if (!(tmthing->flags & MF_MISSILE) )

{

if ( ld->flags & ML_BLOCKING )

return

false;

// explicitly blocking

everything

if ( !tmthing->player && ld->flags & ML_BLOCKMONSTERS )

return

false;

// block monsters only

 

}

//set openrange, opentop, openbottom P_LineOpening (ld);

//adjust floor / ceiling heights

if (opentop < tmceilingz)

{

tmceilingz = opentop; ceilingline = ld;

}

if (openbottom > tmfloorz) tmfloorz = openbottom;

if (lowfloor < tmdropoffz) tmdropoffz = lowfloor;

// if contacted a special line, add it to the list if (ld->special)

{

spechit[numspechit] = ld; numspechit++;

}

return true;

}

//

// PIT_CheckThing

//

boolean PIT_CheckThing (mobj_t* thing)

{

fixed_t

blockdist;

boolean

solid;

int

damage;

if (!(thing->flags & (MF_SOLID|MF_SPECIAL|MF_SHOOTABLE) ))

448

return true;

blockdist = thing->radius + tmthing->radius;

if ( abs(thing->x - tmx) >= blockdist

|| abs(thing->y - tmy) >= blockdist )

{

// didn’t hit it return true;

}

//don’t clip against self if (thing == tmthing)

return true;

//check for skulls slamming into things if (tmthing->flags & MF_SKULLFLY)

{

damage = ((P_Random()%8)+1)*tmthing->info->damage;

P_DamageMobj (thing, tmthing, tmthing, damage);

tmthing->flags &= ~MF_SKULLFLY;

tmthing->momx = tmthing->momy = tmthing->momz = 0;

P_SetMobjState (tmthing, tmthing->info->spawnstate);

return false;

// stop moving

}

 

// missiles can hit other things if (tmthing->flags & MF_MISSILE)

{

// see if it went over / under

 

 

if

(tmthing->z > thing->z + thing->height)

 

return

true;

//

overhead

if

(tmthing->z+tmthing->height < thing->z)

 

return

true;

//

underneath

if (tmthing->target && ( tmthing->target->type == thing->type ||

(tmthing->target->type == MT_KNIGHT && thing->type == MT_BRUISER)|| (tmthing->target->type == MT_BRUISER && thing->type == MT_KNIGHT) ) )

{

// Don’t hit same species as originator. if (thing == tmthing->target)

return true;

if (thing->type != MT_PLAYER)

{

//Explode, but do no damage.

//Let players missile other players. return false;

}

}

if (! (thing->flags & MF_SHOOTABLE) )

{

// didn’t do any damage

return !(thing->flags & MF_SOLID);

}

// damage / explode

damage = ((P_Random()%8)+1)*tmthing->info->damage;

449

P_DamageMobj (thing, tmthing, tmthing->target, damage);

// don’t traverse any more return false;

}

// check for special pickup

if (thing->flags & MF_SPECIAL)

{

solid = thing->flags&MF_SOLID; if (tmflags&MF_PICKUP)

{

// can remove thing P_TouchSpecialThing (thing, tmthing);

}

return !solid;

}

return !(thing->flags & MF_SOLID);

}

//

// MOVEMENT CLIPPING

//

//

//P_CheckPosition

//This is purely informative, nothing is modified

//(except things picked up).

//

//in:

//a mobj_t (can be valid or invalid)

//a position to be checked

//(doesn’t need to be related to the mobj_t->x,y)

//during:

//special things are touched if MF_PICKUP

//early out on solid lines?

//

//out:

//newsubsec

//floorz

//ceilingz

//tmdropoffz

//the lowest point contacted

//(monsters won’t move to a dropoff)

//speciallines[]

//numspeciallines

//

 

boolean

 

P_CheckPosition

 

( mobj_t*

thing,

fixed_t

x,

fixed_t

y )

{

 

int

xl;

int

xh;

int

yl;

int

yh;

int

bx;

int

by;

subsector_t*

newsubsec;

tmthing = thing;

 

450

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]