Source to src/p_ceilng.c
//**************************************************************************
//**
//** p_ceilng.c : Heretic 2 : Raven Software, Corp.
//**
//** $RCSfile: p_ceilng.c,v $
//** $Revision: 1.17 $
//** $Date: 95/09/11 22:06:25 $
//** $Author: cjr $
//**
//**************************************************************************
#include "h2def.h"
#include "p_local.h"
#include "soundst.h"
//==================================================================
//==================================================================
//
// CEILINGS
//
//==================================================================
//==================================================================
ceiling_t *activeceilings[MAXCEILINGS];
//==================================================================
//
// T_MoveCeiling
//
//==================================================================
void T_MoveCeiling (ceiling_t *ceiling)
{
result_e res;
switch(ceiling->direction)
{
// case 0: // IN STASIS
// break;
case 1: // UP
res = T_MovePlane(ceiling->sector,ceiling->speed,
ceiling->topheight, false, 1, ceiling->direction);
if (res == RES_PASTDEST)
{
SN_StopSequence((mobj_t *)&ceiling->sector->soundorg);
switch(ceiling->type)
{
case CLEV_CRUSHANDRAISE:
ceiling->direction = -1;
ceiling->speed = ceiling->speed*2;
break;
default:
P_RemoveActiveCeiling(ceiling);
break;
}
}
break;
case -1: // DOWN
res = T_MovePlane(ceiling->sector,ceiling->speed,
ceiling->bottomheight, ceiling->crush, 1, ceiling->direction);
if(res == RES_PASTDEST)
{
SN_StopSequence((mobj_t *)&ceiling->sector->soundorg);
switch(ceiling->type)
{
case CLEV_CRUSHANDRAISE:
case CLEV_CRUSHRAISEANDSTAY:
ceiling->direction = 1;
ceiling->speed = ceiling->speed/2;
break;
default:
P_RemoveActiveCeiling(ceiling);
break;
}
}
else if(res == RES_CRUSHED)
{
switch(ceiling->type)
{
case CLEV_CRUSHANDRAISE:
case CLEV_LOWERANDCRUSH:
case CLEV_CRUSHRAISEANDSTAY:
//ceiling->speed = ceiling->speed/4;
break;
default:
break;
}
}
break;
}
}
//==================================================================
//
// EV_DoCeiling
// Move a ceiling up/down and all around!
//
//==================================================================
int EV_DoCeiling (line_t *line, byte *arg, ceiling_e type)
{
int secnum,rtn;
sector_t *sec;
ceiling_t *ceiling;
secnum = -1;
rtn = 0;
/* Old Ceiling stasis code
//
// Reactivate in-stasis ceilings...for certain types.
//
switch(type)
{
case CLEV_CRUSHANDRAISE:
P_ActivateInStasisCeiling(line);
default:
break;
}
*/
while ((secnum = P_FindSectorFromTag(arg[0], secnum)) >= 0)
{
sec = §ors[secnum];
if (sec->specialdata)
continue;
//
// new door thinker
//
rtn = 1;
ceiling = Z_Malloc (sizeof(*ceiling), PU_LEVSPEC, 0);
P_AddThinker (&ceiling->thinker);
sec->specialdata = ceiling;
ceiling->thinker.function = T_MoveCeiling;
ceiling->sector = sec;
ceiling->crush = 0;
ceiling->speed = arg[1]*(FRACUNIT/8);
switch(type)
{
case CLEV_CRUSHRAISEANDSTAY:
ceiling->crush = arg[2]; // arg[2] = crushing value
ceiling->topheight = sec->ceilingheight;
ceiling->bottomheight = sec->floorheight + (8*FRACUNIT);
ceiling->direction = -1;
break;
case CLEV_CRUSHANDRAISE:
ceiling->topheight = sec->ceilingheight;
case CLEV_LOWERANDCRUSH:
ceiling->crush = arg[2]; // arg[2] = crushing value
case CLEV_LOWERTOFLOOR:
ceiling->bottomheight = sec->floorheight;
if(type != CLEV_LOWERTOFLOOR)
{
ceiling->bottomheight += 8*FRACUNIT;
}
ceiling->direction = -1;
break;
case CLEV_RAISETOHIGHEST:
ceiling->topheight = P_FindHighestCeilingSurrounding(sec);
ceiling->direction = 1;
break;
case CLEV_LOWERBYVALUE:
ceiling->bottomheight = sec->ceilingheight-arg[2]*FRACUNIT;
ceiling->direction = -1;
break;
case CLEV_RAISEBYVALUE:
ceiling->topheight = sec->ceilingheight+arg[2]*FRACUNIT;
ceiling->direction = 1;
break;
case CLEV_MOVETOVALUETIMES8:
{
int destHeight = arg[2]*FRACUNIT*8;
if(arg[3])
{
destHeight = -destHeight;
}
if(sec->ceilingheight <= destHeight)
{
ceiling->direction = 1;
ceiling->topheight = destHeight;
if(sec->ceilingheight == destHeight)
{
rtn = 0;
}
}
else if(sec->ceilingheight > destHeight)
{
ceiling->direction = -1;
ceiling->bottomheight = destHeight;
}
break;
}
default:
rtn = 0;
break;
}
ceiling->tag = sec->tag;
ceiling->type = type;
P_AddActiveCeiling(ceiling);
if(rtn)
{
SN_StartSequence((mobj_t *)&ceiling->sector->soundorg,
SEQ_PLATFORM+ceiling->sector->seqType);
}
}
return rtn;
}
//==================================================================
//
// Add an active ceiling
//
//==================================================================
void P_AddActiveCeiling(ceiling_t *c)
{
int i;
for (i = 0; i < MAXCEILINGS;i++)
if (activeceilings[i] == NULL)
{
activeceilings[i] = c;
return;
}
}
//==================================================================
//
// Remove a ceiling's thinker
//
//==================================================================
void P_RemoveActiveCeiling(ceiling_t *c)
{
int i;
for (i = 0;i < MAXCEILINGS;i++)
if (activeceilings[i] == c)
{
activeceilings[i]->sector->specialdata = NULL;
P_RemoveThinker (&activeceilings[i]->thinker);
P_TagFinished(activeceilings[i]->sector->tag);
activeceilings[i] = NULL;
break;
}
}
#if 0
//==================================================================
//
// Restart a ceiling that's in-stasis
//
//==================================================================
void P_ActivateInStasisCeiling(line_t *line)
{
int i;
for (i = 0;i < MAXCEILINGS;i++)
if (activeceilings[i] && (activeceilings[i]->tag == line->arg1) &&
(activeceilings[i]->direction == 0))
{
activeceilings[i]->direction = activeceilings[i]->olddirection;
activeceilings[i]->thinker.function = T_MoveCeiling;
SN_StartSequence((mobj_t *)&activeceilings[i]->sector->soundorg,
SEQ_PLATFORM+activeceilings[i]->sector->seqType);
}
}
#endif
//==================================================================
//
// EV_CeilingCrushStop
// Stop a ceiling from crushing!
//
//==================================================================
int EV_CeilingCrushStop(line_t *line, byte *args)
{
int i;
int rtn;
rtn = 0;
for (i = 0;i < MAXCEILINGS;i++)
{
if(activeceilings[i] && activeceilings[i]->tag == args[0])
{
rtn = 1;
SN_StopSequence((mobj_t*)&activeceilings[i]->sector->soundorg);
activeceilings[i]->sector->specialdata = NULL;
P_RemoveThinker (&activeceilings[i]->thinker);
P_TagFinished(activeceilings[i]->sector->tag);
activeceilings[i] = NULL;
break;
}
}
return rtn;
}