Beispiel #1
0
        //==================================================================
        //
        //	TURN LINE'S TAG LIGHTS OFF
        //
        //==================================================================
        public static void EV_TurnTagLightsOff(r_local.line_t line)
        {
            int i;
            int j;
            int min;

            r_local.sector_t sector;
            r_local.sector_t tsec;
            r_local.line_t   templine;

            for (j = 0; j < p_setup.numsectors; j++)
            {
                sector = p_setup.sectors[j];
                if (sector.tag == line.tag)
                {
                    min = sector.lightlevel;
                    for (i = 0; i < sector.linecount; i++)
                    {
                        templine = p_setup.linebuffer[sector.linesi + i];
                        tsec     = p_spec.getNextSector(templine, sector);
                        if (tsec == null)
                        {
                            continue;
                        }
                        if (tsec.lightlevel < min)
                        {
                            min = tsec.lightlevel;
                        }
                    }
                    sector.lightlevel = (short)min;
                }
            }
        }
Beispiel #2
0
        /*
         * ==============
         * =
         * = P_MakeDivline
         * =
         * ==============
         */

        public static void P_MakeDivline(r_local.line_t li, p_local.divline_t dl)
        {
            dl.x  = li.v1.x;
            dl.y  = li.v1.y;
            dl.dx = li.dx;
            dl.dy = li.dy;
        }
Beispiel #3
0
        public static void P_LineOpening(r_local.line_t linedef)
        {
            r_local.sector_t front, back;

            if (linedef.sidenum[1] == -1)
            {                   // single sided line
                openrange = 0;
                return;
            }

            front = linedef.frontsector;
            back  = linedef.backsector;

            if (front.ceilingheight < back.ceilingheight)
            {
                opentop = front.ceilingheight;
            }
            else
            {
                opentop = back.ceilingheight;
            }
            if (front.floorheight > back.floorheight)
            {
                openbottom = front.floorheight;
                lowfloor   = back.floorheight;
            }
            else
            {
                openbottom = back.floorheight;
                lowfloor   = front.floorheight;
            }

            openrange = opentop - openbottom;
        }
Beispiel #4
0
        /*
         * ==================
         * =
         * = P_PointOnLineSide
         * =
         * = Returns 0 or 1
         * ==================
         */

        public static int P_PointOnLineSide(int x, int y, r_local.line_t line)
        {
            int dx, dy;
            int left, right;

            if (line.dx == 0)
            {
                if (x <= line.v1.x)
                {
                    return(line.dy > 0 ? 1 : 0);
                }
                return(line.dy < 0 ? 1 : 0);
            }
            if (line.dy == 0)
            {
                if (y <= line.v1.y)
                {
                    return(line.dx < 0 ? 1 : 0);
                }
                return(line.dx > 0 ? 1 : 0);
            }

            dx = (x - line.v1.x);
            dy = (y - line.v1.y);

            left  = DoomDef.FixedMul(line.dy >> DoomDef.FRACBITS, dx);
            right = DoomDef.FixedMul(dy, line.dx >> DoomDef.FRACBITS);

            if (right < left)
            {
                return(0);                              // front side
            }
            return(1);                                  // back side
        }
Beispiel #5
0
 public static void GatherSectorsInRadiusIter(Vector2 pos, r_local.sector_t sector, float radius, ref List <r_local.sector_t> out_sectors)
 {
     for (int i = 0; i < sector.linecount; ++i)
     {
         r_local.line_t li = p_setup.linebuffer[sector.linesi + i];
         GatherSectorsInRadiusIterThroughLine(pos, sector, li, radius, ref out_sectors);
     }
 }
Beispiel #6
0
        //==================================================================
        //
        //	Function that changes wall texture.
        //	Tell it if switch is ok to use again (1=yes, it's a button).
        //
        //==================================================================
        public static void P_ChangeSwitchTexture(r_local.line_t line, int useAgain)
        {
            int texTop;
            int texMid;
            int texBot;
            int i;
            int sound;

            if (useAgain == 0)
            {
                line.special = 0;
            }

            texTop = p_setup.sides[line.sidenum[0]].toptexture;
            texMid = p_setup.sides[line.sidenum[0]].midtexture;
            texBot = p_setup.sides[line.sidenum[0]].bottomtexture;

            sound = (int)sounds.sfxenum_t.sfx_switch;

            for (i = 0; i < numswitches * 2; i++)
            {
                if (switchlist[i] == texTop)
                {
                    i_ibm.S_StartSound(buttonlist[0].soundorg, sound);
                    p_setup.sides[line.sidenum[0]].toptexture = (short)p_switch.switchlist[i ^ 1];
                    p_setup.sides[line.sidenum[0]].sector.invalidate(false);
                    if (useAgain != 0)
                    {
                        p_switch.P_StartButton(line, p_spec.bwhere_e.top, switchlist[i], p_spec.BUTTONTIME);
                    }
                    return;
                }
                else
                if (switchlist[i] == texMid)
                {
                    i_ibm.S_StartSound(buttonlist[0].soundorg, sound);
                    p_setup.sides[line.sidenum[0]].midtexture = (short)p_switch.switchlist[i ^ 1];
                    p_setup.sides[line.sidenum[0]].sector.invalidate(false);
                    if (useAgain != 0)
                    {
                        p_switch.P_StartButton(line, p_spec.bwhere_e.middle, switchlist[i], p_spec.BUTTONTIME);
                    }
                    return;
                }
                else
                if (switchlist[i] == texBot)
                {
                    i_ibm.S_StartSound(buttonlist[0].soundorg, sound);
                    p_setup.sides[line.sidenum[0]].bottomtexture = (short)p_switch.switchlist[i ^ 1];
                    p_setup.sides[line.sidenum[0]].sector.invalidate(false);
                    if (useAgain != 0)
                    {
                        p_switch.P_StartButton(line, p_spec.bwhere_e.bottom, switchlist[i], p_spec.BUTTONTIME);
                    }
                    return;
                }
            }
        }
Beispiel #7
0
        //==================================================================
        //
        //		Restart a ceiling that's in-stasis
        //
        //==================================================================
        public static void P_ActivateInStasisCeiling(r_local.line_t line)
        {
            int i;

            for (i = 0; i < p_spec.MAXCEILINGS; i++)
            {
                if (activeceilings[i] != null && (activeceilings[i].tag == line.tag) &&
                    (activeceilings[i].direction == 0))
                {
                    activeceilings[i].direction        = activeceilings[i].olddirection;
                    activeceilings[i].thinker.function = new T_MoveCeiling(activeceilings[i]);
                }
            }
        }
