Split up EV_DoElevator

This commit is contained in:
Sally Coolatta 2022-12-27 08:27:09 -05:00
parent e8dff8f12a
commit f8874f3460
3 changed files with 198 additions and 77 deletions

View file

@ -1889,92 +1889,210 @@ void EV_DoCrushFloorOnce(mtag_t tag, fixed_t speed)
// jff 2/22/98 new type to move floor and ceiling in parallel
//
void EV_DoElevator(mtag_t tag, line_t *line, elevator_e elevtype)
{
// This function is deprecated.
// Use any of the following functions directly, instead.
switch (elevtype)
{
case elevateDown:
EV_DoElevateDown(tag);
break;
case elevateUp:
EV_DoElevateUp(tag);
break;
case elevateHighest:
EV_DoElevateHighest(tag);
break;
case elevateContinuous:
EV_DoContinuousElevator(
tag,
line->args[1] << (FRACBITS - 2),
line->args[2],
line->args[3],
(line->args[4] == 0)
);
break;
case bridgeFall:
EV_DoBridgeFall(tag);
break;
default:
break;
}
}
static elevator_t *CreateElevatorThinker(sector_t *sec)
{
elevator_t *elevator = NULL;
if (sec->floordata || sec->ceilingdata)
{
return NULL;
}
elevator = Z_Calloc(sizeof (*elevator), PU_LEVSPEC, NULL);
P_AddThinker(THINK_MAIN, &elevator->thinker);
// make sure other thinkers won't get started over this one
sec->floordata = elevator;
sec->ceilingdata = elevator;
// set up some generic aspects of the floormove_t
elevator->thinker.function.acp1 = (actionf_p1)T_MoveElevator;
elevator->distance = 1; // Always crush unless otherwise
elevator->sector = sec;
// interpolation
R_CreateInterpolator_SectorPlane(&elevator->thinker, sec, false);
R_CreateInterpolator_SectorPlane(&elevator->thinker, sec, true);
return elevator;
}
void EV_DoElevateDown(mtag_t tag)
{
INT32 secnum = -1;
sector_t *sec;
elevator_t *elevator;
// act on all sectors with the given tag
TAG_ITER_SECTORS(tag, secnum)
{
elevator_t *elevator = NULL;
sec = &sectors[secnum];
// If either floor or ceiling is already activated, skip it
if (sec->floordata || sec->ceilingdata)
continue;
// create and initialize new elevator thinker
elevator = Z_Calloc(sizeof (*elevator), PU_LEVSPEC, NULL);
P_AddThinker(THINK_MAIN, &elevator->thinker);
sec->floordata = elevator;
sec->ceilingdata = elevator;
elevator->thinker.function.acp1 = (actionf_p1)T_MoveElevator;
elevator->type = elevtype;
elevator->sourceline = line;
elevator->distance = 1; // Always crush unless otherwise
elevator->sector = sec;
// set up the fields according to the type of elevator action
switch (elevtype)
elevator = CreateElevatorThinker(sec);
if (elevator == NULL)
{
// elevator down to next floor
case elevateDown:
elevator->direction = -1;
elevator->speed = ELEVATORSPEED/2; // half speed
elevator->floordestheight = P_FindNextLowestFloor(sec, sec->floorheight);
break;
// elevator up to next floor
case elevateUp:
elevator->direction = 1;
elevator->speed = ELEVATORSPEED/4; // quarter speed
elevator->floordestheight = P_FindNextHighestFloor(sec, sec->floorheight);
break;
// elevator up to highest floor
case elevateHighest:
elevator->direction = 1;
elevator->speed = ELEVATORSPEED/4; // quarter speed
elevator->floordestheight = P_FindHighestFloorSurrounding(sec);
break;
case elevateContinuous:
elevator->origspeed = line->args[1] << (FRACBITS - 2);
elevator->speed = elevator->origspeed;
elevator->low = !line->args[4]; // go down first unless args[4] is set
if (elevator->low)
{
elevator->direction = 1;
elevator->floordestheight = P_FindNextHighestFloor(sec, sec->floorheight);
}
else
{
elevator->direction = -1;
elevator->floordestheight = P_FindNextLowestFloor(sec,sec->floorheight);
}
elevator->floorwasheight = elevator->sector->floorheight;
elevator->ceilingwasheight = elevator->sector->ceilingheight;
elevator->delay = line->args[3];
elevator->delaytimer = line->args[2]; // Initial delay
break;
case bridgeFall:
elevator->direction = -1;
elevator->speed = ELEVATORSPEED*4; // quadruple speed
elevator->floordestheight = P_FindNextLowestFloor(sec, sec->floorheight);
break;
default:
break;
continue;
}
elevator->ceilingdestheight = elevator->floordestheight + sec->ceilingheight - sec->floorheight;
elevator->type = elevateDown;
// interpolation
R_CreateInterpolator_SectorPlane(&elevator->thinker, sec, false);
R_CreateInterpolator_SectorPlane(&elevator->thinker, sec, true);
elevator->direction = -1;
elevator->speed = ELEVATORSPEED/2; // half speed
elevator->floordestheight = P_FindNextLowestFloor(sec, sec->floorheight);
elevator->ceilingdestheight = elevator->floordestheight + (sec->ceilingheight - sec->floorheight);
}
}
void EV_DoElevateUp(mtag_t tag)
{
INT32 secnum = -1;
sector_t *sec;
TAG_ITER_SECTORS(tag, secnum)
{
elevator_t *elevator = NULL;
sec = &sectors[secnum];
elevator = CreateElevatorThinker(sec);
if (elevator == NULL)
{
continue;
}
elevator->type = elevateDown;
elevator->direction = 1;
elevator->speed = ELEVATORSPEED/4; // quarter speed
elevator->floordestheight = P_FindNextHighestFloor(sec, sec->floorheight);
elevator->ceilingdestheight = elevator->floordestheight + (sec->ceilingheight - sec->floorheight);
}
}
void EV_DoElevateHighest(mtag_t tag)
{
INT32 secnum = -1;
sector_t *sec;
TAG_ITER_SECTORS(tag, secnum)
{
elevator_t *elevator = NULL;
sec = &sectors[secnum];
elevator = CreateElevatorThinker(sec);
if (elevator == NULL)
{
continue;
}
elevator->type = elevateHighest;
elevator->direction = 1;
elevator->speed = ELEVATORSPEED/4; // quarter speed
elevator->floordestheight = P_FindHighestFloorSurrounding(sec);
elevator->ceilingdestheight = elevator->floordestheight + (sec->ceilingheight - sec->floorheight);
}
}
void EV_DoContinuousElevator(mtag_t tag, fixed_t speed, INT32 delayInit, INT32 delay, boolean lowFirst)
{
INT32 secnum = -1;
sector_t *sec;
TAG_ITER_SECTORS(tag, secnum)
{
elevator_t *elevator = NULL;
sec = &sectors[secnum];
elevator = CreateElevatorThinker(sec);
if (elevator == NULL)
{
continue;
}
elevator->type = elevateContinuous;
elevator->origspeed = speed;
elevator->speed = elevator->origspeed;
elevator->low = lowFirst; // go down first unless args[4] is set
if (elevator->low)
{
elevator->direction = 1;
elevator->floordestheight = P_FindNextHighestFloor(sec, sec->floorheight);
}
else
{
elevator->direction = -1;
elevator->floordestheight = P_FindNextLowestFloor(sec,sec->floorheight);
}
elevator->floorwasheight = elevator->sector->floorheight;
elevator->ceilingwasheight = elevator->sector->ceilingheight;
elevator->delay = delay;
elevator->delaytimer = delayInit; // Initial delay
elevator->ceilingdestheight = elevator->floordestheight + (sec->ceilingheight - sec->floorheight);
}
}
void EV_DoBridgeFall(mtag_t tag)
{
INT32 secnum = -1;
sector_t *sec;
TAG_ITER_SECTORS(tag, secnum)
{
elevator_t *elevator = NULL;
sec = &sectors[secnum];
elevator = CreateElevatorThinker(sec);
if (elevator == NULL)
{
continue;
}
elevator->type = bridgeFall;
elevator->direction = -1;
elevator->speed = ELEVATORSPEED*4; // quadruple speed
elevator->floordestheight = P_FindNextLowestFloor(sec, sec->floorheight);
elevator->ceilingdestheight = elevator->floordestheight + (sec->ceilingheight - sec->floorheight);
}
}

