components/prboom/p_genlin.c
//
// EV_DoGenStairs()
//
// Handle generalized stair building
//
// Passed the linedef activating the stairs
// Returns true if a thinker is created
//
EV_DoGenStairs()
Handle generalized stair building

Passed the linedef activating the stairs
Returns true if a thinker is created
EV_DoGenStairs () Handle generalized stair building Passed the linedef activating the stairs Returns true if a thinker is created
int EV_DoGenStairs
( line_t*       line )
{
  int                   secnum;
  int                   osecnum; 
  int                   height;
  int                   i;
  int                   newsecnum;
  int                   texture;
  int                   ok;
  int                   rtn;
  boolean               manual;
  sector_t*             sec;
  sector_t*             tsec;
  floormove_t*  floor;
  fixed_t               stairsize;
  fixed_t               speed;
  unsigned              value = (unsigned)line->special - GenStairsBase;
  int Igno = (value & StairIgnore) >> StairIgnoreShift;
  int Dirn = (value & StairDirection) >> StairDirectionShift;
  int Step = (value & StairStep) >> StairStepShift;
  int Sped = (value & StairSpeed) >> StairSpeedShift;
  int Trig = (value & TriggerType) >> TriggerTypeShift;
  rtn = 0;
  manual = false;
  if (Trig==PushOnce || Trig==PushMany)
  {
    if (!(sec = line->backsector))
      return rtn;
    secnum = sec-sectors;
    manual = true;
    goto manual_stair;
  }
  secnum = -1;
  while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0)
  {
    sec = &sectors[secnum];
manual_stair:
    if (P_SectorActive(floor_special,sec) || sec->stairlock)
    {
      if (!manual)
        continue;
      else
        return rtn;
    }
    rtn = 1;
    floor = Z_Malloc (sizeof(*floor), PU_LEVSPEC, 0);
    memset(floor, 0, sizeof(*floor));
    P_AddThinker (&floor->thinker);
    sec->floordata = floor;
    floor->thinker.function = T_MoveFloor;
    floor->direction = Dirn? 1 : -1;
    floor->sector = sec;
    switch(Sped)
      {
      default:
      case SpeedSlow:
        floor->speed = FLOORSPEED/4;
        break;
      case SpeedNormal:
        floor->speed = FLOORSPEED/2;
        break;
      case SpeedFast:
        floor->speed = FLOORSPEED*2;
        break;
      case SpeedTurbo:
        floor->speed = FLOORSPEED*4;
        break;
      }
    switch(Step)
    {
      default:
      case 0:
        stairsize = 4*FRACUNIT;
        break;
      case 1:
        stairsize = 8*FRACUNIT;
        break;
      case 2:
        stairsize = 16*FRACUNIT;
        break;
      case 3:
        stairsize = 24*FRACUNIT;
        break;
    }
    speed = floor->speed;
    height = sec->floorheight + floor->direction * stairsize;
    floor->floordestheight = height;
    texture = sec->floorpic;
    floor->crush = false;
    floor->type = genBuildStair; 
    sec->stairlock = -2;         
    sec->nextsec = -1;
    sec->prevsec = -1;
    osecnum = secnum;            
    do
    {
      ok = 0;
      for (i = 0;i < sec->linecount;i++)
      {
        if ( !((sec->lines[i])->backsector) )
          continue;
        tsec = (sec->lines[i])->frontsector;
        newsecnum = tsec-sectors;
        if (secnum != newsecnum)
          continue;
        tsec = (sec->lines[i])->backsector;
        newsecnum = tsec - sectors;
        if (!Igno && tsec->floorpic != texture)
          continue;
        if (compatibility_level < boom_202_compatibility)
          height += floor->direction * stairsize;
        if (P_SectorActive(floor_special,tsec) || tsec->stairlock)
          continue;
        if (compatibility_level >= boom_202_compatibility)
          height += floor->direction * stairsize;
        sec->nextsec = newsecnum; 
        tsec->prevsec = secnum;   
        tsec->nextsec = -1;       
        tsec->stairlock = -2;     
        sec = tsec;
        secnum = newsecnum;
        floor = Z_Malloc (sizeof(*floor), PU_LEVSPEC, 0);
        memset(floor, 0, sizeof(*floor));
        P_AddThinker (&floor->thinker);
        sec->floordata = floor;
        floor->thinker.function = T_MoveFloor;
        floor->direction = Dirn? 1 : -1;
        floor->sector = sec;
        floor->speed = speed;
        floor->floordestheight = height;
        floor->crush = false;
        floor->type = genBuildStair; 
        ok = 1;
        break;
      }
    } while(ok);
      if (manual)
        return rtn;
      secnum = osecnum; 
  }
  if (rtn)
    line->special ^= StairDirection; 
  return rtn;
}
int EV_DoGenStairs ( line_t * line ) { int secnum ; int osecnum ; int height ; int i ; int newsecnum ; int texture ; int ok ; int rtn ; boolean manual ; sector_t * sec ; sector_t * tsec ; floormove_t * floor ; fixed_t stairsize ; fixed_t speed ; unsigned value = ( unsigned ) line -> special - GenStairsBase ; int Igno = ( value & StairIgnore ) >> StairIgnoreShift ; int Dirn = ( value & StairDirection ) >> StairDirectionShift ; int Step = ( value & StairStep ) >> StairStepShift ; int Sped = ( value & StairSpeed ) >> StairSpeedShift ; int Trig = ( value & TriggerType ) >> TriggerTypeShift ; rtn = 0 ; manual = false ; if ( Trig == PushOnce || Trig == PushMany ) { if ( ! ( sec = line -> backsector ) ) return rtn ; secnum = sec - sectors ; manual = true ; goto manual_stair ; } secnum = -1 ; while ( ( secnum = P_FindSectorFromLineTag ( line , secnum ) ) >= 0 ) { sec = & sectors [ secnum ] ; manual_stair : if ( P_SectorActive ( floor_special , sec ) || sec -> stairlock ) { if ( ! manual ) continue ; else return rtn ; } rtn = 1 ; floor = Z_Malloc ( sizeof ( * floor ) , PU_LEVSPEC , 0 ) ; memset ( floor , 0 , sizeof ( * floor ) ) ; P_AddThinker ( & floor -> thinker ) ; sec -> floordata = floor ; floor -> thinker . function = T_MoveFloor ; floor -> direction = Dirn ? 1 : -1 ; floor -> sector = sec ; switch ( Sped ) { default : case SpeedSlow : floor -> speed = FLOORSPEED / 4 ; break ; case SpeedNormal : floor -> speed = FLOORSPEED / 2 ; break ; case SpeedFast : floor -> speed = FLOORSPEED * 2 ; break ; case SpeedTurbo : floor -> speed = FLOORSPEED * 4 ; break ; } switch ( Step ) { default : case 0 : stairsize = 4 * FRACUNIT ; break ; case 1 : stairsize = 8 * FRACUNIT ; break ; case 2 : stairsize = 16 * FRACUNIT ; break ; case 3 : stairsize = 24 * FRACUNIT ; break ; } speed = floor -> speed ; height = sec -> floorheight + floor -> direction * stairsize ; floor -> floordestheight = height ; texture = sec -> floorpic ; floor -> crush = false ; floor -> type = genBuildStair ; sec -> stairlock = -2 ; sec -> nextsec = -1 ; sec -> prevsec = -1 ; osecnum = secnum ; do { ok = 0 ; for ( i = 0 ; i < sec -> linecount ; i ++ ) { if ( ! ( ( sec -> lines [ i ] ) -> backsector ) ) continue ; tsec = ( sec -> lines [ i ] ) -> frontsector ; newsecnum = tsec - sectors ; if ( secnum != newsecnum ) continue ; tsec = ( sec -> lines [ i ] ) -> backsector ; newsecnum = tsec - sectors ; if ( ! Igno && tsec -> floorpic != texture ) continue ; if ( compatibility_level < boom_202_compatibility ) height += floor -> direction * stairsize ; if ( P_SectorActive ( floor_special , tsec ) || tsec -> stairlock ) continue ; if ( compatibility_level >= boom_202_compatibility ) height += floor -> direction * stairsize ; sec -> nextsec = newsecnum ; tsec -> prevsec = secnum ; tsec -> nextsec = -1 ; tsec -> stairlock = -2 ; sec = tsec ; secnum = newsecnum ; floor = Z_Malloc ( sizeof ( * floor ) , PU_LEVSPEC , 0 ) ; memset ( floor , 0 , sizeof ( * floor ) ) ; P_AddThinker ( & floor -> thinker ) ; sec -> floordata = floor ; floor -> thinker . function = T_MoveFloor ; floor -> direction = Dirn ? 1 : -1 ; floor -> sector = sec ; floor -> speed = speed ; floor -> floordestheight = height ; floor -> crush = false ; floor -> type = genBuildStair ; ok = 1 ; break ; } } while ( ok ) ; if ( manual ) return rtn ; secnum = osecnum ; } if ( rtn ) line -> special ^= StairDirection ; return rtn ; }
EV_DoGenStairs()
Handle generalized stair building
EV_DoGenStairs () Handle generalized stair building
//jff 3/4/98 preserve loop index // parse the bit fields in the line's special type // check if a manual trigger, if so do just the sector on the backside // if not manual do all sectors tagged the same as the line //Do not start another function if floor already moving //jff 2/26/98 add special lockout condition to wait for entire //staircase to build before retriggering // new floor thinker // setup speed of stair building // setup stepsize for stairs // jff 3/31/98 do not leave uninited // jff 2/26/98 set up lock on current sector //jff 3/4/98 preserve loop index // Find next sector to raise // 1.     Find 2-sided line with same sector side[0] // 2.     Other side is the next sector to raise /* jff 6/19/98 prevent double stepsize */ //jff 2/26/98 special lockout condition for retriggering /* jff 6/19/98 increase height AFTER continue */ // jff 2/26/98 // link the stair chain in both directions // lock the stair sector until building complete // link step to next // link next back // set next forward link as end // lock the step // jff 3/31/98 do not leave uninited //jff 3/4/98 restore old loop index // retriggerable generalized stairs build up or down alternately // alternate dir on succ activations