Beispiel #8
0
        public static void EV_StopPlat(r_local.line_t line)
        {
            int j;

            for (j = 0; j < p_spec.MAXPLATS; j++)
            {
                if (activeplats[j] != null && ((activeplats[j]).status != p_spec.plat_e.in_stasis) &&
                    ((activeplats[j]).tag == line.tag))
                {
                    (activeplats[j]).oldstatus        = (activeplats[j]).status;
                    (activeplats[j]).status           = p_spec.plat_e.in_stasis;
                    (activeplats[j]).thinker.function = null;
                }
            }
        }
Beispiel #9
0
        //----------------------------------------------------------------------------
        //
        // FUNC EV_Teleport
        //
        //----------------------------------------------------------------------------

        public static bool EV_Teleport(r_local.line_t line, int side, DoomDef.mobj_t thing)
        {
            int i;
            int tag;

            DoomDef.mobj_t    m;
            DoomDef.thinker_t thinker;
            r_local.sector_t  sector;

            if ((thing.flags2 & DoomDef.MF2_NOTELEPORT) != 0)
            {
                return(false);
            }
            if (side == 1)
            {             // Don't teleport when crossing back side
                return(false);
            }
            tag = line.tag;
            for (i = 0; i < p_setup.numsectors; i++)
            {
                if (p_setup.sectors[i].tag == tag)
                {
                    thinker = p_tick.thinkercap.next;
                    for (thinker = p_tick.thinkercap.next; thinker != p_tick.thinkercap;
                         thinker = thinker.next)
                    {
                        if (!(thinker.function is p_mobj.P_MobjThinker))
                        {                         // Not a mobj
                            continue;
                        }
                        m = thinker.function.obj as DoomDef.mobj_t;
                        if (m.type != info.mobjtype_t.MT_TELEPORTMAN)
                        {                         // Not a teleportman
                            continue;
                        }
                        sector = m.subsector.sector;
                        if (Array.IndexOf(p_setup.sectors, sector) != i)
                        {                         // Wrong sector
                            continue;
                        }
                        return(P_Teleport(thing, m.x, m.y, m.angle));
                    }
                }
            }
            return(false);
        }
Beispiel #10
0
        //==================================================================
        //
        //	Start strobing lights (usually from a trigger)
        //
        //==================================================================
        public static void EV_StartLightStrobing(r_local.line_t line)
        {
            int secnum;

            r_local.sector_t sec;

            secnum = -1;
            while ((secnum = p_spec.P_FindSectorFromLineTag(line, secnum)) >= 0)
            {
                sec = p_setup.sectors[secnum];
                if (sec.specialdata != null)
                {
                    continue;
                }

                P_SpawnStrobeFlash(sec, p_spec.SLOWDARK, 0);
            }
        }
Beispiel #11
0
            public override bool func(r_local.line_t ld)
            {
                int s1, s2;
                int frac;

                p_local.divline_t dl = new p_local.divline_t();

                // avoid precision problems with two routines
                if (trace.dx > DoomDef.FRACUNIT * 16 || trace.dy > DoomDef.FRACUNIT * 16 ||
                    trace.dx < -DoomDef.FRACUNIT * 16 || trace.dy < -DoomDef.FRACUNIT * 16)
                {
                    s1 = p_maputl.P_PointOnDivlineSide(ld.v1.x, ld.v1.y, trace);
                    s2 = p_maputl.P_PointOnDivlineSide(ld.v2.x, ld.v2.y, trace);
                }
                else
                {
                    s1 = P_PointOnLineSide(trace.x, trace.y, ld);
                    s2 = P_PointOnLineSide(trace.x + trace.dx, trace.y + trace.dy, ld);
                }
                if (s1 == s2)
                {
                    return(true);                               // line isn't crossed
                }
                //
                // hit the line
                //
                p_maputl.P_MakeDivline(ld, dl);
                frac = p_maputl.P_InterceptVector(trace, dl);
                if (frac < 0)
                {
                    return(true);                               // behind source
                }
                // try to early out the check
                if (earlyout && frac < DoomDef.FRACUNIT && ld.backsector == null)
                {
                    return(false);                      // stop checking
                }
                intercepts[intercept_p].frac    = frac;
                intercepts[intercept_p].isaline = true;
                intercepts[intercept_p].line    = ld;
                intercept_p++;

                return(true);                           // continue
            }
Beispiel #12
0
        /*
         * =================
         * =
         * = P_BoxOnLineSide
         * =
         * = Considers the line to be infinite
         * = Returns side 0 or 1, -1 if box crosses the line
         * =================
         */

        public static int P_BoxOnLineSide(int[] tmbox, r_local.line_t ld)
        {
            int p1 = 0, p2 = 0;

            switch (ld.slopetype)
            {
            case r_local.slopetype_t.ST_HORIZONTAL:
                p1 = tmbox[(int)DoomData.eUnknownEnumType2.BOXTOP] > ld.v1.y ? 1 : 0;
                p2 = tmbox[(int)DoomData.eUnknownEnumType2.BOXBOTTOM] > ld.v1.y ? 1 : 0;
                if (ld.dx < 0)
                {
                    p1 ^= 1;
                    p2 ^= 1;
                }
                break;

            case r_local.slopetype_t.ST_VERTICAL:
                p1 = tmbox[(int)DoomData.eUnknownEnumType2.BOXRIGHT] < ld.v1.x ? 1 : 0;
                p2 = tmbox[(int)DoomData.eUnknownEnumType2.BOXLEFT] < ld.v1.x ? 1 : 0;
                if (ld.dy < 0)
                {
                    p1 ^= 1;
                    p2 ^= 1;
                }
                break;

            case r_local.slopetype_t.ST_POSITIVE:
                p1 = p_maputl.P_PointOnLineSide(tmbox[(int)DoomData.eUnknownEnumType2.BOXLEFT], tmbox[(int)DoomData.eUnknownEnumType2.BOXTOP], ld);
                p2 = p_maputl.P_PointOnLineSide(tmbox[(int)DoomData.eUnknownEnumType2.BOXRIGHT], tmbox[(int)DoomData.eUnknownEnumType2.BOXBOTTOM], ld);
                break;

            case r_local.slopetype_t.ST_NEGATIVE:
                p1 = p_maputl.P_PointOnLineSide(tmbox[(int)DoomData.eUnknownEnumType2.BOXRIGHT], tmbox[(int)DoomData.eUnknownEnumType2.BOXTOP], ld);
                p2 = p_maputl.P_PointOnLineSide(tmbox[(int)DoomData.eUnknownEnumType2.BOXLEFT], tmbox[(int)DoomData.eUnknownEnumType2.BOXBOTTOM], ld);
                break;
            }

            if (p1 == p2)
            {
                return(p1);
            }
            return(-1);
        }
