private static int ArchiveLine(LineDef line, byte[] data, int p) { Write(data, p, (short)line.Flags); Write(data, p + 2, (short)line.Special); Write(data, p + 4, (short)line.Tag); p += 6; if (line.FrontSide != null) { var side = line.FrontSide; Write(data, p, (short)side.TextureOffset.ToIntFloor()); Write(data, p + 2, (short)side.RowOffset.ToIntFloor()); Write(data, p + 4, (short)side.TopTexture); Write(data, p + 6, (short)side.BottomTexture); Write(data, p + 8, (short)side.MiddleTexture); p += 10; } if (line.BackSide != null) { var side = line.BackSide; Write(data, p, (short)side.TextureOffset.ToIntFloor()); Write(data, p + 2, (short)side.RowOffset.ToIntFloor()); Write(data, p + 4, (short)side.TopTexture); Write(data, p + 6, (short)side.BottomTexture); Write(data, p + 8, (short)side.MiddleTexture); p += 10; } return(p); }
private void StartButton(LineDef line, ButtonPosition w, int texture, int time) { // See if button is already pressed. for (var i = 0; i < maxButtonCount; i++) { if (buttonList[i].Timer != 0 && buttonList[i].Line == line) { return; } } for (var i = 0; i < maxButtonCount; i++) { if (buttonList[i].Timer == 0) { buttonList[i].Line = line; buttonList[i].Position = w; buttonList[i].Texture = texture; buttonList[i].Timer = time; buttonList[i].SoundOrigin = line.SoundOrigin; return; } } throw new Exception("No button slots left!"); }
public void MakeFrom(LineDef line) { x = line.Vertex1.X; y = line.Vertex1.Y; dx = line.Dx; dy = line.Dy; }
public void LineOpening(LineDef line) { if (line.Side1 == null) { // If the line is single sided, nothing can pass through. openRange = Fixed.Zero; return; } var front = line.FrontSector; var back = line.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; }
private static int UnArchiveLine(LineDef line, byte[] data, int p) { line.Flags = (LineFlags)BitConverter.ToInt16(data, p); line.Special = (LineSpecial)BitConverter.ToInt16(data, p + 2); line.Tag = BitConverter.ToInt16(data, p + 4); p += 6; if (line.FrontSide != null) { var side = line.FrontSide; side.TextureOffset = Fixed.FromInt(BitConverter.ToInt16(data, p)); side.RowOffset = Fixed.FromInt(BitConverter.ToInt16(data, p + 2)); side.TopTexture = BitConverter.ToInt16(data, p + 4); side.BottomTexture = BitConverter.ToInt16(data, p + 6); side.MiddleTexture = BitConverter.ToInt16(data, p + 8); p += 10; } if (line.BackSide != null) { var side = line.BackSide; side.TextureOffset = Fixed.FromInt(BitConverter.ToInt16(data, p)); side.RowOffset = Fixed.FromInt(BitConverter.ToInt16(data, p + 2)); side.TopTexture = BitConverter.ToInt16(data, p + 4); side.BottomTexture = BitConverter.ToInt16(data, p + 6); side.MiddleTexture = BitConverter.ToInt16(data, p + 8); p += 10; } return(p); }
public void MakeFrom(LineDef line) { X = line.Vertex1.X; Y = line.Vertex1.Y; Dx = line.Dx; Dy = line.Dy; }
private bool SlideTraverse(Intercept intercept) { var mc = world.MapCollision; if (intercept.Line == null) { throw new Exception("ThingMovement.SlideTraverse: Not a line?"); } var line = intercept.Line; if ((line.Flags & LineFlags.TwoSided) == 0) { if (Geometry.PointOnLineSide(slideThing.X, slideThing.Y, line) != 0) { // Don't hit the back side. return(true); } goto isBlocking; } // Set openrange, opentop, openbottom. mc.LineOpening(line); if (mc.OpenRange < slideThing.Height) { // Doesn't fit. goto isBlocking; } if (mc.OpenTop - slideThing.Z < slideThing.Height) { // Mobj is too high. goto isBlocking; } if (mc.OpenBottom - slideThing.Z > Fixed.FromInt(24)) { // Too big a step up. goto isBlocking; } // This line doesn't block movement. return(true); // The line does block movement, see if it is closer than best so far. isBlocking: if (intercept.Frac < bestSlideFrac) { secondSlideFrac = bestSlideFrac; secondSlideLine = bestSlideLine; bestSlideFrac = intercept.Frac; bestSlideLine = line; } // Stop. return(false); }
public void Clear() { Line = null; Position = 0; Texture = 0; Timer = 0; SoundOrigin = null; }
public void Clear() { line = null; position = 0; texture = 0; timer = 0; soundOrigin = null; }
public bool TeleportMove(Mobj thing, Fixed x, Fixed y) { // Kill anything occupying the position. currentThing = thing; currentFlags = thing.Flags; currentX = x; currentY = y; currentBox[Box.Top] = y + currentThing.Radius; currentBox[Box.Bottom] = y - currentThing.Radius; currentBox[Box.Right] = x + currentThing.Radius; currentBox[Box.Left] = x - currentThing.Radius; var ss = Geometry.PointInSubsector(x, y, world.Map); currentCeilingLine = null; // The base floor / ceiling is from the subsector that contains the point. // Any contacted lines the step closer together will adjust them. currentFloorZ = currentDropoffZ = ss.Sector.FloorHeight; currentCeilingZ = ss.Sector.CeilingHeight; var validcount = world.GetNewValidCount(); crossedSpecialCount = 0; // Stomp on any things contacted. var bm = world.Map.BlockMap; var blockX1 = bm.GetBlockX(currentBox[Box.Left] - GameConst.MaxThingRadius); var blockX2 = bm.GetBlockX(currentBox[Box.Right] + GameConst.MaxThingRadius); var blockY1 = bm.GetBlockY(currentBox[Box.Bottom] - GameConst.MaxThingRadius); var blockY2 = bm.GetBlockY(currentBox[Box.Top] + GameConst.MaxThingRadius); for (var bx = blockX1; bx <= blockX2; bx++) { for (var by = blockY1; by <= blockY2; by++) { if (!bm.IterateThings(bx, by, stompThingFunc)) { return(false); } } } // the move is ok, so link the thing into its new position UnsetThingPosition(thing); thing.FloorZ = currentFloorZ; thing.CeilingZ = currentCeilingZ; thing.X = x; thing.Y = y; SetThingPosition(thing); return(true); }
private bool AddLineIntercepts(LineDef line) { int s1; int s2; // Avoid precision problems with two routines. if (trace.Dx > Fixed.FromInt(16) || trace.Dy > Fixed.FromInt(16) || trace.Dx < -Fixed.FromInt(16) || trace.Dy < -Fixed.FromInt(16)) { s1 = Geometry.PointOnDivLineSide(line.Vertex1.X, line.Vertex1.Y, trace); s2 = Geometry.PointOnDivLineSide(line.Vertex2.X, line.Vertex2.Y, trace); } else { s1 = Geometry.PointOnLineSide(trace.X, trace.Y, line); s2 = Geometry.PointOnLineSide(trace.X + trace.Dx, trace.Y + trace.Dy, line); } if (s1 == s2) { // Line isn't crossed. return(true); } // Hit the line. target.MakeFrom(line); var frac = InterceptVector(trace, target); if (frac < Fixed.Zero) { // Behind source. return(true); } // Try to early out the check. if (earlyOut && frac < Fixed.One && line.BackSector == null) { // Stop checking. return(false); } intercepts[interceptCount].Frac = frac; intercepts[interceptCount].Line = line; intercepts[interceptCount].Thing = null; interceptCount++; // Continue. return(true); }
/// <summary> /// Calculate on which side of the line the box is. /// </summary> /// <returns> /// 0 (front), 1 (back), or -1 if the box crosses the line. /// </returns> public static int BoxOnLineSide(Fixed[] box, LineDef line) { int p1; int p2; switch (line.SlopeType) { case SlopeType.Horizontal: p1 = box[Box.Top] > line.Vertex1.Y ? 1 : 0; p2 = box[Box.Bottom] > line.Vertex1.Y ? 1 : 0; if (line.Dx < Fixed.Zero) { p1 ^= 1; p2 ^= 1; } break; case SlopeType.Vertical: p1 = box[Box.Right] < line.Vertex1.X ? 1 : 0; p2 = box[Box.Left] < line.Vertex1.X ? 1 : 0; if (line.Dy < Fixed.Zero) { p1 ^= 1; p2 ^= 1; } break; case SlopeType.Positive: p1 = PointOnLineSide(box[Box.Left], box[Box.Top], line); p2 = PointOnLineSide(box[Box.Right], box[Box.Bottom], line); break; case SlopeType.Negative: p1 = PointOnLineSide(box[Box.Right], box[Box.Top], line); p2 = PointOnLineSide(box[Box.Left], box[Box.Bottom], line); break; default: throw new Exception("Invalid SlopeType."); } if (p1 == p2) { return(p1); } else { return(-1); } }
private Sector GetNextSector(LineDef line, Sector sector) { if ((line.Flags & LineFlags.TwoSided) == 0) { return(null); } if (line.FrontSector == sector) { return(line.BackSector); } return(line.FrontSector); }
//////////////////////////////////////////////////////////// // Line shoot //////////////////////////////////////////////////////////// /// <summary> /// Called when a thing shoots a special line. /// </summary> public void ShootSpecialLine(Mobj thing, LineDef line) { bool ok; // Impacts that other things can activate. if (thing.Player == null) { ok = false; switch ((int)line.Special) { case 46: // Open door impact. ok = true; break; } if (!ok) { return; } } var sa = world.SectorAction; var specials = world.Specials; switch ((int)line.Special) { case 24: // Raise floor. sa.DoFloor(line, FloorMoveType.RaiseFloor); specials.ChangeSwitchTexture(line, false); break; case 46: // Open door. sa.DoDoor(line, VerticalDoorType.Open); specials.ChangeSwitchTexture(line, true); break; case 47: // Raise floor near and change. sa.DoPlatform(line, PlatformType.RaiseToNearestAndChange, 0); specials.ChangeSwitchTexture(line, false); break; } }
// // P_ShootSpecialLine - IMPACT SPECIALS // Called when a thing shoots a special line. // public void ShootSpecialLine(Mobj thing, LineDef line) { bool ok; // Impacts that other things can activate. if (thing.Player == null) { ok = false; switch ((int)line.Special) { case 46: // OPEN DOOR IMPACT ok = true; break; } if (!ok) { return; } } var sa = world.SectorAction; var specials = world.Specials; switch ((int)line.Special) { case 24: // RAISE FLOOR sa.EV_DoFloor(line, FloorMoveType.RaiseFloor); specials.ChangeSwitchTexture(line, false); break; case 46: // OPEN DOOR sa.EV_DoDoor(line, VlDoorType.Open); specials.ChangeSwitchTexture(line, true); break; case 47: // RAISE FLOOR NEAR AND CHANGE sa.EV_DoPlat(line, PlatformType.RaiseToNearestAndChange, 0); specials.ChangeSwitchTexture(line, false); break; } }
public Seg( Vertex vertex1, Vertex vertex2, Fixed offset, Angle angle, SideDef sideDef, LineDef lineDef, Sector frontSector, Sector backSector) { this.vertex1 = vertex1; this.vertex2 = vertex2; this.offset = offset; this.angle = angle; this.sideDef = sideDef; this.lineDef = lineDef; this.frontSector = frontSector; this.backSector = backSector; }
/// <summary> /// Calculate on which side of the line the point is. /// </summary> /// <returns> /// 0 (front) or 1 (back). /// </returns> public static int PointOnLineSide(Fixed x, Fixed y, LineDef line) { if (line.Dx == Fixed.Zero) { if (x <= line.Vertex1.X) { return(line.Dy > Fixed.Zero ? 1 : 0); } else { return(line.Dy < Fixed.Zero ? 1 : 0); } } if (line.Dy == Fixed.Zero) { if (y <= line.Vertex1.Y) { return(line.Dx < Fixed.Zero ? 1 : 0); } else { return(line.Dx > Fixed.Zero ? 1 : 0); } } var dx = (x - line.Vertex1.X); var dy = (y - line.Vertex1.Y); var left = new Fixed(line.Dy.Data >> Fixed.FracBits) * dx; var right = dy * new Fixed(line.Dx.Data >> Fixed.FracBits); if (right < left) { // Front side. return(0); } else { // Back side. return(1); } }
public static LineDef[] FromWad(Wad wad, int lump, Vertex[] vertices, SideDef[] sides) { var length = wad.GetLumpSize(lump); if (length % DataSize != 0) { throw new Exception(); } var data = wad.ReadLump(lump); var count = length / DataSize; var lines = new LineDef[count];; for (var i = 0; i < count; i++) { var offset = 14 * i; lines[i] = FromData(data, offset, vertices, sides); } return(lines); }
/// <summary> /// Adjusts the x and y movement so that the next move will /// slide along the wall. /// </summary> private void HitSlideLine(LineDef line) { if (line.SlopeType == SlopeType.Horizontal) { slideMoveY = Fixed.Zero; return; } if (line.SlopeType == SlopeType.Vertical) { slideMoveX = Fixed.Zero; return; } var side = Geometry.PointOnLineSide(slideThing.X, slideThing.Y, line); var lineAngle = Geometry.PointToAngle(Fixed.Zero, Fixed.Zero, line.Dx, line.Dy); if (side == 1) { lineAngle += Angle.Ang180; } var moveAngle = Geometry.PointToAngle(Fixed.Zero, Fixed.Zero, slideMoveX, slideMoveY); var deltaAngle = moveAngle - lineAngle; if (deltaAngle > Angle.Ang180) { deltaAngle += Angle.Ang180; } var moveDist = Geometry.AproxDistance(slideMoveX, slideMoveY); var newDist = moveDist * Trig.Cos(deltaAngle); slideMoveX = newDist * Trig.Cos(lineAngle); slideMoveY = newDist * Trig.Sin(lineAngle); }
public Map(Wad wad, TextureLookup textures, FlatLookup flats, World world) { this.textures = textures; this.flats = flats; this.world = world; var options = world.Options; string name; if (wad.Names.Contains("doom") || wad.Names.Contains("doom1")) { name = "E" + options.Episode + "M" + options.Map; } else { name = "MAP" + options.Map.ToString("00"); } var map = wad.GetLumpNumber(name); vertices = Vertex.FromWad(wad, map + 4); sectors = Sector.FromWad(wad, map + 8, flats); sides = SideDef.FromWad(wad, map + 3, textures, sectors); lines = LineDef.FromWad(wad, map + 2, vertices, sides); segs = Seg.FromWad(wad, map + 5, vertices, lines); subsectors = Subsector.FromWad(wad, map + 6, segs); nodes = Node.FromWad(wad, map + 7, subsectors); things = MapThing.FromWad(wad, map + 1); blockMap = BlockMap.FromWad(wad, map + 10, lines); reject = Reject.FromWad(wad, map + 9, sectors); GroupLines(); skyTexture = GetSkyTextureByMapName(name); }
private void InitBoss() { var v = new Vertex(Fixed.Zero, Fixed.Zero); junk = new LineDef(v, v, 0, 0, 0, null, null); }
public void ChangeSwitchTexture(LineDef line, bool useAgain) { if (!useAgain) { line.Special = 0; } var frontSide = line.FrontSide; var topTexture = frontSide.TopTexture; var middleTexture = frontSide.MiddleTexture; var bottomTexture = frontSide.BottomTexture; var sound = Sfx.SWTCHN; // Exit switch? if ((int)line.Special == 11) { sound = Sfx.SWTCHX; } var switchList = world.Map.Textures.SwitchList; for (var i = 0; i < switchList.Length; i++) { if (switchList[i] == topTexture) { world.StartSound(line.SoundOrigin, sound, SfxType.Misc); frontSide.TopTexture = switchList[i ^ 1]; if (useAgain) { StartButton(line, ButtonPosition.Top, switchList[i], buttonTime); } return; } else { if (switchList[i] == middleTexture) { world.StartSound(line.SoundOrigin, sound, SfxType.Misc); frontSide.MiddleTexture = switchList[i ^ 1]; if (useAgain) { StartButton(line, ButtonPosition.Middle, switchList[i], buttonTime); } return; } else { if (switchList[i] == bottomTexture) { world.StartSound(line.SoundOrigin, sound, SfxType.Misc); frontSide.BottomTexture = switchList[i ^ 1]; if (useAgain) { StartButton(line, ButtonPosition.Bottom, switchList[i], buttonTime); } return; } } } } }
public Map(Wad wad, ITextureLookup textures, IFlatLookup flats, TextureAnimation animation, World world) { try { this.textures = textures; this.flats = flats; this.animation = animation; this.world = world; var options = world.Options; string name; if (wad.GameMode == GameMode.Commercial) { name = "MAP" + options.Map.ToString("00"); } else { name = "E" + options.Episode + "M" + options.Map; } Console.Write("Load map '" + name + "': "); var map = wad.GetLumpNumber(name); if (map == -1) { throw new Exception("Map '" + name + "' was not found!"); } vertices = Vertex.FromWad(wad, map + 4); sectors = Sector.FromWad(wad, map + 8, flats); sides = SideDef.FromWad(wad, map + 3, textures, sectors); lines = LineDef.FromWad(wad, map + 2, vertices, sides); segs = Seg.FromWad(wad, map + 5, vertices, lines); subsectors = Subsector.FromWad(wad, map + 6, segs); nodes = Node.FromWad(wad, map + 7, subsectors); things = MapThing.FromWad(wad, map + 1); blockMap = BlockMap.FromWad(wad, map + 10, lines); reject = Reject.FromWad(wad, map + 9, sectors); GroupLines(); skyTexture = GetSkyTextureByMapName(name); if (options.GameMode == GameMode.Commercial) { switch (options.MissionPack) { case MissionPack.Plutonia: title = DoomInfo.MapTitles.Plutonia[options.Map - 1]; break; case MissionPack.Tnt: title = DoomInfo.MapTitles.Tnt[options.Map - 1]; break; default: title = DoomInfo.MapTitles.Doom2[options.Map - 1]; break; } } else { title = DoomInfo.MapTitles.Doom[options.Episode - 1][options.Map - 1]; } Console.WriteLine("OK"); } catch (Exception e) { Console.WriteLine("Failed"); ExceptionDispatchInfo.Throw(e); } }
public void Make(Fixed frac, LineDef line) { this.frac = frac; this.thing = null; this.line = line; }
public void ChangeSwitchTexture(LineDef line, bool useAgain) { if (!useAgain) { line.Special = 0; } var texTop = line.Side0.TopTexture; var texMid = line.Side0.MiddleTexture; var texBot = line.Side0.BottomTexture; var sound = Sfx.SWTCHN; // EXIT SWITCH? if ((int)line.Special == 11) { sound = Sfx.SWTCHX; } var switchList = world.Map.Textures.SwitchList; for (var i = 0; i < switchList.Length; i++) { if (switchList[i] == texTop) { world.StartSound(line.SoundOrigin, sound); line.Side0.TopTexture = switchList[i ^ 1]; if (useAgain) { StartButton(line, ButtonPosition.Top, switchList[i], BUTTONTIME); } return; } else { if (switchList[i] == texMid) { world.StartSound(line.SoundOrigin, sound); line.Side0.MiddleTexture = switchList[i ^ 1]; if (useAgain) { StartButton(line, ButtonPosition.Middle, switchList[i], BUTTONTIME); } return; } else { if (switchList[i] == texBot) { world.StartSound(line.SoundOrigin, sound); line.Side0.BottomTexture = switchList[i ^ 1]; if (useAgain) { StartButton(line, ButtonPosition.Bottom, switchList[i], BUTTONTIME); } return; } } } } }
// // P_UseSpecialLine // Called when a thing uses a special line. // Only the front sides of lines are usable. // public bool UseSpecialLine(Mobj thing, LineDef line, int side) { var specials = world.Specials; var sa = world.SectorAction; // Err... // Use the back sides of VERY SPECIAL lines... if (side != 0) { switch ((int)line.Special) { case 124: // Sliding door open&close // UNUSED? break; default: return(false); } } // Switches that other things can activate. if (thing.Player == null) { // never open secret doors if ((line.Flags & LineFlags.Secret) != 0) { return(false); } switch ((int)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 ((int)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 case 117: // Blazing door raise case 118: // Blazing door open sa.EV_VerticalDoor(line, thing); break; //UNUSED - Door Slide Open&Close // case 124: // EV_SlidingDoor (line, thing); // break; // SWITCHES case 7: // Build Stairs if (sa.EV_BuildStairs(line, StairType.Build8)) { specials.ChangeSwitchTexture(line, false); } break; case 9: // Change Donut //if (EV_DoDonut(line)) { //P_ChangeSwitchTexture(line, 0); } break; case 11: // Exit level specials.ChangeSwitchTexture(line, false); world.G_ExitLevel(); break; case 14: // Raise Floor 32 and change texture if (sa.EV_DoPlat(line, PlatformType.RaiseAndChange, 32)) { specials.ChangeSwitchTexture(line, false); } break; case 15: // Raise Floor 24 and change texture if (sa.EV_DoPlat(line, PlatformType.RaiseAndChange, 24)) { specials.ChangeSwitchTexture(line, false); } break; case 18: // Raise Floor to next highest floor if (sa.EV_DoFloor(line, FloorMoveType.RaiseFloorToNearest)) { specials.ChangeSwitchTexture(line, false); } break; case 20: // Raise Plat next highest floor and change texture if (sa.EV_DoPlat(line, PlatformType.RaiseToNearestAndChange, 0)) { specials.ChangeSwitchTexture(line, false); } break; case 21: // PlatDownWaitUpStay if (sa.EV_DoPlat(line, PlatformType.DownWaitUpStay, 0)) { specials.ChangeSwitchTexture(line, false); } break; case 23: // Lower Floor to Lowest if (sa.EV_DoFloor(line, FloorMoveType.LowerFloorToLowest)) { specials.ChangeSwitchTexture(line, false); } break; case 29: // Raise Door if (sa.EV_DoDoor(line, VlDoorType.Normal)) { specials.ChangeSwitchTexture(line, false); } break; case 41: // Lower Ceiling to Floor if (sa.EV_DoCeiling(line, CeilingMoveType.LowerToFloor)) { specials.ChangeSwitchTexture(line, false); } break; case 71: // Turbo Lower Floor if (sa.EV_DoFloor(line, FloorMoveType.TurboLower)) { specials.ChangeSwitchTexture(line, false); } break; case 49: // Ceiling Crush And Raise if (sa.EV_DoCeiling(line, CeilingMoveType.CrushAndRaise)) { specials.ChangeSwitchTexture(line, false); } break; case 50: // Close Door if (sa.EV_DoDoor(line, VlDoorType.Close)) { specials.ChangeSwitchTexture(line, false); } break; case 51: // Secret EXIT //P_ChangeSwitchTexture(line, 0); //G_SecretExitLevel(); break; case 55: // Raise Floor Crush if (sa.EV_DoFloor(line, FloorMoveType.RaiseFloorCrush)) { specials.ChangeSwitchTexture(line, false); } break; case 101: // Raise Floor if (sa.EV_DoFloor(line, FloorMoveType.RaiseFloor)) { specials.ChangeSwitchTexture(line, false); } break; case 102: // Lower Floor to Surrounding floor height if (sa.EV_DoFloor(line, FloorMoveType.LowerFloor)) { specials.ChangeSwitchTexture(line, false); } break; case 103: // Open Door if (sa.EV_DoDoor(line, VlDoorType.Open)) { specials.ChangeSwitchTexture(line, false); } break; case 111: // Blazing Door Raise (faster than TURBO!) if (sa.EV_DoDoor(line, VlDoorType.BlazeRaise)) { specials.ChangeSwitchTexture(line, false); } break; case 112: // Blazing Door Open (faster than TURBO!) if (sa.EV_DoDoor(line, VlDoorType.BlazeOpen)) { specials.ChangeSwitchTexture(line, false); } break; case 113: // Blazing Door Close (faster than TURBO!) if (sa.EV_DoDoor(line, VlDoorType.BlazeClose)) { specials.ChangeSwitchTexture(line, false); } break; case 122: // Blazing PlatDownWaitUpStay if (sa.EV_DoPlat(line, PlatformType.BlazeDwus, 0)) { specials.ChangeSwitchTexture(line, false); } break; case 127: // Build Stairs Turbo 16 if (sa.EV_BuildStairs(line, StairType.Turbo16)) { specials.ChangeSwitchTexture(line, false); } break; case 131: // Raise Floor Turbo if (sa.EV_DoFloor(line, FloorMoveType.RaiseFloorTurbo)) { specials.ChangeSwitchTexture(line, false); } break; case 133: // BlzOpenDoor BLUE case 135: // BlzOpenDoor RED case 137: // BlzOpenDoor YELLOW if (sa.EV_DoLockedDoor(line, VlDoorType.BlazeOpen, thing)) { specials.ChangeSwitchTexture(line, false); } break; case 140: // Raise Floor 512 if (sa.EV_DoFloor(line, FloorMoveType.RaiseFloor512)) { specials.ChangeSwitchTexture(line, false); } break; // BUTTONS case 42: // Close Door if (sa.EV_DoDoor(line, VlDoorType.Close)) { specials.ChangeSwitchTexture(line, true); } break; case 43: // Lower Ceiling to Floor if (sa.EV_DoCeiling(line, CeilingMoveType.LowerToFloor)) { specials.ChangeSwitchTexture(line, true); } break; case 45: // Lower Floor to Surrounding floor height if (sa.EV_DoFloor(line, FloorMoveType.LowerFloor)) { specials.ChangeSwitchTexture(line, true); } break; case 60: // Lower Floor to Lowest if (sa.EV_DoFloor(line, FloorMoveType.LowerFloorToLowest)) { specials.ChangeSwitchTexture(line, true); } break; case 61: // Open Door if (sa.EV_DoDoor(line, VlDoorType.Open)) { specials.ChangeSwitchTexture(line, true); } break; case 62: // PlatDownWaitUpStay if (sa.EV_DoPlat(line, PlatformType.DownWaitUpStay, 1)) { specials.ChangeSwitchTexture(line, true); } break; case 63: // Raise Door if (sa.EV_DoDoor(line, VlDoorType.Normal)) { specials.ChangeSwitchTexture(line, true); } break; case 64: // Raise Floor to ceiling if (sa.EV_DoFloor(line, FloorMoveType.RaiseFloor)) { specials.ChangeSwitchTexture(line, true); } break; case 66: // Raise Floor 24 and change texture if (sa.EV_DoPlat(line, PlatformType.RaiseAndChange, 24)) { specials.ChangeSwitchTexture(line, true); } break; case 67: // Raise Floor 32 and change texture if (sa.EV_DoPlat(line, PlatformType.RaiseAndChange, 32)) { specials.ChangeSwitchTexture(line, true); } break; case 65: // Raise Floor Crush if (sa.EV_DoFloor(line, FloorMoveType.RaiseFloorCrush)) { specials.ChangeSwitchTexture(line, true); } break; case 68: // Raise Plat to next highest floor and change texture if (sa.EV_DoPlat(line, PlatformType.RaiseToNearestAndChange, 0)) { specials.ChangeSwitchTexture(line, true); } break; case 69: // Raise Floor to next highest floor if (sa.EV_DoFloor(line, FloorMoveType.RaiseFloorToNearest)) { specials.ChangeSwitchTexture(line, true); } break; case 70: // Turbo Lower Floor if (sa.EV_DoFloor(line, FloorMoveType.TurboLower)) { specials.ChangeSwitchTexture(line, true); } break; case 114: // Blazing Door Raise (faster than TURBO!) if (sa.EV_DoDoor(line, VlDoorType.BlazeRaise)) { specials.ChangeSwitchTexture(line, true); } break; case 115: // Blazing Door Open (faster than TURBO!) if (sa.EV_DoDoor(line, VlDoorType.BlazeOpen)) { specials.ChangeSwitchTexture(line, true); } break; case 116: // Blazing Door Close (faster than TURBO!) if (sa.EV_DoDoor(line, VlDoorType.BlazeClose)) { specials.ChangeSwitchTexture(line, true); } break; case 123: // Blazing PlatDownWaitUpStay if (sa.EV_DoPlat(line, PlatformType.BlazeDwus, 0)) { specials.ChangeSwitchTexture(line, true); } break; case 132: // Raise Floor Turbo if (sa.EV_DoFloor(line, FloorMoveType.RaiseFloorTurbo)) { specials.ChangeSwitchTexture(line, true); } break; case 99: // BlzOpenDoor BLUE case 134: // BlzOpenDoor RED case 136: // BlzOpenDoor YELLOW if (sa.EV_DoLockedDoor(line, VlDoorType.BlazeOpen, thing)) { specials.ChangeSwitchTexture(line, true); } break; case 138: // Light Turn On sa.EV_LightTurnOn(line, 255); specials.ChangeSwitchTexture(line, true); break; case 139: // Light Turn Off sa.EV_LightTurnOn(line, 35); specials.ChangeSwitchTexture(line, true); break; } return(true); }
/// <summary> /// This is purely informative, nothing is modified /// (except things picked up). /// /// In: /// A Mobj (can be valid or invalid) /// A position to be checked /// (doesn't need to be related to the mobj.X and Y) /// /// During: /// Special things are touched if MobjFlags.PickUp /// Early out on solid lines? /// /// Out: /// New subsector /// CurrentFloorZ /// CurrentCeilingZ /// CurrentDropoffZ /// The lowest point contacted /// (monsters won't move to a dropoff) /// crossedSpecials[] /// crossedSpecialCount /// </summary> public bool CheckPosition(Mobj thing, Fixed x, Fixed y) { var map = world.Map; var bm = map.BlockMap; currentThing = thing; currentFlags = thing.Flags; currentX = x; currentY = y; currentBox[Box.Top] = y + currentThing.Radius; currentBox[Box.Bottom] = y - currentThing.Radius; currentBox[Box.Right] = x + currentThing.Radius; currentBox[Box.Left] = x - currentThing.Radius; var newSubsector = Geometry.PointInSubsector(x, y, map); currentCeilingLine = null; // The base floor / ceiling is from the subsector that contains the point. // Any contacted lines the step closer together will adjust them. currentFloorZ = currentDropoffZ = newSubsector.Sector.FloorHeight; currentCeilingZ = newSubsector.Sector.CeilingHeight; var validCount = world.GetNewValidCount(); crossedSpecialCount = 0; if ((currentFlags & MobjFlags.NoClip) != 0) { return(true); } // Check things first, possibly picking things up. // The bounding box is extended by MaxThingRadius because mobj_ts are grouped into // mapblocks based on their origin point, and can overlap into adjacent blocks by up // to MaxThingRadius units. { var blockX1 = bm.GetBlockX(currentBox[Box.Left] - GameConst.MaxThingRadius); var blockX2 = bm.GetBlockX(currentBox[Box.Right] + GameConst.MaxThingRadius); var blockY1 = bm.GetBlockY(currentBox[Box.Bottom] - GameConst.MaxThingRadius); var blockY2 = bm.GetBlockY(currentBox[Box.Top] + GameConst.MaxThingRadius); for (var bx = blockX1; bx <= blockX2; bx++) { for (var by = blockY1; by <= blockY2; by++) { if (!map.BlockMap.IterateThings(bx, by, checkThingFunc)) { return(false); } } } } // Check lines. { var blockX1 = bm.GetBlockX(currentBox[Box.Left]); var blockX2 = bm.GetBlockX(currentBox[Box.Right]); var blockY1 = bm.GetBlockY(currentBox[Box.Bottom]); var blockY2 = bm.GetBlockY(currentBox[Box.Top]); for (var bx = blockX1; bx <= blockX2; bx++) { for (var by = blockY1; by <= blockY2; by++) { if (!map.BlockMap.IterateLines(bx, by, checkLineFunc, validCount)) { return(false); } } } } return(true); }
/// <summary> /// Adjusts currentFloorZ and currentCeilingZ as lines are contacted. /// </summary> private bool CheckLine(LineDef line) { var mc = world.MapCollision; if (currentBox.Right() <= line.BoundingBox.Left() || currentBox.Left() >= line.BoundingBox.Right() || currentBox.Top() <= line.BoundingBox.Bottom() || currentBox.Bottom() >= line.BoundingBox.Top()) { return(true); } if (Geometry.BoxOnLineSide(currentBox, line) != -1) { return(true); } // A line has been hit. // // The moving thing's destination position will cross the given line. // If this should not be allowed, return false. // If the line is special, keep track of it to process later if the move is proven ok. // // NOTE: // specials are NOT sorted by order, so two special lines that are only 8 pixels // apart could be crossed in either order. if (line.BackSector == null) { // One sided line. return(false); } if ((currentThing.Flags & MobjFlags.Missile) == 0) { if ((line.Flags & LineFlags.Blocking) != 0) { // Explicitly blocking everything. return(false); } if (currentThing.Player == null && (line.Flags & LineFlags.BlockMonsters) != 0) { // Block monsters only. return(false); } } // Set openrange, opentop, openbottom. mc.LineOpening(line); // Adjust floor / ceiling heights. if (mc.OpenTop < currentCeilingZ) { currentCeilingZ = mc.OpenTop; currentCeilingLine = line; } if (mc.OpenBottom > currentFloorZ) { currentFloorZ = mc.OpenBottom; } if (mc.LowFloor < currentDropoffZ) { currentDropoffZ = mc.LowFloor; } // If contacted a special line, add it to the list. if (line.Special != 0) { crossedSpecials[crossedSpecialCount] = line; crossedSpecialCount++; } return(true); }
// // P_CrossSpecialLine - TRIGGER // Called every time a thing origin is about // to cross a line with a non 0 special. // public void CrossSpecialLine(LineDef line, int side, Mobj thing) { // Triggers that other things can activate if (thing.Player == null) { // Things that should NOT trigger specials... switch (thing.Type) { case MobjType.Rocket: case MobjType.Plasma: case MobjType.Bfg: case MobjType.Troopshot: case MobjType.Headshot: case MobjType.Bruisershot: return; default: break; } var ok = false; switch ((int)line.Special) { case 39: // TELEPORT TRIGGER case 97: // TELEPORT RETRIGGER case 125: // TELEPORT MONSTERONLY TRIGGER case 126: // TELEPORT MONSTERONLY RETRIGGER case 4: // RAISE DOOR case 10: // PLAT DOWN-WAIT-UP-STAY TRIGGER case 88: // PLAT DOWN-WAIT-UP-STAY RETRIGGER ok = true; break; } if (!ok) { return; } } var sa = world.SectorAction; // Note: could use some const's here. switch ((int)line.Special) { // TRIGGERS. // All from here to RETRIGGERS. case 2: // Open Door sa.EV_DoDoor(line, VlDoorType.Open); line.Special = 0; break; case 3: // Close Door sa.EV_DoDoor(line, VlDoorType.Close); line.Special = 0; break; case 4: // Raise Door sa.EV_DoDoor(line, VlDoorType.Normal); line.Special = 0; break; case 5: // Raise Floor sa.EV_DoFloor(line, FloorMoveType.RaiseFloor); line.Special = 0; break; case 6: // Fast Ceiling Crush & Raise sa.EV_DoCeiling(line, CeilingMoveType.FastCrushAndRaise); line.Special = 0; break; case 8: // Build Stairs sa.EV_BuildStairs(line, StairType.Build8); line.Special = 0; break; case 10: // PlatDownWaitUp sa.EV_DoPlat(line, PlatformType.DownWaitUpStay, 0); line.Special = 0; break; case 12: // Light Turn On - brightest near sa.EV_LightTurnOn(line, 0); line.Special = 0; break; case 13: // Light Turn On 255 sa.EV_LightTurnOn(line, 255); line.Special = 0; break; case 16: // Close Door 30 sa.EV_DoDoor(line, VlDoorType.Close30ThenOpen); line.Special = 0; break; case 17: // Start Light Strobing sa.EV_StartLightStrobing(line); line.Special = 0; break; case 19: // Lower Floor sa.EV_DoFloor(line, FloorMoveType.LowerFloor); line.Special = 0; break; case 22: // Raise floor to nearest height and change texture sa.EV_DoPlat(line, PlatformType.RaiseToNearestAndChange, 0); line.Special = 0; break; case 25: // Ceiling Crush and Raise sa.EV_DoCeiling(line, CeilingMoveType.CrushAndRaise); line.Special = 0; break; case 30: // Raise floor to shortest texture height // on either side of lines. sa.EV_DoFloor(line, FloorMoveType.RaiseToTexture); line.Special = 0; break; case 35: // Lights Very Dark sa.EV_LightTurnOn(line, 35); line.Special = 0; break; case 36: // Lower Floor (TURBO) sa.EV_DoFloor(line, FloorMoveType.TurboLower); line.Special = 0; break; case 37: // LowerAndChange sa.EV_DoFloor(line, FloorMoveType.LowerAndChange); line.Special = 0; break; case 38: // Lower Floor To Lowest sa.EV_DoFloor(line, FloorMoveType.LowerFloorToLowest); line.Special = 0; break; case 39: // TELEPORT! sa.EV_Teleport(line, side, thing); line.Special = 0; break; case 40: // RaiseCeilingLowerFloor sa.EV_DoCeiling(line, CeilingMoveType.RaiseToHighest); sa.EV_DoFloor(line, FloorMoveType.LowerFloorToLowest); line.Special = 0; break; case 44: // Ceiling Crush sa.EV_DoCeiling(line, CeilingMoveType.LowerAndCrush); line.Special = 0; break; case 52: // EXIT! world.G_ExitLevel(); break; case 53: // Perpetual Platform Raise sa.EV_DoPlat(line, PlatformType.PerpetualRaise, 0); line.Special = 0; break; case 54: // Platform Stop sa.EV_StopPlat(line); line.Special = 0; break; case 56: // Raise Floor Crush sa.EV_DoFloor(line, FloorMoveType.RaiseFloorCrush); line.Special = 0; break; case 57: // Ceiling Crush Stop sa.EV_CeilingCrushStop(line); line.Special = 0; break; case 58: // Raise Floor 24 sa.EV_DoFloor(line, FloorMoveType.RaiseFloor24); line.Special = 0; break; case 59: // Raise Floor 24 And Change sa.EV_DoFloor(line, FloorMoveType.RaiseFloor24AndChange); line.Special = 0; break; case 104: // Turn lights off in sector(tag) sa.EV_TurnTagLightsOff(line); line.Special = 0; break; case 108: // Blazing Door Raise (faster than TURBO!) sa.EV_DoDoor(line, VlDoorType.BlazeRaise); line.Special = 0; break; case 109: // Blazing Door Open (faster than TURBO!) sa.EV_DoDoor(line, VlDoorType.BlazeOpen); line.Special = 0; break; case 100: // Build Stairs Turbo 16 sa.EV_BuildStairs(line, StairType.Turbo16); line.Special = 0; break; case 110: // Blazing Door Close (faster than TURBO!) sa.EV_DoDoor(line, VlDoorType.BlazeClose); line.Special = 0; break; case 119: // Raise floor to nearest surr. floor sa.EV_DoFloor(line, FloorMoveType.RaiseFloorToNearest); line.Special = 0; break; case 121: // Blazing PlatDownWaitUpStay sa.EV_DoPlat(line, PlatformType.BlazeDwus, 0); line.Special = 0; break; case 124: // Secret EXIT //G_SecretExitLevel(); break; case 125: // TELEPORT MonsterONLY if (thing.Player == null) { sa.EV_Teleport(line, side, thing); line.Special = 0; } break; case 130: // Raise Floor Turbo sa.EV_DoFloor(line, FloorMoveType.RaiseFloorTurbo); line.Special = 0; break; case 141: // Silent Ceiling Crush & Raise sa.EV_DoCeiling(line, CeilingMoveType.SilentCrushAndRaise); line.Special = 0; break; // RETRIGGERS. All from here till end. case 72: // Ceiling Crush sa.EV_DoCeiling(line, CeilingMoveType.LowerAndCrush); break; case 73: // Ceiling Crush and Raise sa.EV_DoCeiling(line, CeilingMoveType.CrushAndRaise); break; case 74: // Ceiling Crush Stop sa.EV_CeilingCrushStop(line); break; case 75: // Close Door sa.EV_DoDoor(line, VlDoorType.Close); break; case 76: // Close Door 30 sa.EV_DoDoor(line, VlDoorType.Close30ThenOpen); break; case 77: // Fast Ceiling Crush & Raise sa.EV_DoCeiling(line, CeilingMoveType.FastCrushAndRaise); break; case 79: // Lights Very Dark sa.EV_LightTurnOn(line, 35); break; case 80: // Light Turn On - brightest near sa.EV_LightTurnOn(line, 0); break; case 81: // Light Turn On 255 sa.EV_LightTurnOn(line, 255); break; case 82: // Lower Floor To Lowest sa.EV_DoFloor(line, FloorMoveType.LowerFloorToLowest); break; case 83: // Lower Floor sa.EV_DoFloor(line, FloorMoveType.LowerFloor); break; case 84: // LowerAndChange sa.EV_DoFloor(line, FloorMoveType.LowerAndChange); break; case 86: // Open Door sa.EV_DoDoor(line, VlDoorType.Open); break; case 87: // Perpetual Platform Raise sa.EV_DoPlat(line, PlatformType.PerpetualRaise, 0); break; case 88: // PlatDownWaitUp sa.EV_DoPlat(line, PlatformType.DownWaitUpStay, 0); break; case 89: // Platform Stop sa.EV_StopPlat(line); break; case 90: // Raise Door sa.EV_DoDoor(line, VlDoorType.Normal); break; case 91: // Raise Floor sa.EV_DoFloor(line, FloorMoveType.RaiseFloor); break; case 92: // Raise Floor 24 sa.EV_DoFloor(line, FloorMoveType.RaiseFloor24); break; case 93: // Raise Floor 24 And Change sa.EV_DoFloor(line, FloorMoveType.RaiseFloor24AndChange); break; case 94: // Raise Floor Crush sa.EV_DoFloor(line, FloorMoveType.RaiseFloorCrush); break; case 95: // Raise floor to nearest height // and change texture. sa.EV_DoPlat(line, PlatformType.RaiseToNearestAndChange, 0); break; case 96: // Raise floor to shortest texture height // on either side of lines. sa.EV_DoFloor(line, FloorMoveType.RaiseToTexture); break; case 97: // TELEPORT! sa.EV_Teleport(line, side, thing); break; case 98: // Lower Floor (TURBO) sa.EV_DoFloor(line, FloorMoveType.TurboLower); break; case 105: // Blazing Door Raise (faster than TURBO!) sa.EV_DoDoor(line, VlDoorType.BlazeRaise); break; case 106: // Blazing Door Open (faster than TURBO!) sa.EV_DoDoor(line, VlDoorType.BlazeOpen); break; case 107: // Blazing Door Close (faster than TURBO!) sa.EV_DoDoor(line, VlDoorType.BlazeClose); break; case 120: // Blazing PlatDownWaitUpStay. sa.EV_DoPlat(line, PlatformType.BlazeDwus, 0); break; case 126: // TELEPORT MonsterONLY. if (thing.Player == null) { sa.EV_Teleport(line, side, thing); } break; case 128: // Raise To Nearest Floor sa.EV_DoFloor(line, FloorMoveType.RaiseFloorToNearest); break; case 129: // Raise Floor Turbo sa.EV_DoFloor(line, FloorMoveType.RaiseFloorTurbo); break; } }
public void Make(Fixed frac, Mobj thing) { this.frac = frac; this.thing = thing; this.line = null; }