0,0 → 1,555 |
// 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: |
// Floor animation: raising stairs. |
// |
//----------------------------------------------------------------------------- |
|
static const char |
rcsid[] = "$Id: p_floor.c,v 1.4 1997/02/03 16:47:54 b1 Exp $"; |
|
|
#include "z_zone.h" |
#include "doomdef.h" |
#include "p_local.h" |
|
#include "s_sound.h" |
|
// State. |
#include "doomstat.h" |
#include "r_state.h" |
// Data. |
#include "sounds.h" |
|
|
// |
// FLOORS |
// |
|
// |
// Move a plane (floor or ceiling) and check for crushing |
// |
result_e |
T_MovePlane |
( sector_t* sector, |
fixed_t speed, |
fixed_t dest, |
boolean crush, |
int floorOrCeiling, |
int direction ) |
{ |
boolean flag; |
fixed_t lastpos; |
|
switch(floorOrCeiling) |
{ |
case 0: |
// FLOOR |
switch(direction) |
{ |
case -1: |
// DOWN |
if (sector->floorheight - speed < dest) |
{ |
lastpos = sector->floorheight; |
sector->floorheight = dest; |
flag = P_ChangeSector(sector,crush); |
if (flag == true) |
{ |
sector->floorheight =lastpos; |
P_ChangeSector(sector,crush); |
//return crushed; |
} |
return pastdest; |
} |
else |
{ |
lastpos = sector->floorheight; |
sector->floorheight -= speed; |
flag = P_ChangeSector(sector,crush); |
if (flag == true) |
{ |
sector->floorheight = lastpos; |
P_ChangeSector(sector,crush); |
return crushed; |
} |
} |
break; |
|
case 1: |
// UP |
if (sector->floorheight + speed > dest) |
{ |
lastpos = sector->floorheight; |
sector->floorheight = dest; |
flag = P_ChangeSector(sector,crush); |
if (flag == true) |
{ |
sector->floorheight = lastpos; |
P_ChangeSector(sector,crush); |
//return crushed; |
} |
return pastdest; |
} |
else |
{ |
// COULD GET CRUSHED |
lastpos = sector->floorheight; |
sector->floorheight += speed; |
flag = P_ChangeSector(sector,crush); |
if (flag == true) |
{ |
if (crush == true) |
return crushed; |
sector->floorheight = lastpos; |
P_ChangeSector(sector,crush); |
return crushed; |
} |
} |
break; |
} |
break; |
|
case 1: |
// CEILING |
switch(direction) |
{ |
case -1: |
// DOWN |
if (sector->ceilingheight - speed < dest) |
{ |
lastpos = sector->ceilingheight; |
sector->ceilingheight = dest; |
flag = P_ChangeSector(sector,crush); |
|
if (flag == true) |
{ |
sector->ceilingheight = lastpos; |
P_ChangeSector(sector,crush); |
//return crushed; |
} |
return pastdest; |
} |
else |
{ |
// COULD GET CRUSHED |
lastpos = sector->ceilingheight; |
sector->ceilingheight -= speed; |
flag = P_ChangeSector(sector,crush); |
|
if (flag == true) |
{ |
if (crush == true) |
return crushed; |
sector->ceilingheight = lastpos; |
P_ChangeSector(sector,crush); |
return crushed; |
} |
} |
break; |
|
case 1: |
// UP |
if (sector->ceilingheight + speed > dest) |
{ |
lastpos = sector->ceilingheight; |
sector->ceilingheight = dest; |
flag = P_ChangeSector(sector,crush); |
if (flag == true) |
{ |
sector->ceilingheight = lastpos; |
P_ChangeSector(sector,crush); |
//return crushed; |
} |
return pastdest; |
} |
else |
{ |
lastpos = sector->ceilingheight; |
sector->ceilingheight += speed; |
flag = P_ChangeSector(sector,crush); |
// UNUSED |
#if 0 |
if (flag == true) |
{ |
sector->ceilingheight = lastpos; |
P_ChangeSector(sector,crush); |
return crushed; |
} |
#endif |
} |
break; |
} |
break; |
|
} |
return ok; |
} |
|
|
// |
// MOVE A FLOOR TO IT'S DESTINATION (UP OR DOWN) |
// |
void T_MoveFloor(floormove_t* floor) |
{ |
result_e res; |
|
res = T_MovePlane(floor->sector, |
floor->speed, |
floor->floordestheight, |
floor->crush,0,floor->direction); |
|
if (!(leveltime&7)) |
S_StartSound((mobj_t *)&floor->sector->soundorg, |
sfx_stnmov); |
|
if (res == pastdest) |
{ |
floor->sector->specialdata = NULL; |
|
if (floor->direction == 1) |
{ |
switch(floor->type) |
{ |
case donutRaise: |
floor->sector->special = floor->newspecial; |
floor->sector->floorpic = floor->texture; |
default: |
break; |
} |
} |
else if (floor->direction == -1) |
{ |
switch(floor->type) |
{ |
case lowerAndChange: |
floor->sector->special = floor->newspecial; |
floor->sector->floorpic = floor->texture; |
default: |
break; |
} |
} |
P_RemoveThinker(&floor->thinker); |
|
S_StartSound((mobj_t *)&floor->sector->soundorg, |
sfx_pstop); |
} |
|
} |
|
// |
// HANDLE FLOOR TYPES |
// |
int |
EV_DoFloor |
( line_t* line, |
floor_e floortype ) |
{ |
int secnum; |
int rtn; |
int i; |
sector_t* sec; |
floormove_t* floor; |
|
secnum = -1; |
rtn = 0; |
while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0) |
{ |
sec = §ors[secnum]; |
|
// ALREADY MOVING? IF SO, KEEP GOING... |
if (sec->specialdata) |
continue; |
|
// new floor thinker |
rtn = 1; |
floor = Z_Malloc (sizeof(*floor), PU_LEVSPEC, 0); |
P_AddThinker (&floor->thinker); |
sec->specialdata = floor; |
floor->thinker.function.acp1 = (actionf_p1) T_MoveFloor; |
floor->type = floortype; |
floor->crush = false; |
|
switch(floortype) |
{ |
case lowerFloor: |
floor->direction = -1; |
floor->sector = sec; |
floor->speed = FLOORSPEED; |
floor->floordestheight = |
P_FindHighestFloorSurrounding(sec); |
break; |
|
case lowerFloorToLowest: |
floor->direction = -1; |
floor->sector = sec; |
floor->speed = FLOORSPEED; |
floor->floordestheight = |
P_FindLowestFloorSurrounding(sec); |
break; |
|
case turboLower: |
floor->direction = -1; |
floor->sector = sec; |
floor->speed = FLOORSPEED * 4; |
floor->floordestheight = |
P_FindHighestFloorSurrounding(sec); |
if (floor->floordestheight != sec->floorheight) |
floor->floordestheight += 8*FRACUNIT; |
break; |
|
case raiseFloorCrush: |
floor->crush = true; |
case raiseFloor: |
floor->direction = 1; |
floor->sector = sec; |
floor->speed = FLOORSPEED; |
floor->floordestheight = |
P_FindLowestCeilingSurrounding(sec); |
if (floor->floordestheight > sec->ceilingheight) |
floor->floordestheight = sec->ceilingheight; |
floor->floordestheight -= (8*FRACUNIT)* |
(floortype == raiseFloorCrush); |
break; |
|
case raiseFloorTurbo: |
floor->direction = 1; |
floor->sector = sec; |
floor->speed = FLOORSPEED*4; |
floor->floordestheight = |
P_FindNextHighestFloor(sec,sec->floorheight); |
break; |
|
case raiseFloorToNearest: |
floor->direction = 1; |
floor->sector = sec; |
floor->speed = FLOORSPEED; |
floor->floordestheight = |
P_FindNextHighestFloor(sec,sec->floorheight); |
break; |
|
case raiseFloor24: |
floor->direction = 1; |
floor->sector = sec; |
floor->speed = FLOORSPEED; |
floor->floordestheight = floor->sector->floorheight + |
24 * FRACUNIT; |
break; |
case raiseFloor512: |
floor->direction = 1; |
floor->sector = sec; |
floor->speed = FLOORSPEED; |
floor->floordestheight = floor->sector->floorheight + |
512 * FRACUNIT; |
break; |
|
case raiseFloor24AndChange: |
floor->direction = 1; |
floor->sector = sec; |
floor->speed = FLOORSPEED; |
floor->floordestheight = floor->sector->floorheight + |
24 * FRACUNIT; |
sec->floorpic = line->frontsector->floorpic; |
sec->special = line->frontsector->special; |
break; |
|
case raiseToTexture: |
{ |
int minsize = MAXINT; |
side_t* side; |
|
floor->direction = 1; |
floor->sector = sec; |
floor->speed = FLOORSPEED; |
for (i = 0; i < sec->linecount; i++) |
{ |
if (twoSided (secnum, i) ) |
{ |
side = getSide(secnum,i,0); |
if (side->bottomtexture >= 0) |
if (textureheight[side->bottomtexture] < |
minsize) |
minsize = |
textureheight[side->bottomtexture]; |
side = getSide(secnum,i,1); |
if (side->bottomtexture >= 0) |
if (textureheight[side->bottomtexture] < |
minsize) |
minsize = |
textureheight[side->bottomtexture]; |
} |
} |
floor->floordestheight = |
floor->sector->floorheight + minsize; |
} |
break; |
|
case lowerAndChange: |
floor->direction = -1; |
floor->sector = sec; |
floor->speed = FLOORSPEED; |
floor->floordestheight = |
P_FindLowestFloorSurrounding(sec); |
floor->texture = sec->floorpic; |
|
for (i = 0; i < sec->linecount; i++) |
{ |
if ( twoSided(secnum, i) ) |
{ |
if (getSide(secnum,i,0)->sector-sectors == secnum) |
{ |
sec = getSector(secnum,i,1); |
|
if (sec->floorheight == floor->floordestheight) |
{ |
floor->texture = sec->floorpic; |
floor->newspecial = sec->special; |
break; |
} |
} |
else |
{ |
sec = getSector(secnum,i,0); |
|
if (sec->floorheight == floor->floordestheight) |
{ |
floor->texture = sec->floorpic; |
floor->newspecial = sec->special; |
break; |
} |
} |
} |
} |
default: |
break; |
} |
} |
return rtn; |
} |
|
|
|
|
// |
// BUILD A STAIRCASE! |
// |
int |
EV_BuildStairs |
( line_t* line, |
stair_e type ) |
{ |
int secnum; |
int height; |
int i; |
int newsecnum; |
int texture; |
int ok; |
int rtn; |
|
sector_t* sec; |
sector_t* tsec; |
|
floormove_t* floor; |
|
fixed_t stairsize; |
fixed_t speed; |
|
secnum = -1; |
rtn = 0; |
while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0) |
{ |
sec = §ors[secnum]; |
|
// ALREADY MOVING? IF SO, KEEP GOING... |
if (sec->specialdata) |
continue; |
|
// new floor thinker |
rtn = 1; |
floor = Z_Malloc (sizeof(*floor), PU_LEVSPEC, 0); |
P_AddThinker (&floor->thinker); |
sec->specialdata = floor; |
floor->thinker.function.acp1 = (actionf_p1) T_MoveFloor; |
floor->direction = 1; |
floor->sector = sec; |
switch(type) |
{ |
case build8: |
speed = FLOORSPEED/4; |
stairsize = 8*FRACUNIT; |
break; |
case turbo16: |
speed = FLOORSPEED*4; |
stairsize = 16*FRACUNIT; |
break; |
} |
floor->speed = speed; |
height = sec->floorheight + stairsize; |
floor->floordestheight = height; |
|
texture = sec->floorpic; |
|
// Find next sector to raise |
// 1. Find 2-sided line with same sector side[0] |
// 2. Other side is the next sector to raise |
do |
{ |
ok = 0; |
for (i = 0;i < sec->linecount;i++) |
{ |
if ( !((sec->lines[i])->flags & ML_TWOSIDED) ) |
continue; |
|
tsec = (sec->lines[i])->frontsector; |
newsecnum = tsec-sectors; |
|
if (secnum != newsecnum) |
continue; |
|
tsec = (sec->lines[i])->backsector; |
newsecnum = tsec - sectors; |
|
if (tsec->floorpic != texture) |
continue; |
|
height += stairsize; |
|
if (tsec->specialdata) |
continue; |
|
sec = tsec; |
secnum = newsecnum; |
floor = Z_Malloc (sizeof(*floor), PU_LEVSPEC, 0); |
|
P_AddThinker (&floor->thinker); |
|
sec->specialdata = floor; |
floor->thinker.function.acp1 = (actionf_p1) T_MoveFloor; |
floor->direction = 1; |
floor->sector = sec; |
floor->speed = speed; |
floor->floordestheight = height; |
ok = 1; |
break; |
} |
} while(ok); |
} |
return rtn; |
} |
|