Beispiel #13
0
        //==================================================================
        //
        //		EV_CeilingCrushStop
        //		Stop a ceiling from crushing!
        //
        //==================================================================
        public static int EV_CeilingCrushStop(r_local.line_t line)
        {
            int i;
            int rtn;

            rtn = 0;
            for (i = 0; i < p_spec.MAXCEILINGS; i++)
            {
                if (activeceilings[i] != null && (activeceilings[i].tag == line.tag) &&
                    (activeceilings[i].direction != 0))
                {
                    activeceilings[i].olddirection     = activeceilings[i].direction;
                    activeceilings[i].thinker.function = null;
                    activeceilings[i].direction        = 0;                             // in-stasis
                    rtn = 1;
                }
            }

            return(rtn);
        }
Beispiel #14
0
        //==================================================================
        //
        //	TURN LINE'S TAG LIGHTS ON
        //
        //==================================================================
        public static void EV_LightTurnOn(r_local.line_t line, int bright)
        {
            int i;
            int j;

            r_local.sector_t sector;
            r_local.sector_t temp;
            r_local.line_t   templine;


            for (i = 0; i < p_setup.numsectors; i++)
            {
                sector = p_setup.sectors[i];
                if (sector.tag == line.tag)
                {
                    //
                    // bright = 0 means to search for highest
                    // light level surrounding sector
                    //
                    if (bright == 0)
                    {
                        for (j = 0; j < sector.linecount; j++)
                        {
                            templine = p_setup.linebuffer[sector.linesi + j];
                            temp     = p_spec.getNextSector(templine, sector);
                            if (temp == null)
                            {
                                continue;
                            }
                            if (temp.lightlevel > bright)
                            {
                                bright = temp.lightlevel;
                            }
                        }
                    }
                    sector.lightlevel = (short)bright;
                }
            }
        }
Beispiel #15
0
        //==================================================================
        //
        //	Start a button counting down till it turns off.
        //
        //==================================================================
        public static void P_StartButton(r_local.line_t line, p_spec.bwhere_e w, int texture, int time)
        {
            int i;

            for (i = 0; i < p_spec.MAXBUTTONS; i++)
            {
                if (buttonlist[i].btimer == 0)
                {
                    buttonlist[i].line       = line;
                    buttonlist[i].where      = w;
                    buttonlist[i].btexture   = texture;
                    buttonlist[i].btimer     = time;
                    buttonlist[i].soundorg   = new DoomDef.mobj_t();
                    buttonlist[i].soundorg.x = line.frontsector.soundorg.x;
                    buttonlist[i].soundorg.y = line.frontsector.soundorg.y;
                    buttonlist[i].soundorg.z = line.frontsector.soundorg.z;
                    return;
                }
            }

            i_ibm.I_Error("P_StartButton: no button slots left!");
        }
Beispiel #16
0
        //==================================================================
        //
        //	HANDLE FLOOR TYPES
        //
        //==================================================================
        public static int EV_DoFloor(r_local.line_t line, p_spec.floor_e floortype)
        {
            int secnum;
            int rtn;
            int i;

            r_local.sector_t   sec;
            p_spec.floormove_t floor;

            secnum = -1;
            rtn    = 0;
            while ((secnum = p_spec.P_FindSectorFromLineTag(line, secnum)) >= 0)
            {
                sec = p_setup.sectors[secnum];

                //	ALREADY MOVING?  IF SO, KEEP GOING... [dsl] WHY ARE YOU YELLING?
                if (sec.specialdata != null)
                {
                    continue;
                }

                //
                //	new floor thinker
                //
                rtn   = 1;
                floor = new p_spec.floormove_t();
                p_tick.P_AddThinker(floor.thinker);
                sec.specialdata        = floor;
                floor.thinker.function = new T_MoveFloor(floor);
                floor.type             = floortype;
                floor.crush            = false;
                switch (floortype)
                {
                case p_spec.floor_e.lowerFloor:
                    floor.direction       = -1;
                    floor.sector          = sec;
                    floor.speed           = p_spec.FLOORSPEED;
                    floor.floordestheight =
                        p_spec.P_FindHighestFloorSurrounding(sec);
                    break;

                case p_spec.floor_e.lowerFloorToLowest:
                    floor.direction       = -1;
                    floor.sector          = sec;
                    floor.speed           = p_spec.FLOORSPEED;
                    floor.floordestheight =
                        p_spec.P_FindLowestFloorSurrounding(sec);
                    break;

                case p_spec.floor_e.turboLower:
                    floor.direction       = -1;
                    floor.sector          = sec;
                    floor.speed           = p_spec.FLOORSPEED * 4;
                    floor.floordestheight = (8 * DoomDef.FRACUNIT) +
                                            p_spec.P_FindHighestFloorSurrounding(sec);
                    break;

                case p_spec.floor_e.raiseFloorCrush:
                    floor.crush           = true;
                    floor.direction       = 1;
                    floor.sector          = sec;
                    floor.speed           = p_spec.FLOORSPEED;
                    floor.floordestheight =
                        p_spec.P_FindLowestCeilingSurrounding(sec);
                    if (floor.floordestheight > sec.ceilingheight)
                    {
                        floor.floordestheight = sec.ceilingheight;
                    }
                    floor.floordestheight -= (8 * DoomDef.FRACUNIT) *
                                             ((floortype == p_spec.floor_e.raiseFloorCrush) ? 1 : 0);
                    break;

                case p_spec.floor_e.raiseFloor:
                    floor.direction       = 1;
                    floor.sector          = sec;
                    floor.speed           = p_spec.FLOORSPEED;
                    floor.floordestheight =
                        p_spec.P_FindLowestCeilingSurrounding(sec);
                    if (floor.floordestheight > sec.ceilingheight)
                    {
                        floor.floordestheight = sec.ceilingheight;
                    }
                    floor.floordestheight -= (8 * DoomDef.FRACUNIT) *
                                             ((floortype == p_spec.floor_e.raiseFloorCrush) ? 1 : 0);
                    break;

                case p_spec.floor_e.raiseFloorToNearest:
                    floor.direction       = 1;
                    floor.sector          = sec;
                    floor.speed           = p_spec.FLOORSPEED;
                    floor.floordestheight =
                        p_spec.P_FindNextHighestFloor(sec, sec.floorheight);
                    break;

                case p_spec.floor_e.raiseFloor24:
                    floor.direction       = 1;
                    floor.sector          = sec;
                    floor.speed           = p_spec.FLOORSPEED;
                    floor.floordestheight = floor.sector.floorheight +
                                            24 * DoomDef.FRACUNIT;
                    break;

                case p_spec.floor_e.raiseFloor24AndChange:
                    floor.direction       = 1;
                    floor.sector          = sec;
                    floor.speed           = p_spec.FLOORSPEED;
                    floor.floordestheight = floor.sector.floorheight +
                                            24 * DoomDef.FRACUNIT;
                    sec.floorpic = line.frontsector.floorpic;
                    sec.special  = line.frontsector.special;
                    break;

                case p_spec.floor_e.raiseToTexture:
                {
                    int            minsize = DoomDef.MAXINT;
                    r_local.side_t side;

                    floor.direction = 1;
                    floor.sector    = sec;
                    floor.speed     = p_spec.FLOORSPEED;
                    for (i = 0; i < sec.linecount; i++)
                    {
                        if (p_spec.twoSided(secnum, i) != 0)
                        {
                            side = p_spec.getSide(secnum, i, 0);
                            if (side.bottomtexture >= 0)
                            {
                                if (r_data.textureheight[side.bottomtexture] <
                                    minsize)
                                {
                                    minsize =
                                        r_data.textureheight[side.bottomtexture];
                                }
                            }
                            side = p_spec.getSide(secnum, i, 1);
                            if (side.bottomtexture >= 0)
                            {
                                if (r_data.textureheight[side.bottomtexture] <
                                    minsize)
                                {
                                    minsize =
                                        r_data.textureheight[side.bottomtexture];
                                }
                            }
                        }
                    }
                    floor.floordestheight = floor.sector.floorheight +
                                            minsize;
                }
                break;

                case p_spec.floor_e.lowerAndChange:
                    floor.direction       = -1;
                    floor.sector          = sec;
                    floor.speed           = p_spec.FLOORSPEED;
                    floor.floordestheight =
                        p_spec.P_FindLowestFloorSurrounding(sec);
                    floor.texture = sec.floorpic;
                    for (i = 0; i < sec.linecount; i++)
                    {
                        if (p_spec.twoSided(secnum, i) != 0)
                        {
                            if (Array.IndexOf(p_setup.sectors, p_spec.getSide(secnum, i, 0).sector) == secnum)
                            {
                                sec              = p_spec.getSector(secnum, i, 1);
                                floor.texture    = sec.floorpic;
                                floor.newspecial = sec.special;
                                break;
                            }
                            else
                            {
                                sec              = p_spec.getSector(secnum, i, 0);
                                floor.texture    = sec.floorpic;
                                floor.newspecial = sec.special;
                                break;
                            }
                        }
                    }
                    break;

                default:
                    break;
                }
            }
            return(rtn);
        }
