⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 p_genlin.c

📁 The source code of Doom legacy for windows
💻 C
📖 第 1 页 / 共 2 页
字号:
// Emacs style mode select   -*- C++ -*- //-----------------------------------------------------------------------------//// Copyright (C) 1993-1996 by id Software, Inc.// Portions Copyright (C) 1998-2000 by DooM Legacy Team.//// This program is free software; you can redistribute it and/or// modify it under the terms of the GNU General Public License// as published by the Free Software Foundation; either version 2// of the License, or (at your option) any later version.//// This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the// GNU General Public License for more details.//////// DESCRIPTION://  Generalized linedef type handlers//  Floors, Ceilings, Doors, Locked Doors, Lifts, Stairs, Crushers////-----------------------------------------------------------------------------#include "doomdef.h"#include "g_game.h"#include "p_local.h"#include "r_data.h"#include "m_random.h"#include "s_sound.h"#include "z_zone.h"/*  SoM: 3/9/2000: Copied this entire file from Boom sources to Legacy sources.  This file contains all routiens for Generalized linedef types.*///// EV_DoGenFloor()//// Handle generalized floor types//// Passed the line activating the generalized floor function// Returns true if a thinker is created//int EV_DoGenFloor( line_t*       line ){  int                   secnum;  int                   rtn;  boolean               manual;  sector_t*             sec;  floormove_t*          floor;  unsigned              value = (unsigned)line->special - GenFloorBase;  // parse the bit fields in the line's special type  int Crsh = (value & FloorCrush) >> FloorCrushShift;  int ChgT = (value & FloorChange) >> FloorChangeShift;  int Targ = (value & FloorTarget) >> FloorTargetShift;  int Dirn = (value & FloorDirection) >> FloorDirectionShift;  int ChgM = (value & FloorModel) >> FloorModelShift;  int Sped = (value & FloorSpeed) >> FloorSpeedShift;  int Trig = (value & TriggerType) >> TriggerTypeShift;  rtn = 0;  // check if a manual trigger, if so do just the sector on the backside  manual = false;  if (Trig==PushOnce || Trig==PushMany)  {    if (!(sec = line->backsector))      return rtn;    secnum = sec-sectors;    manual = true;    goto manual_floor;  }  secnum = -1;  // if not manual do all sectors tagged the same as the line  while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0)  {    sec = &sectors[secnum];manual_floor:                    // Do not start another function if floor already moving    if (P_SectorActive(floor_special,sec))    {      if (!manual)        continue;      else        return rtn;    }    // new floor thinker    rtn = 1;    floor = Z_Malloc (sizeof(floormove_t), PU_LEVSPEC, 0);    P_AddThinker (&floor->thinker);    sec->floordata = floor;    floor->thinker.function.acp1 = (actionf_p1) T_MoveFloor;    floor->crush = Crsh;    floor->direction = Dirn? 1 : -1;    floor->sector = sec;    floor->texture = sec->floorpic;    floor->newspecial = sec->special;    floor->oldspecial = sec->oldspecial;    floor->type = genFloor;    // set the speed of motion    switch (Sped)    {      case SpeedSlow:        floor->speed = FLOORSPEED;        break;      case SpeedNormal:        floor->speed = FLOORSPEED*2;        break;      case SpeedFast:        floor->speed = FLOORSPEED*4;        break;      case SpeedTurbo:        floor->speed = FLOORSPEED*8;        break;      default:        break;    }    // set the destination height    switch(Targ)    {      case FtoHnF:        floor->floordestheight = P_FindHighestFloorSurrounding(sec);        break;      case FtoLnF:        floor->floordestheight = P_FindLowestFloorSurrounding(sec);        break;      case FtoNnF:        floor->floordestheight = Dirn?          P_FindNextHighestFloor(sec,sec->floorheight) :          P_FindNextLowestFloor(sec,sec->floorheight);        break;      case FtoLnC:        floor->floordestheight = P_FindLowestCeilingSurrounding(sec);        break;      case FtoC:        floor->floordestheight = sec->ceilingheight;        break;      case FbyST:        floor->floordestheight = (floor->sector->floorheight>>FRACBITS) +          floor->direction * (P_FindShortestTextureAround(secnum)>>FRACBITS);        if (floor->floordestheight>32000)          floor->floordestheight=32000;        if (floor->floordestheight<-32000)          floor->floordestheight=-32000;        floor->floordestheight<<=FRACBITS;        break;      case Fby24:        floor->floordestheight = floor->sector->floorheight +          floor->direction * 24*FRACUNIT;        break;      case Fby32:        floor->floordestheight = floor->sector->floorheight +          floor->direction * 32*FRACUNIT;        break;      default:        break;    }    // set texture/type change properties    if (ChgT)   // if a texture change is indicated    {      if (ChgM) // if a numeric model change      {        sector_t *sec;        sec = (Targ==FtoLnC || Targ==FtoC)?          P_FindModelCeilingSector(floor->floordestheight,secnum) :          P_FindModelFloorSector(floor->floordestheight,secnum);        if (sec)        {          floor->texture = sec->floorpic;          switch(ChgT)          {            case FChgZero:  // zero type              floor->newspecial = 0;              floor->oldspecial = 0;              floor->type = genFloorChg0;              break;            case FChgTyp:   // copy type              floor->newspecial = sec->special;              floor->oldspecial = sec->oldspecial;              floor->type = genFloorChgT;              break;            case FChgTxt:   // leave type be              floor->type = genFloorChg;              break;            default:              break;          }        }      }      else     // else if a trigger model change      {        floor->texture = line->frontsector->floorpic;        switch (ChgT)        {          case FChgZero:    // zero type            floor->newspecial = 0;            floor->oldspecial = 0;            floor->type = genFloorChg0;            break;          case FChgTyp:     // copy type            floor->newspecial = line->frontsector->special;            floor->oldspecial = line->frontsector->oldspecial;            floor->type = genFloorChgT;            break;          case FChgTxt:     // leave type be            floor->type = genFloorChg;          default:            break;        }      }    }    if (manual) return rtn;  }  return rtn;}//// EV_DoGenCeiling()//// Handle generalized ceiling types//// Passed the linedef activating the ceiling function// Returns true if a thinker created//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;  // parse the bit fields in the line's special type  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;  // check if a manual trigger, if so do just the sector on the backside  manual = false;  if (Trig==PushOnce || Trig==PushMany)  {    if (!(sec = line->backsector))      return rtn;    secnum = sec-sectors;    manual = true;    goto manual_ceiling;  }  secnum = -1;  // if not manual do all sectors tagged the same as the line  while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0)  {    sec = &sectors[secnum];manual_ceiling:                    // Do not start another function if ceiling already moving    if (P_SectorActive(ceiling_special,sec))    {      if (!manual)        continue;      else        return rtn;    }    // new ceiling thinker    rtn = 1;    ceiling = Z_Malloc (sizeof(ceiling_t), PU_LEVSPEC, 0);    P_AddThinker (&ceiling->thinker);    sec->ceilingdata = ceiling;    ceiling->thinker.function.acp1 = (actionf_p1) 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;    // set speed of motion    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;    }    // set destination target height    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;    }    //that doesn't compile under windows    //Dirn? ceiling->topheight : ceiling->bottomheight = targheight;    if(Dirn)      ceiling->topheight = targheight;    else      ceiling->bottomheight = targheight;    // set texture/type change properties    if (ChgT)     // if a texture change is indicated    {      if (ChgM)   // if a numeric model change      {        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:  // type is zeroed              ceiling->newspecial = 0;              ceiling->oldspecial = 0;              ceiling->type = genCeilingChg0;              break;            case CChgTyp:   // type is copied              ceiling->newspecial = sec->special;              ceiling->oldspecial = sec->oldspecial;              ceiling->type = genCeilingChgT;              break;            case CChgTxt:   // type is left alone              ceiling->type = genCeilingChg;              break;            default:              break;          }        }      }      else        // else if a trigger model change      {        ceiling->texture = line->frontsector->ceilingpic;        switch (ChgT)        {          case CChgZero:    // type is zeroed            ceiling->newspecial = 0;            ceiling->oldspecial = 0;            ceiling->type = genCeilingChg0;            break;          case CChgTyp:     // type is copied            ceiling->newspecial = line->frontsector->special;            ceiling->oldspecial = line->frontsector->oldspecial;            ceiling->type = genCeilingChgT;            break;          case CChgTxt:     // type is left alone            ceiling->type = genCeilingChg;            break;          default:            break;        }      }    }    P_AddActiveCeiling(ceiling);  // add this ceiling to the active list    if (manual) return rtn;  }  return rtn;}//// EV_DoGenLift()//// Handle generalized lift types//// Passed the linedef activating the lift// Returns true if a thinker is created//int EV_DoGenLift( line_t*       line ){  plat_t*         plat;  int             secnum;  int             rtn;  boolean         manual;  sector_t*       sec;  unsigned        value = (unsigned)line->special - GenLiftBase;  // parse the bit fields in the line's special type  int Targ = (value & LiftTarget) >> LiftTargetShift;  int Dely = (value & LiftDelay) >> LiftDelayShift;  int Sped = (value & LiftSpeed) >> LiftSpeedShift;  int Trig = (value & TriggerType) >> TriggerTypeShift;  secnum = -1;  rtn = 0;  // Activate all <type> plats that are in_stasis  if (Targ==LnF2HnF)    P_ActivateInStasis(line->tag);          // check if a manual trigger, if so do just the sector on the backside  manual = false;  if (Trig==PushOnce || Trig==PushMany)  {    if (!(sec = line->backsector))      return rtn;    secnum = sec-sectors;    manual = true;    goto manual_lift;  }  // if not manual do all sectors tagged the same as the line  while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0)  {    sec = &sectors[secnum];manual_lift:    // Do not start another function if floor already moving    if (P_SectorActive(floor_special,sec))    {      if (!manual)        continue;      else        return rtn;    }          // Setup the plat thinker    rtn = 1;    plat = Z_Malloc( sizeof(*plat), PU_LEVSPEC, 0);    P_AddThinker(&plat->thinker);                  plat->sector = sec;    plat->sector->floordata = plat;    plat->thinker.function.acp1 = (actionf_p1) T_PlatRaise;    plat->crush = false;    plat->tag = line->tag;    plat->type = genLift;    plat->high = sec->floorheight;    plat->status = down;    // setup the target destination height    switch(Targ)    {      case F2LnF:        plat->low = P_FindLowestFloorSurrounding(sec);        if (plat->low > sec->floorheight)          plat->low = sec->floorheight;        break;      case F2NnF:        plat->low = P_FindNextLowestFloor(sec,sec->floorheight);        break;      case F2LnC:        plat->low = P_FindLowestCeilingSurrounding(sec);        if (plat->low > sec->floorheight)          plat->low = sec->floorheight;        break;      case LnF2HnF:        plat->type = genPerpetual;        plat->low = P_FindLowestFloorSurrounding(sec);        if (plat->low > sec->floorheight)          plat->low = sec->floorheight;        plat->high = P_FindHighestFloorSurrounding(sec);        if (plat->high < sec->floorheight)          plat->high = sec->floorheight;        plat->status = P_Random()&1;        break;      default:        break;    }    // setup the speed of motion    switch(Sped)    {      case SpeedSlow:        plat->speed = PLATSPEED * 2;        break;      case SpeedNormal:        plat->speed = PLATSPEED * 4;        break;      case SpeedFast:        plat->speed = PLATSPEED * 8;        break;      case SpeedTurbo:        plat->speed = PLATSPEED * 16;        break;      default:        break;    }    // setup the delay time before the floor returns    switch(Dely)    {      case 0:        plat->wait = 1*35;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -