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

Iskhodnyy_kod_Doom

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

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

static const char

rcsid[] = "$Id: p_sight.c,v 1.3 1997/01/28 22:08:28 b1 Exp $";

#include "doomdef.h"

#include "i_system.h" #include "p_local.h"

// State.

#include "r_state.h"

//

 

 

// P_CheckSight

 

 

//

 

 

fixed_t

sightzstart;

// eye z of looker

fixed_t

topslope;

 

fixed_t

bottomslope;

// slopes to top and bottom of target

divline_t

strace;

// from t1 to t2

fixed_t

t2x;

 

fixed_t

t2y;

 

int

sightcounts[2];

 

//

//P_DivlineSide

//Returns side 0 (front), 1 (back), or 2 (on).

int P_DivlineSide

( fixed_t x, fixed_t y,

divline_t* node )

{

fixed_t

dx;

fixed_t

dy;

fixed_t

left;

fixed_t

right;

if (!node->dx)

{

if (x==node->x) return 2;

if (x <= node->x)

return node->dy > 0;

return node->dy < 0;

}

if (!node->dy)

{

if (x==node->y) return 2;

if (y <= node->y)

return node->dx < 0;

return node->dx > 0;

}

541

dx = (x - node->x); dy = (y - node->y);

left = (node->dy>>FRACBITS) * (dx>>FRACBITS); right = (dy>>FRACBITS) * (node->dx>>FRACBITS);

if

(right <

left)

 

 

return 0;

// front side

if

(left ==

right)

 

 

return 2;

 

return 1;

 

// back side

}

//

//P_InterceptVector2

//Returns the fractional intercept point

//along the first divline.

//This is only called by the addthings and addlines traversers.

fixed_t P_InterceptVector2

( divline_t* v2,

divline_t*

v1 )

{

 

fixed_t

frac;

fixed_t

num;

fixed_t

den;

den = FixedMul (v1->dy>>8,v2->dx) - FixedMul(v1->dx>>8,v2->dy);

if (den == 0) return 0;

//I_Error ("P_InterceptVector: parallel");

num = FixedMul ( (v1->x - v2->x)>>8 ,v1->dy) + FixedMul ( (v2->y - v1->y)>>8 , v1->dx);

frac = FixedDiv (num , den);

return frac;

}

//

//P_CrossSubsector

//Returns true

//if strace crosses the given subsector successfully.

boolean P_CrossSubsector (int num)

{

seg_t*

seg;

line_t*

line;

int

s1;

int

s2;

int

count;

subsector_t*

sub;

sector_t*

front;

sector_t*

back;

fixed_t

opentop;

fixed_t

openbottom;

divline_t

divl;

vertex_t*

v1;

vertex_t*

v2;

fixed_t

frac;

fixed_t

slope;

542

#ifdef RANGECHECK

if (num>=numsubsectors)

I_Error ("P_CrossSubsector: ss %i with numss = %i", num,

numsubsectors);

#endif

sub = &subsectors[num];

// check lines

count = sub->numlines;

seg = &segs[sub->firstline];

for ( ; count ; seg++, count--)

{

line = seg->linedef;

// allready checked other side?

if (line->validcount == validcount) continue;

line->validcount = validcount;

v1 = line->v1;

v2 = line->v2;

s1 = P_DivlineSide (v1->x,v1->y, &strace); s2 = P_DivlineSide (v2->x, v2->y, &strace);

// line isn’t crossed? if (s1 == s2)

continue;

divl.x = v1->x; divl.y = v1->y;

divl.dx = v2->x - v1->x; divl.dy = v2->y - v1->y;

s1 = P_DivlineSide (strace.x, strace.y, &divl);

s2 = P_DivlineSide (t2x, t2y, &divl);

//line isn’t crossed? if (s1 == s2)

continue;

//stop because it is not two sided anyway

//might do this after updating validcount? if ( !(line->flags & ML_TWOSIDED) )

return false;

//crosses a two sided line

front = seg->frontsector; back = seg->backsector;

// no wall to block sight with?

if (front->floorheight == back->floorheight

&& front->ceilingheight == back->ceilingheight) continue;

//possible occluder

//because of ceiling height differences

if (front->ceilingheight < back->ceilingheight) opentop = front->ceilingheight;

else

opentop = back->ceilingheight;

543

// because of ceiling height differences

if (front->floorheight > back->floorheight)

openbottom

= front->floorheight;

else

 

 

openbottom

= back->floorheight;

// quick test for

totally closed doors

if (openbottom

>=

opentop)

return false;

// stop

frac = P_InterceptVector2 (&strace, &divl);

if (front->floorheight != back->floorheight)

{

slope = FixedDiv (openbottom - sightzstart , frac); if (slope > bottomslope)

bottomslope = slope;

}

if (front->ceilingheight != back->ceilingheight)

{

slope = FixedDiv (opentop - sightzstart , frac); if (slope < topslope)

topslope = slope;

}

 

if (topslope <= bottomslope)

 

return false;

// stop

}

 

// passed the subsector ok

 

return true;

 

}