Beispiel #17
0
 public virtual bool func(r_local.line_t line)
 {
     return(false);
 }
Beispiel #18
0
        //==================================================================
        //
        //	BUILD A STAIRCASE!
        //
        //==================================================================
        public static int EV_BuildStairs(r_local.line_t line, int stepDelta)
        {
            int secnum;
            int height;
            int i;
            int newsecnum;
            int texture;
            int ok;
            int rtn;

            r_local.sector_t   sec, tsec;
            p_spec.floormove_t floor;

            secnum = -1;
            rtn    = 0;
            while ((secnum = p_spec.P_FindSectorFromLineTag(line, secnum)) >= 0)
            {
                sec = p_setup.sectors[secnum];

                // ALREADY MOVING?  IF SO, KEEP GOING...
                if (sec.specialdata != null)
                {
                    continue;
                }

                //
                // new floor thinker
                //
                rtn    = 1;
                height = sec.floorheight + stepDelta;
                floor  = new p_spec.floormove_t();
                p_tick.P_AddThinker(floor.thinker);
                sec.specialdata        = floor;
                floor.thinker.function = new T_MoveFloor(floor);
                floor.type             = p_spec.floor_e.raiseBuildStep;
                floor.direction        = 1;
                floor.sector           = sec;
                floor.speed            = p_spec.FLOORSPEED;
                floor.floordestheight  = height;

                texture = sec.floorpic;

                //
                // Find next sector to raise
                // 1.	Find 2-sided line with same sector side[0]
                // 2.	Other side is the next sector to raise
                //
                do
                {
                    ok = 0;
                    for (i = 0; i < sec.linecount; i++)
                    {
                        if (((p_setup.linebuffer[sec.linesi + i]).flags & DoomData.ML_TWOSIDED) == 0)
                        {
                            continue;
                        }

                        tsec      = (p_setup.linebuffer[sec.linesi + i]).frontsector;
                        newsecnum = Array.IndexOf(p_setup.sectors, tsec);
                        if (secnum != newsecnum)
                        {
                            continue;
                        }
                        tsec      = (p_setup.linebuffer[sec.linesi + i]).backsector;
                        newsecnum = Array.IndexOf(p_setup.sectors, tsec);
                        if (tsec.floorpic != texture)
                        {
                            continue;
                        }

                        height += stepDelta;
                        if (tsec.specialdata != null)
                        {
                            continue;
                        }

                        sec    = tsec;
                        secnum = newsecnum;
                        floor  = new p_spec.floormove_t();
                        p_tick.P_AddThinker(floor.thinker);
                        sec.specialdata        = floor;
                        floor.thinker.function = new T_MoveFloor(floor);
                        floor.type             = p_spec.floor_e.raiseBuildStep;
                        floor.direction        = 1;
                        floor.sector           = sec;
                        floor.speed            = p_spec.FLOORSPEED;
                        floor.floordestheight  = height;
                        ok = 1;
                        break;
                    }
                } while (ok != 0);
            }
            return(rtn);
        }
Beispiel #19
0
//----------------------------------------------------------------------------
//
// EV_DoDoor
//
// Move a door up/down
//
//----------------------------------------------------------------------------

        public static int EV_DoDoor(r_local.line_t line, p_spec.vldoor_e type, int speed)
        {
            int secnum;
            int retcode;

            r_local.sector_t sec;
            p_spec.vldoor_t  door;

            secnum  = -1;
            retcode = 0;
            while ((secnum = p_spec.P_FindSectorFromLineTag(line, secnum)) >= 0)
            {
                sec = p_setup.sectors[secnum];
                if (sec.specialdata != null)
                {
                    continue;
                }
                // Add new door thinker
                retcode = 1;
                door    = new p_spec.vldoor_t();
                p_tick.P_AddThinker(door.thinker);
                sec.specialdata       = door;
                door.thinker.function = new T_VerticalDoor(door);
                door.sector           = sec;
                switch (type)
                {
                case p_spec.vldoor_e.close:
                    door.topheight  = p_spec.P_FindLowestCeilingSurrounding(sec);
                    door.topheight -= 4 * DoomDef.FRACUNIT;
                    door.direction  = -1;
                    i_ibm.S_StartSound(
                        door.sector.soundorg.x,
                        door.sector.soundorg.y,
                        door.sector.soundorg.z,
                        (int)sounds.sfxenum_t.sfx_doropn);
                    break;

                case p_spec.vldoor_e.close30ThenOpen:
                    door.topheight = sec.ceilingheight;
                    door.direction = -1;
                    i_ibm.S_StartSound(
                        door.sector.soundorg.x,
                        door.sector.soundorg.y,
                        door.sector.soundorg.z,
                        (int)sounds.sfxenum_t.sfx_doropn);
                    break;

                case p_spec.vldoor_e.normal:
                case p_spec.vldoor_e.open:
                    door.direction  = 1;
                    door.topheight  = p_spec.P_FindLowestCeilingSurrounding(sec);
                    door.topheight -= 4 * DoomDef.FRACUNIT;
                    if (door.topheight != sec.ceilingheight)
                    {
                        i_ibm.S_StartSound(
                            door.sector.soundorg.x,
                            door.sector.soundorg.y,
                            door.sector.soundorg.z,
                            (int)sounds.sfxenum_t.sfx_doropn);
                    }
                    break;

                default:
                    break;
                }
                door.type    = type;
                door.speed   = speed;
                door.topwait = p_spec.VDOORWAIT;
            }
            return(retcode);
        }
