components/prboom/p_genlin.c
//
// EV_DoGenCeiling()
//
// Handle generalized ceiling types
//
// Passed the linedef activating the ceiling function
// Returns true if a thinker created
//
// jff 02/04/98 Added this routine (and file) to handle generalized
// floor movers using bit fields in the line special type.
//
EV_DoGenCeiling()
Handle generalized ceiling types

Passed the linedef activating the ceiling function
Returns true if a thinker created

jff 02/04/98 Added this routine (and file) to handle generalized
floor movers using bit fields in the line special type.
EV_DoGenCeiling () Handle generalized ceiling types Passed the linedef activating the ceiling function Returns true if a thinker created jff 02 / 04 / 98 Added this routine ( and file ) to handle generalized floor movers using bit fields in the line special type .
int EV_DoGenCeiling
( line_t*       line )
{
  int                   secnum;
  int                   rtn;
  boolean               manual;
  fixed_t               targheight;
  sector_t*             sec;
  ceiling_t*            ceiling;
  unsigned              value = (unsigned)line->special - GenCeilingBase;
  int Crsh = (value & CeilingCrush) >> CeilingCrushShift;
  int ChgT = (value & CeilingChange) >> CeilingChangeShift;
  int Targ = (value & CeilingTarget) >> CeilingTargetShift;
  int Dirn = (value & CeilingDirection) >> CeilingDirectionShift;
  int ChgM = (value & CeilingModel) >> CeilingModelShift;
  int Sped = (value & CeilingSpeed) >> CeilingSpeedShift;
  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_ceiling;
  }
  secnum = -1;
  while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0)
  {
    sec = &sectors[secnum];
manual_ceiling:
    if (P_SectorActive(ceiling_special,sec)) 
    {
      if (!manual)
        continue;
      else
        return rtn;
    }
    rtn = 1;
    ceiling = Z_Malloc (sizeof(*ceiling), PU_LEVSPEC, 0);
    memset(ceiling, 0, sizeof(*ceiling));
    P_AddThinker (&ceiling->thinker);
    sec->ceilingdata = ceiling; 
    ceiling->thinker.function = T_MoveCeiling;
    ceiling->crush = Crsh;
    ceiling->direction = Dirn? 1 : -1;
    ceiling->sector = sec;
    ceiling->texture = sec->ceilingpic;
    ceiling->newspecial = sec->special;
    ceiling->oldspecial = sec->oldspecial;
    ceiling->tag = sec->tag;
    ceiling->type = genCeiling;
    switch (Sped)
    {
      case SpeedSlow:
        ceiling->speed = CEILSPEED;
        break;
      case SpeedNormal:
        ceiling->speed = CEILSPEED*2;
        break;
      case SpeedFast:
        ceiling->speed = CEILSPEED*4;
        break;
      case SpeedTurbo:
        ceiling->speed = CEILSPEED*8;
        break;
      default:
        break;
    }
    targheight = sec->ceilingheight;
    switch(Targ)
    {
      case CtoHnC:
        targheight = P_FindHighestCeilingSurrounding(sec);
        break;
      case CtoLnC:
        targheight = P_FindLowestCeilingSurrounding(sec);
        break;
      case CtoNnC:
        targheight = Dirn?
          P_FindNextHighestCeiling(sec,sec->ceilingheight) :
          P_FindNextLowestCeiling(sec,sec->ceilingheight);
        break;
      case CtoHnF:
        targheight = P_FindHighestFloorSurrounding(sec);
        break;
      case CtoF:
        targheight = sec->floorheight;
        break;
      case CbyST:
        targheight = (ceiling->sector->ceilingheight>>FRACBITS) +
          ceiling->direction * (P_FindShortestUpperAround(secnum)>>FRACBITS);
        if (targheight>32000)  
          targheight=32000;    
        if (targheight<-32000)
          targheight=-32000;
        targheight<<=FRACBITS;
        break;
      case Cby24:
        targheight = ceiling->sector->ceilingheight +
          ceiling->direction * 24*FRACUNIT;
        break;
      case Cby32:
        targheight = ceiling->sector->ceilingheight +
          ceiling->direction * 32*FRACUNIT;
        break;
      default:
        break;
    }
    if (Dirn) ceiling->topheight = targheight;
    else ceiling->bottomheight = targheight;
    if (ChgT)     
    {
      if (ChgM)   
      {
        sector_t *sec;
        sec = (Targ==CtoHnF || Targ==CtoF)?
          P_FindModelFloorSector(targheight,secnum) :
          P_FindModelCeilingSector(targheight,secnum);
        if (sec)
        {
          ceiling->texture = sec->ceilingpic;
          switch (ChgT)
          {
            case CChgZero:  
              ceiling->newspecial = 0;
              ceiling->oldspecial = 0;
              ceiling->type = genCeilingChg0;
              break;
            case CChgTyp:   
              ceiling->newspecial = sec->special;
              ceiling->oldspecial = sec->oldspecial;
              ceiling->type = genCeilingChgT;
              break;
            case CChgTxt:   
              ceiling->type = genCeilingChg;
              break;
            default:
              break;
          }
        }
      }
      else        
      {
        ceiling->texture = line->frontsector->ceilingpic;
        switch (ChgT)
        {
          case CChgZero:    
            ceiling->newspecial = 0;
            ceiling->oldspecial = 0;
            ceiling->type = genCeilingChg0;
            break;
          case CChgTyp:     
            ceiling->newspecial = line->frontsector->special;
            ceiling->oldspecial = line->frontsector->oldspecial;
            ceiling->type = genCeilingChgT;
            break;
          case CChgTxt:     
            ceiling->type = genCeilingChg;
            break;
          default:
            break;
        }
      }
    }
    P_AddActiveCeiling(ceiling);  
    if (manual) return rtn;
  }
  return rtn;
}
int EV_DoGenCeiling ( line_t * line ) { int secnum ; int rtn ; boolean manual ; fixed_t targheight ; sector_t * sec ; ceiling_t * ceiling ; unsigned value = ( unsigned ) line -> special - GenCeilingBase ; int Crsh = ( value & CeilingCrush ) >> CeilingCrushShift ; int ChgT = ( value & CeilingChange ) >> CeilingChangeShift ; int Targ = ( value & CeilingTarget ) >> CeilingTargetShift ; int Dirn = ( value & CeilingDirection ) >> CeilingDirectionShift ; int ChgM = ( value & CeilingModel ) >> CeilingModelShift ; int Sped = ( value & CeilingSpeed ) >> CeilingSpeedShift ; 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_ceiling ; } secnum = -1 ; while ( ( secnum = P_FindSectorFromLineTag ( line , secnum ) ) >= 0 ) { sec = & sectors [ secnum ] ; manual_ceiling : if ( P_SectorActive ( ceiling_special , sec ) ) { if ( ! manual ) continue ; else return rtn ; } rtn = 1 ; ceiling = Z_Malloc ( sizeof ( * ceiling ) , PU_LEVSPEC , 0 ) ; memset ( ceiling , 0 , sizeof ( * ceiling ) ) ; P_AddThinker ( & ceiling -> thinker ) ; sec -> ceilingdata = ceiling ; ceiling -> thinker . function = T_MoveCeiling ; ceiling -> crush = Crsh ; ceiling -> direction = Dirn ? 1 : -1 ; ceiling -> sector = sec ; ceiling -> texture = sec -> ceilingpic ; ceiling -> newspecial = sec -> special ; ceiling -> oldspecial = sec -> oldspecial ; ceiling -> tag = sec -> tag ; ceiling -> type = genCeiling ; switch ( Sped ) { case SpeedSlow : ceiling -> speed = CEILSPEED ; break ; case SpeedNormal : ceiling -> speed = CEILSPEED * 2 ; break ; case SpeedFast : ceiling -> speed = CEILSPEED * 4 ; break ; case SpeedTurbo : ceiling -> speed = CEILSPEED * 8 ; break ; default : break ; } targheight = sec -> ceilingheight ; switch ( Targ ) { case CtoHnC : targheight = P_FindHighestCeilingSurrounding ( sec ) ; break ; case CtoLnC : targheight = P_FindLowestCeilingSurrounding ( sec ) ; break ; case CtoNnC : targheight = Dirn ? P_FindNextHighestCeiling ( sec , sec -> ceilingheight ) : P_FindNextLowestCeiling ( sec , sec -> ceilingheight ) ; break ; case CtoHnF : targheight = P_FindHighestFloorSurrounding ( sec ) ; break ; case CtoF : targheight = sec -> floorheight ; break ; case CbyST : targheight = ( ceiling -> sector -> ceilingheight >> FRACBITS ) + ceiling -> direction * ( P_FindShortestUpperAround ( secnum ) >> FRACBITS ) ; if ( targheight > 32000 ) targheight = 32000 ; if ( targheight < -32000 ) targheight = -32000 ; targheight <<= FRACBITS ; break ; case Cby24 : targheight = ceiling -> sector -> ceilingheight + ceiling -> direction * 24 * FRACUNIT ; break ; case Cby32 : targheight = ceiling -> sector -> ceilingheight + ceiling -> direction * 32 * FRACUNIT ; break ; default : break ; } if ( Dirn ) ceiling -> topheight = targheight ; else ceiling -> bottomheight = targheight ; if ( ChgT ) { if ( ChgM ) { sector_t * sec ; sec = ( Targ == CtoHnF || Targ == CtoF ) ? P_FindModelFloorSector ( targheight , secnum ) : P_FindModelCeilingSector ( targheight , secnum ) ; if ( sec ) { ceiling -> texture = sec -> ceilingpic ; switch ( ChgT ) { case CChgZero : ceiling -> newspecial = 0 ; ceiling -> oldspecial = 0 ; ceiling -> type = genCeilingChg0 ; break ; case CChgTyp : ceiling -> newspecial = sec -> special ; ceiling -> oldspecial = sec -> oldspecial ; ceiling -> type = genCeilingChgT ; break ; case CChgTxt : ceiling -> type = genCeilingChg ; break ; default : break ; } } } else { ceiling -> texture = line -> frontsector -> ceilingpic ; switch ( ChgT ) { case CChgZero : ceiling -> newspecial = 0 ; ceiling -> oldspecial = 0 ; ceiling -> type = genCeilingChg0 ; break ; case CChgTyp : ceiling -> newspecial = line -> frontsector -> special ; ceiling -> oldspecial = line -> frontsector -> oldspecial ; ceiling -> type = genCeilingChgT ; break ; case CChgTxt : ceiling -> type = genCeilingChg ; break ; default : break ; } } } P_AddActiveCeiling ( ceiling ) ; if ( manual ) return rtn ; } return rtn ; }
EV_DoGenCeiling()
Handle generalized ceiling types
EV_DoGenCeiling () Handle generalized ceiling types
// 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 ceiling already moving //jff 2/22/98 // new ceiling thinker //jff 2/22/98 //jff 3/14/98 change old field too // set speed of motion // set destination target height //jff 3/13/98 prevent overflow // wraparound in ceiling height // set texture/type change properties // if a texture change is indicated // if a numeric model change //jff 5/23/98 find model with floor at target height if target //is a floor type // type is zeroed //jff 3/14/98 change old field too // type is copied //jff 3/14/98 change old field too // type is left alone // else if a trigger model change // type is zeroed //jff 3/14/98 change old field too // type is copied //jff 3/14/98 change old field too // type is left alone // add this ceiling to the active list