//================================================================== // // 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; } } }
/* * ============== * = * = 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; }
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; }
/* * ================== * = * = 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 }
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); } }
//================================================================== // // 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; } } }
//================================================================== // // 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]); } } }
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; } } }
//---------------------------------------------------------------------------- // // 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); }
//================================================================== // // 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); } }
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 }
/* * ================= * = * = 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); }
//================================================================== // // 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); }
//================================================================== // // 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; } } }
//================================================================== // // 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!"); }
//================================================================== // // 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); }
public virtual bool func(r_local.line_t line) { return(false); }
//================================================================== // // 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); }
//---------------------------------------------------------------------------- // // 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); }
//================================================================== // // 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; }
/* * ============================================================================== * = * = 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); }
/* * ================= * = * = 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; } }
//================================================================== // // 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); }
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); }
//================================================================== // // 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); }