Beispiel #20
0
//==================================================================
//
//	EV_VerticalDoor : open a door manually, no tag value
//
//==================================================================
        public static void EV_VerticalDoor(r_local.line_t line, DoomDef.mobj_t thing)
        {
            DoomDef.player_t player;
            int secnum;

            r_local.sector_t sec;
            p_spec.vldoor_t  door;
            int side;

            side = 0; // only front sides can be used
//
//	Check for locks
//
            player = thing.player;
            switch (line.special)
            {
            case 26:     // Blue Lock
            case 32:
                if (player == null)
                {
                    return;
                }
                if (!player.keys[(int)DoomDef.keytype_t.key_blue])
                {
                    p_inter.P_SetMessage(player, dstring.TXT_NEEDBLUEKEY, false);
                    i_ibm.S_StartSound(null, (int)sounds.sfxenum_t.sfx_plroof);
                    return;
                }
                break;

            case 27:     // Yellow Lock
            case 34:
                if (player == null)
                {
                    return;
                }
                if (!player.keys[(int)DoomDef.keytype_t.key_yellow])
                {
                    p_inter.P_SetMessage(player, dstring.TXT_NEEDYELLOWKEY, false);
                    i_ibm.S_StartSound(null, (int)sounds.sfxenum_t.sfx_plroof);
                    return;
                }
                break;

            case 28:     // Green Lock
            case 33:
                if (player == null)
                {
                    return;
                }
                if (!player.keys[(int)DoomDef.keytype_t.key_green])
                {
                    p_inter.P_SetMessage(player, dstring.TXT_NEEDGREENKEY, false);
                    i_ibm.S_StartSound(null, (int)sounds.sfxenum_t.sfx_plroof);
                    return;
                }
                break;
            }
            // if the sector has an active thinker, use it
            sec    = p_setup.sides[line.sidenum[side ^ 1]].sector;
            secnum = Array.IndexOf(p_setup.sectors, sec);
            if (sec.specialdata != null)
            {
                door = sec.specialdata as p_spec.vldoor_t;
                switch (line.special)
                {
                case 1:         // ONLY FOR "RAISE" DOORS, NOT "OPEN"s
                case 26:
                case 27:
                case 28:
                    if (door.direction == -1)
                    {
                        door.direction = 1;                 // go back up
                    }
                    else
                    {
                        if (thing.player == null)
                        {                 // Monsters don't close doors
                            return;
                        }
                        door.direction = -1;                 // start going down immediately
                    }
                    return;
                }
            }

            // for proper sound
            switch (line.special)
            {
            case 1:     // NORMAL DOOR SOUND
            case 31:
                i_ibm.S_StartSound(
                    sec.soundorg.x,
                    sec.soundorg.y,
                    sec.soundorg.z,
                    (int)sounds.sfxenum_t.sfx_doropn);
                break;

            default:     // LOCKED DOOR SOUND
                i_ibm.S_StartSound(
                    sec.soundorg.x,
                    sec.soundorg.y,
                    sec.soundorg.z,
                    (int)sounds.sfxenum_t.sfx_doropn);
                break;
            }

            //
            // new door thinker
            //
            door = new p_spec.vldoor_t();
            p_tick.P_AddThinker(door.thinker);
            sec.specialdata       = door;
            door.thinker.function = new T_VerticalDoor(door);
            door.sector           = sec;
            door.direction        = 1;
            switch (line.special)
            {
            case 1:
            case 26:
            case 27:
            case 28:
                door.type = p_spec.vldoor_e.normal;
                break;

            case 31:
            case 32:
            case 33:
            case 34:
                door.type    = p_spec.vldoor_e.open;
                line.special = 0;
                break;
            }
            door.speed   = p_spec.VDOORSPEED;
            door.topwait = p_spec.VDOORWAIT;

            //
            // find the top and bottom of the movement range
            //
            door.topheight  = p_spec.P_FindLowestCeilingSurrounding(sec);
            door.topheight -= 4 * DoomDef.FRACUNIT;
        }