//

//P_CrossBSPNode

//Returns true

//if strace crosses the given node successfully.

boolean P_CrossBSPNode (int bspnum)

{

node_t*

bsp;

int

side;

if (bspnum & NF_SUBSECTOR)

{

 

if (bspnum

== -1)

return

P_CrossSubsector (0);

else

 

return

P_CrossSubsector (bspnum&(~NF_SUBSECTOR));

}

 

bsp = &nodes[bspnum];

// decide which side the start point is on

side = P_DivlineSide (strace.x, strace.y, (divline_t *)bsp); if (side == 2)

side = 0; // an "on" should cross both sides

// cross the starting side

if (!P_CrossBSPNode (bsp->children[side]) ) return false;

// the partition plane is crossed here

544

if (side == P_DivlineSide (t2x, t2y,(divline_t *)bsp))

{

// the line doesn’t touch the other side return true;

}

// cross the ending side

return P_CrossBSPNode (bsp->children[side^1]);

}

//

//P_CheckSight

//Returns true

//if a straight line between t1 and t2 is unobstructed.

//Uses REJECT.

//

 

boolean

 

P_CheckSight

 

( mobj_t*

t1,

mobj_t*

t2 )

{

 

int

s1;

int

s2;

int

pnum;

int

bytenum;

int

bitnum;

//First check for trivial rejection.

//Determine subsector entries in REJECT table. s1 = (t1->subsector->sector - sectors);

s2 = (t2->subsector->sector - sectors); pnum = s1*numsectors + s2;

bytenum = pnum>>3; bitnum = 1 << (pnum&7);

//Check in REJECT table.

if (rejectmatrix[bytenum]&bitnum)

{

sightcounts[0]++;

// can’t possibly be connected return false;

}

//An unobstructed LOS is possible.

//Now look from eyes of t1 to any part of t2. sightcounts[1]++;

validcount++;

sightzstart = t1->z + t1->height - (t1->height>>2); topslope = (t2->z+t2->height) - sightzstart; bottomslope = (t2->z) - sightzstart;

strace.x = t1->x; strace.y = t1->y; t2x = t2->x;

t2y = t2->y;

strace.dx = t2->x - t1->x; strace.dy = t2->y - t1->y;

// the head node is the last node output return P_CrossBSPNode (numnodes-1);

545

}

9.23 p spec.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:

//Implements special effects:

//Texture animation, height or lighting changes

//according to adjacent sectors, respective

//utility functions, etc.

//Line Tag handling. Line and Sector triggers.

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

static const char

rcsid[] = "$Id: p_spec.c,v 1.6 1997/02/03 22:45:12 b1 Exp $";

#include <stdlib.h>

#include "doomdef.h" #include "doomstat.h"

#include "i_system.h" #include "z_zone.h" #include "m_argv.h" #include "m_random.h" #include "w_wad.h"

#include "r_local.h" #include "p_local.h"

#include "g_game.h"

#include "s_sound.h"

// State.

#include "r_state.h"

// Data.

#include "sounds.h"

//

//Animating textures and planes

//There is another anim_t used in wi_stuff, unrelated.

546

//

 

 

 

typedef

struct

 

 

{

 

 

 

boolean

istexture;

 

int

 

picnum;

 

int

 

basepic;

 

int

 

numpics;

 

int

 

speed;

 

} anim_t;

 

 

//

 

 

 

//

source animation definition

 

//

 

 

 

typedef

struct

 

 

{

 

 

 

boolean

istexture;

// if false, it is a flat

char

 

endname[9];

 

char

 

startname[9];

 

int

 

speed;

 

} animdef_t;

 

 

#define

MAXANIMS

32

 

extern anim_t

anims[MAXANIMS];

 

extern anim_t*

lastanim;

 

//

//P_InitPicAnims

//Floor/ceiling animation sequences,

//defined by first and last frame,

//i.e. the flat (64x64 tile) name to

//be used.

//The full animation sequence is given

//using all the flats between the start

//and end entry, in the order found in

//the WAD file.

//

animdef_t animdefs[] =