View file

@ -2523,7 +2523,6 @@ static void SaveElevatorThinker(savebuffer_t *save, const thinker_t *th, const U
WRITEFIXED(save->p, ht->delaytimer);
WRITEFIXED(save->p, ht->floorwasheight);
WRITEFIXED(save->p, ht->ceilingwasheight);
WRITEUINT32(save->p, SaveLine(ht->sourceline));
}
static void SaveCrumbleThinker(savebuffer_t *save, const thinker_t *th, const UINT8 type)
@ -3753,7 +3752,6 @@ static thinker_t* LoadElevatorThinker(savebuffer_t *save, actionf_p1 thinker, bo
ht->delaytimer = READFIXED(save->p);
ht->floorwasheight = READFIXED(save->p);
ht->ceilingwasheight = READFIXED(save->p);
ht->sourceline = LoadLine(READUINT32(save->p));
if (ht->sector && setplanedata)
{

View file

@ -839,7 +839,6 @@ struct elevator_t
fixed_t delaytimer;
fixed_t floorwasheight; // Height the floor WAS at
fixed_t ceilingwasheight; // Height the ceiling WAS at
line_t *sourceline;
};
typedef enum
@ -987,6 +986,12 @@ void EV_DoBounceFloor(mtag_t tag, boolean crush, fixed_t crushHeight, fixed_t cr
void EV_DoCrushFloorOnce(mtag_t tag, fixed_t speed);
void EV_DoElevator(mtag_t tag, line_t *line, elevator_e elevtype);
void EV_DoElevateDown(mtag_t tag);
void EV_DoElevateUp(mtag_t tag);
void EV_DoElevateHighest(mtag_t tag);
void EV_DoContinuousElevator(mtag_t tag, fixed_t speed, INT32 delayInit, INT32 delay, boolean lowFirst);
void EV_DoBridgeFall(mtag_t tag);
void EV_CrumbleChain(sector_t *sec, ffloor_t *rover);
void EV_BounceSector(sector_t *sector, fixed_t momz, line_t *sourceline);