Beispiel #21
0
        /*
         * ==============================================================================
         * =
         * = P_UseSpecialLine
         * =
         * = Called when a thing uses a special line
         * = Only the front sides of lines are usable
         * ===============================================================================
         */

        public static bool P_UseSpecialLine(DoomDef.mobj_t thing, r_local.line_t line)
        {
            //
            //	Switches that other things can activate
            //
            if (thing.player == null)
            {
                if ((line.flags & DoomData.ML_SECRET) != 0)
                {
                    return(false);                              // never open secret doors
                }
                switch (line.special)
                {
                case 1:                                 // MANUAL DOOR RAISE
                case 32:                                // MANUAL BLUE
                case 33:                                // MANUAL RED
                case 34:                                // MANUAL YELLOW
                    break;

                default:
                    return(false);
                }
            }

            //
            // do something
            //
            switch (line.special)
            {
            //===============================================
            //	MANUALS
            //===============================================
            case 1:                                     // Vertical Door
            case 26:                                    // Blue Door/Locked
            case 27:                                    // Yellow Door /Locked
            case 28:                                    // Red Door /Locked

            case 31:                                    // Manual door open
            case 32:                                    // Blue locked door open
            case 33:                                    // Red locked door open
            case 34:                                    // Yellow locked door open
                p_doors.EV_VerticalDoor(line, thing);
                break;

            //===============================================
            //	SWITCHES
            //===============================================
            case 7:                     // Switch_Build_Stairs (8 pixel steps)
                if (p_floor.EV_BuildStairs(line, 8 * DoomDef.FRACUNIT) != 0)
                {
                    P_ChangeSwitchTexture(line, 0);
                }
                break;

            case 107:                     // Switch_Build_Stairs_16 (16 pixel steps)
                if (p_floor.EV_BuildStairs(line, 16 * DoomDef.FRACUNIT) != 0)
                {
                    P_ChangeSwitchTexture(line, 0);
                }
                break;

            case 9:                                     // Change Donut
                //if (EV_DoDonut(line))
                //    P_ChangeSwitchTexture(line, 0);
                break;

            case 11:                                    // Exit level
                g_game.G_ExitLevel();
                P_ChangeSwitchTexture(line, 0);
                break;

            case 14:                                    // Raise Floor 32 and change texture
                if (p_plats.EV_DoPlat(line, p_spec.plattype_e.raiseAndChange, 32) != 0)
                {
                    P_ChangeSwitchTexture(line, 0);
                }
                break;

            case 15:                                    // Raise Floor 24 and change texture
                if (p_plats.EV_DoPlat(line, p_spec.plattype_e.raiseAndChange, 24) != 0)
                {
                    P_ChangeSwitchTexture(line, 0);
                }
                break;

            case 18:                                    // Raise Floor to next highest floor
                if (p_floor.EV_DoFloor(line, p_spec.floor_e.raiseFloorToNearest) != 0)
                {
                    P_ChangeSwitchTexture(line, 0);
                }
                break;

            case 20:                                    // Raise Plat next highest floor and change texture
                if (p_plats.EV_DoPlat(line, p_spec.plattype_e.raiseToNearestAndChange, 0) != 0)
                {
                    P_ChangeSwitchTexture(line, 0);
                }
                break;

            case 21:                                    // PlatDownWaitUpStay
                if (p_plats.EV_DoPlat(line, p_spec.plattype_e.downWaitUpStay, 0) != 0)
                {
                    P_ChangeSwitchTexture(line, 0);
                }
                break;

            case 23:                                    // Lower Floor to Lowest
                if (p_floor.EV_DoFloor(line, p_spec.floor_e.lowerFloorToLowest) != 0)
                {
                    P_ChangeSwitchTexture(line, 0);
                }
                break;

            case 29:                                    // Raise Door
                if (p_doors.EV_DoDoor(line, p_spec.vldoor_e.normal, p_spec.VDOORSPEED) != 0)
                {
                    P_ChangeSwitchTexture(line, 0);
                }
                break;

            case 41:                                    // Lower Ceiling to Floor
                if (p_ceilng.EV_DoCeiling(line, p_spec.ceiling_e.lowerToFloor) != 0)
                {
                    P_ChangeSwitchTexture(line, 0);
                }
                break;

            case 71:                                    // Turbo Lower Floor
                if (p_floor.EV_DoFloor(line, p_spec.floor_e.turboLower) != 0)
                {
                    P_ChangeSwitchTexture(line, 0);
                }
                break;

            case 49:                                    // Lower Ceiling And Crush
                if (p_ceilng.EV_DoCeiling(line, p_spec.ceiling_e.lowerAndCrush) != 0)
                {
                    P_ChangeSwitchTexture(line, 0);
                }
                break;

            case 50:                                    // Close Door
                if (p_doors.EV_DoDoor(line, p_spec.vldoor_e.close, p_spec.VDOORSPEED) != 0)
                {
                    P_ChangeSwitchTexture(line, 0);
                }
                break;

            case 51:                                    // Secret EXIT
                //G_SecretExitLevel();
                //P_ChangeSwitchTexture(line, 0);
                break;

            case 55:                                    // Raise Floor Crush
                if (p_floor.EV_DoFloor(line, p_spec.floor_e.raiseFloorCrush) != 0)
                {
                    P_ChangeSwitchTexture(line, 0);
                }
                break;

            case 101:                                   // Raise Floor
                if (p_floor.EV_DoFloor(line, p_spec.floor_e.raiseFloor) != 0)
                {
                    P_ChangeSwitchTexture(line, 0);
                }
                break;

            case 102:                                   // Lower Floor to Surrounding floor height
                if (p_floor.EV_DoFloor(line, p_spec.floor_e.lowerFloor) != 0)
                {
                    P_ChangeSwitchTexture(line, 0);
                }
                break;

            case 103:                                   // Open Door
                if (p_doors.EV_DoDoor(line, p_spec.vldoor_e.open, p_spec.VDOORSPEED) != 0)
                {
                    P_ChangeSwitchTexture(line, 0);
                }
                break;

            //===============================================
            //	BUTTONS
            //===============================================
            case 42:                                    // Close Door
                if (p_doors.EV_DoDoor(line, p_spec.vldoor_e.close, p_spec.VDOORSPEED) != 0)
                {
                    P_ChangeSwitchTexture(line, 1);
                }
                break;

            case 43:                                    // Lower Ceiling to Floor
                if (p_ceilng.EV_DoCeiling(line, p_spec.ceiling_e.lowerToFloor) != 0)
                {
                    P_ChangeSwitchTexture(line, 1);
                }
                break;

            case 45:                                    // Lower Floor to Surrounding floor height
                if (p_floor.EV_DoFloor(line, p_spec.floor_e.lowerFloor) != 0)
                {
                    P_ChangeSwitchTexture(line, 1);
                }
                break;

            case 60:                                    // Lower Floor to Lowest
                if (p_floor.EV_DoFloor(line, p_spec.floor_e.lowerFloorToLowest) != 0)
                {
                    P_ChangeSwitchTexture(line, 1);
                }
                break;

            case 61:                                    // Open Door
                if (p_doors.EV_DoDoor(line, p_spec.vldoor_e.open, p_spec.VDOORSPEED) != 0)
                {
                    P_ChangeSwitchTexture(line, 1);
                }
                break;

            case 62:                                    // PlatDownWaitUpStay
                if (p_plats.EV_DoPlat(line, p_spec.plattype_e.downWaitUpStay, 1) != 0)
                {
                    P_ChangeSwitchTexture(line, 1);
                }
                break;

            case 63:                                    // Raise Door
                if (p_doors.EV_DoDoor(line, p_spec.vldoor_e.normal, p_spec.VDOORSPEED) != 0)
                {
                    P_ChangeSwitchTexture(line, 1);
                }
                break;

            case 64:                                    // Raise Floor to ceiling
                if (p_floor.EV_DoFloor(line, p_spec.floor_e.raiseFloor) != 0)
                {
                    P_ChangeSwitchTexture(line, 1);
                }
                break;

            case 66:                                    // Raise Floor 24 and change texture
                if (p_plats.EV_DoPlat(line, p_spec.plattype_e.raiseAndChange, 24) != 0)
                {
                    P_ChangeSwitchTexture(line, 1);
                }
                break;

            case 67:                                    // Raise Floor 32 and change texture
                if (p_plats.EV_DoPlat(line, p_spec.plattype_e.raiseAndChange, 32) != 0)
                {
                    P_ChangeSwitchTexture(line, 1);
                }
                break;

            case 65:                                    // Raise Floor Crush
                if (p_floor.EV_DoFloor(line, p_spec.floor_e.raiseFloorCrush) != 0)
                {
                    P_ChangeSwitchTexture(line, 1);
                }
                break;

            case 68:                                    // Raise Plat to next highest floor and change texture
                if (p_plats.EV_DoPlat(line, p_spec.plattype_e.raiseToNearestAndChange, 0) != 0)
                {
                    P_ChangeSwitchTexture(line, 1);
                }
                break;

            case 69:                                    // Raise Floor to next highest floor
                if (p_floor.EV_DoFloor(line, p_spec.floor_e.raiseFloorToNearest) != 0)
                {
                    P_ChangeSwitchTexture(line, 1);
                }
                break;

            case 70:                                    // Turbo Lower Floor
                if (p_floor.EV_DoFloor(line, p_spec.floor_e.turboLower) != 0)
                {
                    P_ChangeSwitchTexture(line, 1);
                }
                break;
            }

            return(true);
        }