{

{false,

"NUKAGE3",

"NUKAGE1",

8},

{false,

"FWATER4",

"FWATER1",

8},

{false,

"SWATER4",

"SWATER1",

8},

{false,

"LAVA4",

"LAVA1",

8},

{false,

"BLOOD3",

"BLOOD1",

8},

// DOOM II flat animations.

 

 

{false,

"RROCK08",

"RROCK05",

8},

{false,

"SLIME04",

"SLIME01",

8},

{false,

"SLIME08",

"SLIME05",

8},

{false,

"SLIME12",

"SLIME09",

8},

{true,

"BLODGR4",

"BLODGR1",

8},

{true,

"SLADRIP3",

"SLADRIP1",

8},

{true,

"BLODRIP4",

"BLODRIP1",

8},

{true,

"FIREWALL",

"FIREWALA",

8},

{true,

"GSTFONT3",

"GSTFONT1",

8},

{true,

"FIRELAVA",

"FIRELAV3",

8},

{true,

"FIREMAG3",

"FIREMAG1",

8},

{true,

"FIREBLU2",

"FIREBLU1",

8},

547

{true,

"ROCKRED3",

"ROCKRED1",

8},

{true,

"BFALL4",

"BFALL1",

8},

{true,

"SFALL4",

"SFALL1",

8},

{true,

"WFALL4",

"WFALL1",

8},

{true,

"DBRAIN4",

"DBRAIN1",

8},

{-1}

 

 

 

 

};

 

 

 

 

anim_t

 

anims[MAXANIMS];

 

anim_t*

 

lastanim;

 

 

//

 

 

 

 

//

Animating line specials

 

 

//

 

 

 

 

#define

MAXLINEANIMS

64

 

extern

short

numlinespecials;

 

extern

line_t*

linespeciallist[MAXLINEANIMS];

 

void P_InitPicAnims (void)

 

 

{

 

 

 

 

int

 

i;

 

 

//

Init animation

 

 

lastanim =

anims;

for (i=0 ;

animdefs[i].istexture != -1 ; i++)

{

 

if (animdefs[i].istexture)

{

 

//

different episode ?

if

(R_CheckTextureNumForName(animdefs[i].startname) == -1)

 

continue;

lastanim->picnum = R_TextureNumForName (animdefs[i].endname); lastanim->basepic = R_TextureNumForName (animdefs[i].startname);

}

else

{

if (W_CheckNumForName(animdefs[i].startname) == -1) continue;

lastanim->picnum = R_FlatNumForName (animdefs[i].endname); lastanim->basepic = R_FlatNumForName (animdefs[i].startname);

}

lastanim->istexture = animdefs[i].istexture; lastanim->numpics = lastanim->picnum - lastanim->basepic + 1;

if (lastanim->numpics < 2)

I_Error ("P_InitPicAnims: bad cycle from %s to %s", animdefs[i].startname, animdefs[i].endname);

lastanim->speed = animdefs[i].speed; lastanim++;

}

}

548

//

// UTILITIES

//

//

//getSide()

//Will return a side_t*

//given the number of the current sector,

//the line number, and the side (0/1) that you want.

side_t* getSide

( int

currentSector,

int

line,

int

side )

{

 

return &sides[ (sectors[currentSector].lines[line])->sidenum[side] ];

}

//

//getSector()

//Will return a sector_t*

//given the number of the current sector,

//the line number and the side (0/1) that you want.

sector_t* getSector

( int

currentSector,

int

line,

int

side )

{

 

return sides[ (sectors[currentSector].lines[line])->sidenum[side] ].sector;

}

//

//twoSided()

//Given the sector number and the line number,

//it will tell you whether the line is two-sided or not.

int twoSided

( int

sector,

int

line )

{

 

return (sectors[sector].lines[line])->flags & ML_TWOSIDED;

}

//

//getNextSector()

//Return sector_t * of sector next to current.

//NULL if not two-sided line

//

 

 

sector_t*

 

 

getNextSector

 

 

( line_t*

line,

 

sector_t*

sec

)

549

{

if (!(line->flags & ML_TWOSIDED)) return NULL;

if (line->frontsector == sec) return line->backsector;

return line->frontsector;

}

//

//P_FindLowestFloorSurrounding()

//FIND LOWEST FLOOR HEIGHT IN SURROUNDING SECTORS

fixed_t P_FindLowestFloorSurrounding(sector_t* sec)

{

int

i;

line_t*

check;

sector_t*

other;

fixed_t

floor = sec->floorheight;

for (i=0 ;i < sec->linecount ; i++)

{

check = sec->lines[i];

other = getNextSector(check,sec);

if (!other) continue;

if (other->floorheight < floor) floor = other->floorheight;

}

return floor;

}

//

//P_FindHighestFloorSurrounding()

//FIND HIGHEST FLOOR HEIGHT IN SURROUNDING SECTORS

fixed_t P_FindHighestFloorSurrounding(sector_t *sec)

{

int

i;

line_t*

check;

sector_t*

other;

fixed_t

floor = -500*FRACUNIT;

for (i=0 ;i < sec->linecount ; i++)

{

check = sec->lines[i];

other = getNextSector(check,sec);

if (!other) continue;

if (other->floorheight > floor) floor = other->floorheight;

}

return floor;

}

550

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