Beispiel #22
0
        /*
         * =================
         * =
         * = P_LoadLineDefs
         * =
         * = Also counts secret lines for intermissions [dsl] No it doesn't?
         * =================
         */

        public static void P_LoadLineDefs(int lump)
        {
            w_wad.CacheInfo data;
            int             i;

            DoomData.maplinedef_t mld;
            r_local.line_t        ld;
            r_local.vertex_t      v1, v2;

            numlines = w_wad.W_LumpLength(lump) / 14;
            lines    = new r_local.line_t[numlines];
            data     = w_wad.W_CacheLumpNum(lump, DoomDef.PU_STATIC);
            BinaryReader br = new BinaryReader(new MemoryStream(data.data));

            for (i = 0; i < numlines; i++)
            {
                mld            = new DoomData.maplinedef_t();
                mld.v1         = br.ReadInt16();
                mld.v2         = br.ReadInt16();
                mld.flags      = br.ReadInt16();
                mld.special    = br.ReadInt16();
                mld.tag        = br.ReadInt16();
                mld.sidenum[0] = br.ReadInt16();
                mld.sidenum[1] = br.ReadInt16();

                ld         = new r_local.line_t();
                ld.flags   = mld.flags;
                ld.special = mld.special;
                ld.tag     = mld.tag;
                v1         = ld.v1 = vertexes[mld.v1];
                v2         = ld.v2 = vertexes[mld.v2];
                ld.dx      = v2.x - v1.x;
                ld.dy      = v2.y - v1.y;
                if (ld.dx == 0)
                {
                    ld.slopetype = r_local.slopetype_t.ST_VERTICAL;
                }
                else if (ld.dy == 0)
                {
                    ld.slopetype = r_local.slopetype_t.ST_HORIZONTAL;
                }
                else
                {
                    if (d_main.FixedDiv(ld.dy, ld.dx) > 0)
                    {
                        ld.slopetype = r_local.slopetype_t.ST_POSITIVE;
                    }
                    else
                    {
                        ld.slopetype = r_local.slopetype_t.ST_NEGATIVE;
                    }
                }

                if (v1.x < v2.x)
                {
                    ld.bbox[(int)DoomData.eUnknownEnumType2.BOXLEFT]  = v1.x;
                    ld.bbox[(int)DoomData.eUnknownEnumType2.BOXRIGHT] = v2.x;
                }
                else
                {
                    ld.bbox[(int)DoomData.eUnknownEnumType2.BOXLEFT]  = v2.x;
                    ld.bbox[(int)DoomData.eUnknownEnumType2.BOXRIGHT] = v1.x;
                }
                if (v1.y < v2.y)
                {
                    ld.bbox[(int)DoomData.eUnknownEnumType2.BOXBOTTOM] = v1.y;
                    ld.bbox[(int)DoomData.eUnknownEnumType2.BOXTOP]    = v2.y;
                }
                else
                {
                    ld.bbox[(int)DoomData.eUnknownEnumType2.BOXBOTTOM] = v2.y;
                    ld.bbox[(int)DoomData.eUnknownEnumType2.BOXTOP]    = v1.y;
                }
                ld.sidenum[0] = (mld.sidenum[0]);
                ld.sidenum[1] = (mld.sidenum[1]);
                if (ld.sidenum[0] != -1)
                {
                    ld.frontsector = sides[ld.sidenum[0]].sector;
                }
                else
                {
                    ld.frontsector = null;
                }
                if (ld.sidenum[1] != -1)
                {
                    ld.backsector = sides[ld.sidenum[1]].sector;
                }
                else
                {
                    ld.backsector = null;
                }
                lines[i] = ld;
            }
        }
Beispiel #23
0
        //==================================================================
        //
        //		EV_DoCeiling
        //		Move a ceiling up/down and all around!
        //
        //==================================================================
        public static int EV_DoCeiling(r_local.line_t line, p_spec.ceiling_e type)
        {
            int secnum, rtn;

            r_local.sector_t sec;
            p_spec.ceiling_t ceiling;

            secnum = -1;
            rtn    = 0;

            //
            //	Reactivate in-stasis ceilings...for certain types.
            //
            switch (type)
            {
            case p_spec.ceiling_e.fastCrushAndRaise:
            case p_spec.ceiling_e.crushAndRaise:
                P_ActivateInStasisCeiling(line);
                break;

            default:
                break;
            }

            while ((secnum = p_spec.P_FindSectorFromLineTag(line, secnum)) >= 0)
            {
                sec = p_setup.sectors[secnum];
                if (sec.specialdata != null)
                {
                    continue;
                }

                //
                // new door thinker
                //
                rtn     = 1;
                ceiling = new p_spec.ceiling_t();
                p_tick.P_AddThinker(ceiling.thinker);
                sec.specialdata          = ceiling;
                ceiling.thinker.function = new T_MoveCeiling(ceiling);
                ceiling.sector           = sec;
                ceiling.crush            = false;
                switch (type)
                {
                case p_spec.ceiling_e.fastCrushAndRaise:
                    ceiling.crush        = true;
                    ceiling.topheight    = sec.ceilingheight;
                    ceiling.bottomheight = sec.floorheight + (8 * DoomDef.FRACUNIT);
                    ceiling.direction    = -1;
                    ceiling.speed        = p_spec.CEILSPEED * 2;
                    break;

                case p_spec.ceiling_e.crushAndRaise:
                    ceiling.crush        = true;
                    ceiling.topheight    = sec.ceilingheight;
                    ceiling.bottomheight = sec.floorheight;
                    if (type != p_spec.ceiling_e.lowerToFloor)
                    {
                        ceiling.bottomheight += 8 * DoomDef.FRACUNIT;
                    }
                    ceiling.direction = -1;
                    ceiling.speed     = p_spec.CEILSPEED;
                    break;

                case p_spec.ceiling_e.lowerAndCrush:
                case p_spec.ceiling_e.lowerToFloor:
                    ceiling.bottomheight = sec.floorheight;
                    if (type != p_spec.ceiling_e.lowerToFloor)
                    {
                        ceiling.bottomheight += 8 * DoomDef.FRACUNIT;
                    }
                    ceiling.direction = -1;
                    ceiling.speed     = p_spec.CEILSPEED;
                    break;

                case p_spec.ceiling_e.raiseToHighest:
                    ceiling.topheight = p_spec.P_FindHighestCeilingSurrounding(sec);
                    ceiling.direction = 1;
                    ceiling.speed     = p_spec.CEILSPEED;
                    break;
                }

                ceiling.tag  = sec.tag;
                ceiling.type = type;
                P_AddActiveCeiling(ceiling);
            }
            return(rtn);
        }
Beispiel #24
0
        public static void GatherSectorsInRadiusIterThroughLine(
            Vector2 pos,
            r_local.sector_t sector,
            r_local.line_t li,
            float radius,
            ref List <r_local.sector_t> out_sectors)
        {
            r_local.sector_t newSector = null;
            Vector2          liNormal  = Vector2.Zero;
            Vector2          v         = new Vector2(
                li.v1.x >> DoomDef.FRACBITS,
                li.v1.y >> DoomDef.FRACBITS);
            Vector2 w = new Vector2(
                li.v2.x >> DoomDef.FRACBITS,
                li.v2.y >> DoomDef.FRACBITS);

            if (li.frontsector == sector)
            {
                if (li.backsector != null)
                {
                    newSector = li.backsector;
                    Vector2 dir = w - v;
                    dir.Normalize();
                    liNormal.X = dir.Y;
                    liNormal.Y = -dir.X;
                }
            }
            else if (li.backsector == sector)
            {
                newSector = li.frontsector;
                Vector2 dir = v - w;
                dir.Normalize();
                liNormal.X = dir.Y;
                liNormal.Y = -dir.X;
            }
            if (newSector == null)
            {
                return;
            }
            if (newSector.checkId == checkId)
            {
                return;                                           // Already checked
            }
            float dotWithNormal = Vector2.Dot(
                liNormal, v - pos);

            if (dotWithNormal > 0)
            {
                return;
            }

            // Is out line in the radius?
            float dis = minimum_distance(v, w, pos);

            if (dis > radius)
            {
                return;
            }

            newSector.checkId = checkId;
            out_sectors.Add(newSector);
            GatherSectorsInRadiusIter(pos, newSector, radius, ref out_sectors);
        }
Beispiel #25
0
        //==================================================================
        //
        //	Do Platforms
        //	"amount" is only used for SOME platforms.
        //
        //==================================================================
        public static int EV_DoPlat(r_local.line_t line, p_spec.plattype_e type, int amount)
        {
            p_spec.plat_t plat;
            int           secnum;
            int           rtn;

            r_local.sector_t sec;

            secnum = -1;
            rtn    = 0;

            //
            //	Activate all <type> plats that are in_stasis
            //
            switch (type)
            {
            case p_spec.plattype_e.perpetualRaise:
                P_ActivateInStasis(line.tag);
                break;

            default:
                break;
            }

            while ((secnum = p_spec.P_FindSectorFromLineTag(line, secnum)) >= 0)
            {
                sec = p_setup.sectors[secnum];
                if (sec.specialdata != null)
                {
                    continue;
                }

                //
                // Find lowest & highest floors around sector
                //
                rtn  = 1;
                plat = new p_spec.plat_t();
                p_tick.P_AddThinker(plat.thinker);

                plat.type               = type;
                plat.sector             = sec;
                plat.sector.specialdata = plat;
                plat.thinker.function   = new T_PlatRaise(plat);
                plat.crush              = false;
                plat.tag = line.tag;
                switch (type)
                {
                case p_spec.plattype_e.raiseToNearestAndChange:
                    plat.speed   = p_spec.PLATSPEED / 2;
                    sec.floorpic = p_setup.sides[line.sidenum[0]].sector.floorpic;
                    plat.high    = p_spec.P_FindNextHighestFloor(sec, sec.floorheight);
                    plat.wait    = 0;
                    plat.status  = p_spec.plat_e.up;
                    sec.special  = 0;                                           // NO MORE DAMAGE, IF APPLICABLE
                    i_ibm.S_StartSound(sec.soundorg.x, sec.soundorg.y, sec.soundorg.z, (int)sounds.sfxenum_t.sfx_stnmov);
                    break;

                case p_spec.plattype_e.raiseAndChange:
                    plat.speed   = p_spec.PLATSPEED / 2;
                    sec.floorpic = p_setup.sides[line.sidenum[0]].sector.floorpic;
                    plat.high    = sec.floorheight + amount * DoomDef.FRACUNIT;
                    plat.wait    = 0;
                    plat.status  = p_spec.plat_e.up;
                    i_ibm.S_StartSound(sec.soundorg.x, sec.soundorg.y, sec.soundorg.z, (int)sounds.sfxenum_t.sfx_stnmov);
                    break;

                case p_spec.plattype_e.downWaitUpStay:
                    plat.speed = p_spec.PLATSPEED * 4;
                    plat.low   = p_spec.P_FindLowestFloorSurrounding(sec);
                    if (plat.low > sec.floorheight)
                    {
                        plat.low = sec.floorheight;
                    }
                    plat.high   = sec.floorheight;
                    plat.wait   = 35 * p_spec.PLATWAIT;
                    plat.status = p_spec.plat_e.down;
                    i_ibm.S_StartSound(sec.soundorg.x, sec.soundorg.y, sec.soundorg.z, (int)sounds.sfxenum_t.sfx_pstart);
                    break;

                case p_spec.plattype_e.perpetualRaise:
                    plat.speed = p_spec.PLATSPEED;
                    plat.low   = p_spec.P_FindLowestFloorSurrounding(sec);
                    if (plat.low > sec.floorheight)
                    {
                        plat.low = sec.floorheight;
                    }
                    plat.high = p_spec.P_FindHighestFloorSurrounding(sec);
                    if (plat.high < sec.floorheight)
                    {
                        plat.high = sec.floorheight;
                    }
                    plat.wait   = 35 * p_spec.PLATWAIT;
                    plat.status = (p_spec.plat_e)(m_misc.P_Random() & 1);
                    i_ibm.S_StartSound(sec.soundorg.x, sec.soundorg.y, sec.soundorg.z, (int)sounds.sfxenum_t.sfx_pstart);
                    break;
                }
                P_AddActivePlat(plat);
            }
            return(rtn);
        }