public static Track LoadTrack(string trackfile, string trackname) { var ret = new Track(); ret.Filename = trackfile; ret.Name = trackname; ret.Remount = false; var addedlines = new Dictionary <int, StandardLine>(); var location = trackfile; var bytes = File.ReadAllBytes(location); using (var file = new MemoryStream(bytes)) { var br = new BinaryReader(file); int magic = br.ReadInt32(); if (magic != ('T' | 'R' << 8 | 'K' << 16 | 0xF2 << 24)) { throw new TrackIO.TrackLoadException("File was read as .trk but it is not valid"); } byte version = br.ReadByte(); string[] features = ReadString(br).Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries); if (version != 1) { throw new TrackIO.TrackLoadException("Unsupported version"); } bool redmultipier = false; bool scenerywidth = false; bool supports61 = false; bool songinfo = false; bool ignorabletrigger = false; for (int i = 0; i < features.Length; i++) { switch (features[i]) { case TrackFeatures.redmultiplier: redmultipier = true; break; case TrackFeatures.scenerywidth: scenerywidth = true; break; case TrackFeatures.six_one: supports61 = true; break; case TrackFeatures.songinfo: songinfo = true; break; case TrackFeatures.ignorable_trigger: ignorabletrigger = true; break; case TrackFeatures.zerostart: ret.ZeroStart = true; break; case TrackFeatures.remount: ret.Remount = true; break; case TrackFeatures.frictionless: ret.frictionless = true; break; default: throw new TrackIO.TrackLoadException("Unsupported feature"); } } if (supports61) { ret.SetVersion(61); } else { ret.SetVersion(62); } if (songinfo) { var song = br.ReadString(); try { var strings = song.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries); var fn = Program.UserDirectory + "Songs" + Path.DirectorySeparatorChar + strings[0]; if (File.Exists(fn)) { if (AudioService.LoadFile(ref fn)) { ret.Song = new Song(Path.GetFileName(fn), float.Parse(strings[1], Program.Culture)); } else { Program.NonFatalError("An unknown error occured trying to load the song file"); } } } catch { // ignored } } ret.StartOffset = new Vector2d(br.ReadDouble(), br.ReadDouble()); var lines = br.ReadInt32(); List <LineTrigger> linetriggers = new List <LineTrigger>(); for (var i = 0; i < lines; i++) { GameLine l; byte ltype = br.ReadByte(); var lt = (LineType)(ltype & 0x1F);//we get 5 bits var inv = (ltype >> 7) != 0; var lim = (ltype >> 5) & 0x3; var ID = -1; var prvID = -1; var nxtID = -1; var multiplier = 1; var linewidth = 1f; LineTrigger tr = null; if (redmultipier) { if (lt == LineType.Red) { multiplier = br.ReadByte(); } } if (lt == LineType.Blue || lt == LineType.Red) { if (ignorabletrigger) { tr = new LineTrigger(); bool zoomtrigger = br.ReadBoolean(); if (zoomtrigger) { tr.ZoomTrigger = true; var target = br.ReadSingle(); var frames = br.ReadInt16(); tr.ZoomFrames = frames; tr.ZoomTarget = target; } else { tr = null; } } ID = br.ReadInt32(); if (lim != 0) { prvID = br.ReadInt32(); //ignored nxtID = br.ReadInt32(); //ignored } } if (lt == LineType.Scenery) { if (scenerywidth) { float b = br.ReadByte(); linewidth = b / 10f; } } var x1 = br.ReadDouble(); var y1 = br.ReadDouble(); var x2 = br.ReadDouble(); var y2 = br.ReadDouble(); if (tr != null) { tr.LineID = ID; linetriggers.Add(tr); } switch (lt) { case LineType.Blue: var bl = new StandardLine(new Vector2d(x1, y1), new Vector2d(x2, y2), inv); bl.ID = ID; bl.Extension = (StandardLine.Ext)lim; l = bl; break; case LineType.Red: var rl = new RedLine(new Vector2d(x1, y1), new Vector2d(x2, y2), inv); rl.ID = ID; rl.Extension = (StandardLine.Ext)lim; if (redmultipier) { rl.Multiplier = multiplier; } l = rl; break; case LineType.Scenery: l = new SceneryLine(new Vector2d(x1, y1), new Vector2d(x2, y2)) { Width = linewidth }; break; default: throw new TrackIO.TrackLoadException("Invalid line type at ID " + ID); } if (l is StandardLine) { if (!addedlines.ContainsKey(l.ID)) { addedlines[ID] = (StandardLine)l; ret.AddLine(l); } } else { ret.AddLine(l); } } ret.Triggers = TriggerConverter.ConvertTriggers(linetriggers, ret); if (br.BaseStream.Position != br.BaseStream.Length) { var meta = br.ReadInt32(); if (meta == ('M' | 'E' << 8 | 'T' << 16 | 'A' << 24)) { ParseMetadata(ret, br); } else { throw new TrackIO.TrackLoadException("Expected metadata tag but got " + meta.ToString("X8")); } } } return(ret); }
public SelectedLineWindow(Gwen.Controls.ControlBase parent, MainWindow glgame, GameLine line) : base(parent, DefaultTitle) { game = glgame; _ownerline = line; this.MakeModal(true); this.Height = 190; this.Width = 150; ControlBase container1 = new ControlBase(this); container1.Dock = Gwen.Pos.Fill; if (line.Type != LineType.Scenery) { var stl = (StandardLine)line; LabeledCheckBox btn = new LabeledCheckBox(container1); btn.Dock = Gwen.Pos.Top; btn.Text = "Inverse"; btn.IsChecked = stl.inv; btn.CheckChanged += (o, e) => { using (var trk = game.Track.CreateTrackWriter()) { LineChanging(); var copy = (StandardLine)stl.Clone(); var caller = (LabeledCheckBox)o; copy.inv = caller.IsChecked; copy.CalculateConstants(); trk.ReplaceLine(stl, copy); game.Track.NotifyTrackChanged(); game.Invalidate(); } }; LineTrigger tr = (LineTrigger)stl.Trigger ?? new LineTrigger(); var gb = new PropertyTree(container1); gb.Height = 110; gb.Dock = Gwen.Pos.Top; PropertyTree table = new PropertyTree(gb); table.Name = "triggers"; table.Dock = Gwen.Pos.Fill; table.Height = 100; var row = table.Add("Zoom Trigger"); var enabled = row.Add("Enabled", new Gwen.Controls.Property.Check(table)); enabled.Value = tr.Zoomtrigger ? "1" : "0"; enabled.ValueChanged += (o, e) => { using (var trk = game.Track.CreateTrackWriter()) { LineChanging(); trk.DisableExtensionUpdating(); var copy = (StandardLine)stl.Clone(); if (enabled.Value == "1") { tr.Zoomtrigger = true; tr.ZoomTarget = float.Parse(((PropertyRow)container1.FindChildByName("Zoom", true)).Value); tr.ZoomFrames = int.Parse(((PropertyRow)container1.FindChildByName("ZoomFrames", true)).Value); copy.Trigger = tr; } else { tr.Zoomtrigger = false; if (!tr.Enabled) { copy.Trigger = null; } } trk.ReplaceLine(stl, copy); game.Track.NotifyTrackChanged(); } }; var prop = row.Add("Zoom"); prop.Name = "Zoom"; prop.Value = (enabled.Value == "1" ? tr.ZoomTarget : 1).ToString(); prop.ValueChanged += (o, e) => { var caller = (PropertyRow)o; float val = 0; if (float.TryParse(caller.Value, out val) && val >= 0.1 && val <= 24) { caller.LabelColor = System.Drawing.Color.Black; tr.ZoomTarget = val; } else { caller.LabelColor = System.Drawing.Color.Red; } }; prop = row.Add("Frames"); prop.Name = "ZoomFrames"; prop.Value = (enabled.Value == "1" ? tr.ZoomFrames : 40).ToString(); prop.ValueChanged += (o, e) => { var caller = (PropertyRow)o; int val = 0; if (int.TryParse(caller.Value, out val) && val >= 1 && val < 10000) { caller.LabelColor = System.Drawing.Color.Black; tr.ZoomFrames = val; } else { caller.LabelColor = System.Drawing.Color.Red; } }; } if (line.Type == LineType.Red) { ControlBase optioncontainer = new ControlBase(container1); optioncontainer.Dock = Pos.Top; optioncontainer.Height = 30; var redstl = (RedLine)line; Height += 30; NoDecimalNUD nud = new NoDecimalNUD(optioncontainer); var marg = nud.Margin; marg.Top = 5; marg.Left = marg.Right = 1; marg.Left = 70; marg.Bottom = 10; nud.Margin = marg; nud.Dock = Gwen.Pos.Top; nud.Min = 1; nud.Max = 3; nud.Value = (line as RedLine).Multiplier; nud.ValueChanged += nud_redlinemultiplier_ValueChanged; nud.UserData = line; Label l = new Label(optioncontainer); l.Y = 5; l.Text = "Multiplier"; Height += 25; optioncontainer = new ControlBase(container1); optioncontainer.Dock = Pos.Top; optioncontainer.Height = 30; nud = new NoDecimalNUD(optioncontainer); marg = nud.Margin; marg.Top = 5; marg.Left = marg.Right = 1; marg.Left = 70; marg.Bottom = 10; nud.Margin = marg; nud.Dock = Gwen.Pos.Top; nud.Min = 1; nud.Max = 9999; nud.Value = GetMultiLines(true).Count; nud.ValueChanged += (o, e) => { var val = (int)nud.Value; if (val > 0) { Multiline(val); } }; nud.UserData = line; l = new Label(optioncontainer); l.Y = 5; l.Text = "Multilines"; } Button saveandquit = new Button(container1); saveandquit.Name = "saveandquit"; saveandquit.Disable(); saveandquit.Dock = Pos.Bottom; saveandquit.Text = "Save changes"; saveandquit.Clicked += (o, e) => { if (!saveandquit.IsDisabled) { if (!_closing) { _closing = true; if (_linechanged) { game.Track.UndoManager.EndAction(); } if (!this.IsHidden) { Close(); } } } }; RecurseLayout(Skin); this.MinimumSize = new System.Drawing.Point(Width, Height); game.Cursor = OpenTK.MouseCursor.Default; }
public static Track LoadTrack(string trackfile, string trackname) { var ret = new Track(); ret.Filename = trackfile; ret.Name = trackname; var addedlines = new Dictionary <int, StandardLine>(); var location = trackfile; var bytes = File.ReadAllBytes(location); using (var file = new MemoryStream(bytes)) { var br = new BinaryReader(file); int magic = br.ReadInt32(); if (magic == ('T' | 'R' << 8 | 'K' << 16 | 0xF2 << 24)) { byte version = br.ReadByte(); string[] features = Encoding.ASCII.GetString(br.ReadBytes(br.ReadInt16())).Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries); if (version != 1) { throw new TrackIO.TrackLoadException("Unsupported version"); } bool redmultipier = false; bool scenerywidth = false; bool supports61 = false; bool songinfo = false; bool ignorabletrigger = false; for (int i = 0; i < features.Length; i++) { switch (features[i]) { case "REDMULTIPLIER": redmultipier = true; break; case "SCENERYWIDTH": scenerywidth = true; break; case "6.1": supports61 = true; break; case "SONGINFO": songinfo = true; break; case "IGNORABLE_TRIGGER": ignorabletrigger = true; break; case "ZEROSTART": ret.ZeroStart = true; break; default: throw new TrackIO.TrackLoadException("Unsupported feature"); } } if (supports61) { ret.SetVersion(61); } else { ret.SetVersion(62); } if (songinfo) { var song = br.ReadString(); try { var strings = song.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries); var fn = Program.UserDirectory + "Songs" + Path.DirectorySeparatorChar + strings[0]; if (File.Exists(fn)) { if (AudioService.LoadFile(ref fn)) { Settings.Local.CurrentSong = new Song(Path.GetFileName(fn), float.Parse(strings[1])); Settings.Local.EnableSong = true; } else { Program.NonFatalError("An unknown error occured trying to load the song file"); } } } catch { // ignored } } ret.StartOffset = new Vector2d(br.ReadDouble(), br.ReadDouble()); var lines = br.ReadInt32(); for (var i = 0; i < lines; i++) { GameLine l; byte ltype = br.ReadByte(); var lt = (LineType)(ltype & 0x1F);//we get 5 bits var inv = (ltype >> 7) != 0; var lim = (ltype >> 5) & 0x3; var ID = -1; var prvID = -1; var nxtID = -1; var multiplier = 1; var linewidth = 1f; LineTrigger tr = ignorabletrigger ? new LineTrigger() : null; if (redmultipier) { if (lt == LineType.Red) { multiplier = br.ReadByte(); } } if (lt == LineType.Blue || lt == LineType.Red) { if (ignorabletrigger) { bool zoomtrigger = br.ReadBoolean(); if (zoomtrigger) { tr.Zoomtrigger = true; var target = br.ReadSingle(); var frames = br.ReadInt16(); tr.ZoomFrames = frames; tr.ZoomTarget = target; } else { tr = null; } } ID = br.ReadInt32(); if (lim != 0) { prvID = br.ReadInt32(); //ignored nxtID = br.ReadInt32(); //ignored } } if (lt == LineType.Scenery) { if (scenerywidth) { float b = br.ReadByte(); linewidth = b / 10f; } } var x1 = br.ReadDouble(); var y1 = br.ReadDouble(); var x2 = br.ReadDouble(); var y2 = br.ReadDouble(); switch (lt) { case LineType.Blue: var bl = new StandardLine(new Vector2d(x1, y1), new Vector2d(x2, y2), inv); bl.ID = ID; bl.Extension = (StandardLine.Ext)lim; l = bl; bl.Trigger = tr; break; case LineType.Red: var rl = new RedLine(new Vector2d(x1, y1), new Vector2d(x2, y2), inv); rl.ID = ID; rl.Extension = (StandardLine.Ext)lim; if (redmultipier) { rl.Multiplier = multiplier; } l = rl; rl.Trigger = tr; break; case LineType.Scenery: l = new SceneryLine(new Vector2d(x1, y1), new Vector2d(x2, y2)) { Width = linewidth }; break; default: throw new TrackIO.TrackLoadException("Invalid line type at ID " + ID); } if (l is StandardLine) { if (!addedlines.ContainsKey(l.ID)) { addedlines[ID] = (StandardLine)l; ret.AddLine(l); } } else { ret.AddLine(l); } } } } return(ret); }
public static List <GameTrigger> ConvertTriggers(List <LineTrigger> triggers, Track track) { List <GameTrigger> gametriggers = new List <GameTrigger>(); const int minute = 40 * 60; int lasthit = 0; var rider = track.GetStart(); var hittest = new HitTestManager(); int i = 1; int hitframe = -1; LineTrigger activetrigger = null; float zoom = track.StartZoom; GameTrigger newtrigger = null; do { var collisions = new LinkedList <int>(); rider = rider.Simulate( track.Grid, track.Bones, collisions); hittest.AddFrame(collisions); LineTrigger hittrigger = null; foreach (var lineid in collisions) { foreach (var trigger in triggers) { if (trigger.LineID == lineid) { hittrigger = trigger; } } } if (hittrigger != null && hittrigger != activetrigger) { if (activetrigger != null) { newtrigger.ZoomTarget = zoom; newtrigger.End = i; gametriggers.Add(newtrigger); } hitframe = i; activetrigger = hittrigger; newtrigger = new GameTrigger() { TriggerType = TriggerType.Zoom, Start = i }; } if (activetrigger != null) { var delta = i - hitframe; if (!activetrigger.Activate(delta, ref zoom)) { newtrigger.ZoomTarget = zoom; newtrigger.End = i; gametriggers.Add(newtrigger); activetrigger = null; } } if (hittest.HasUniqueCollisions(i)) { lasthit = i; } i++; }while (i - lasthit < (minute * 2)); // be REALLY sure, 2 minutes. return(gametriggers); }
public static void ApplyLinedefBehavior() { Transform holder = new GameObject("DynamicMeshes").transform; holder.transform.SetParent(GameManager.Instance.transform); int index = -1; foreach (Linedef l in linedefs) { index++; if (l.lineType == 0) { continue; } switch (l.lineType) { default: Debug.Log("Linedef " + index + " has unknown type (" + l.lineType + ")"); break; //common door case 1: case 26: //keycard doors case 27: case 28: { if (l.TopFrontObject == null) { break; } if (l.Back == null) { break; } l.Back.Sector.ceilingObject.transform.SetParent(holder); Door1Controller lc = l.TopFrontObject.AddComponent <Door1Controller>(); if (l.lineType == 26) { lc.requiresKeycard = 0; } if (l.lineType == 27) { lc.requiresKeycard = 1; } if (l.lineType == 28) { lc.requiresKeycard = 2; } SlowRepeatableDoorController sc = l.Back.Sector.ceilingObject.GetComponent <SlowRepeatableDoorController>(); if (sc == null) { sc = l.Back.Sector.ceilingObject.AddComponent <SlowRepeatableDoorController>(); } sc.Init(l.Back.Sector); lc.sectorController = sc; l.Back.Sector.Dynamic = true; } break; //single use door, walk trigger case 2: { if (!Sector.TaggedSectors.ContainsKey(l.lineTag)) { break; } List <SlowOneshotDoorController> linked = new List <SlowOneshotDoorController>(); foreach (Sector sector in Sector.TaggedSectors[l.lineTag]) { sector.ceilingObject.transform.SetParent(holder); SlowOneshotDoorController sc = sector.ceilingObject.GetComponent <SlowOneshotDoorController>(); if (sc == null) { sc = sector.ceilingObject.gameObject.AddComponent <SlowOneshotDoorController>(); sc.Init(sector); } linked.Add(sc); sector.Dynamic = true; } BoxCollider mc = Mesher.CreateLineTriggerCollider( l, Mathf.Min(l.Front.Sector.minimumFloorHeight, l.Back.Sector.minimumFloorHeight), Mathf.Max(l.Front.Sector.maximumCeilingHeight, l.Back.Sector.maximumCeilingHeight), "Tag_" + l.lineTag + "_trigger", holder ); if (mc == null) { Debug.LogError("Linedef " + index + " could not create trigger. Type(" + l.lineType + ")"); break; } mc.isTrigger = true; LineTrigger lt = mc.gameObject.AddComponent <LineTrigger>(); lt.TriggerAction = (c) => { PlayerThing player = c.GetComponent <PlayerThing>(); if (player == null) { return; } foreach (SlowOneshotDoorController lc in linked) { if (lc.CurrentState == SlowOneshotDoorController.State.Closed) { lc.CurrentState = SlowOneshotDoorController.State.Opening; } } }; } break; //stairbuilder, walktrigger case 8: { if (!Sector.TaggedSectors.ContainsKey(l.lineTag)) { break; } List <StairbuilderSlow> linked = new List <StairbuilderSlow>(); foreach (Sector sector in Sector.TaggedSectors[l.lineTag]) { sector.floorObject.transform.SetParent(holder); List <Sector> stairSectors = new List <Sector>(); Sector targetSector = sector; int count = 0; bool failed = false; while (!failed) { count++; stairSectors.Add(targetSector); targetSector.Dynamic = true; targetSector.floorObject.transform.SetParent(holder); failed = true; foreach (Sidedef s in targetSector.Sidedefs) { if (s.Line.Back == null) { continue; } if (s.Line.Back.Sector == targetSector) { continue; } if (s.Line.Back.Sector.floorTexture != targetSector.floorTexture) { continue; } if (stairSectors.Contains(s.Line.Back.Sector)) { continue; } targetSector = s.Line.Back.Sector; failed = false; } } StairbuilderSlow sc = sector.floorObject.GetComponent <StairbuilderSlow>(); if (sc == null) { sc = sector.floorObject.gameObject.AddComponent <StairbuilderSlow>(); sc.Init(stairSectors); } linked.Add(sc); } BoxCollider mc = Mesher.CreateLineTriggerCollider( l, Mathf.Min(l.Front.Sector.minimumFloorHeight, l.Back.Sector.minimumFloorHeight), Mathf.Max(l.Front.Sector.maximumCeilingHeight, l.Back.Sector.maximumCeilingHeight), "Tag_" + l.lineTag + "_trigger", holder ); if (mc == null) { Debug.LogError("Linedef " + index + " could not create trigger. Type(" + l.lineType + ")"); break; } mc.isTrigger = true; LineTrigger lt = mc.gameObject.AddComponent <LineTrigger>(); lt.TriggerAction = (c) => { PlayerThing player = c.GetComponent <PlayerThing>(); if (player == null) { return; } foreach (StairbuilderSlow lc in linked) { if (lc.CurrentState == StairbuilderSlow.State.Waiting) { lc.CurrentState = StairbuilderSlow.State.Active; } } }; } break; //donut, switch case 9: { if (!Sector.TaggedSectors.ContainsKey(l.lineTag)) { break; } List <Sector> sectors = Sector.TaggedSectors[l.lineTag]; if (sectors.Count == 0) { break; } sectors[0].floorObject.transform.SetParent(holder); Sector ringSector = null; foreach (Sidedef s in sectors[0].Sidedefs) { if (s.Line.Back == null) { continue; } if (s.Line.Front.Sector == sectors[0]) { ringSector = s.Line.Back.Sector; ringSector.floorObject.transform.SetParent(holder); break; } if (s.Line.Back.Sector == sectors[0]) { ringSector = s.Line.Front.Sector; ringSector.floorObject.transform.SetParent(holder); break; } } if (ringSector == null) { Debug.LogError("MapLoader: Donut9Controller: No ring sector found!"); } Donut9SectorController sc = sectors[0].floorObject.gameObject.AddComponent <Donut9SectorController>(); Donut9LinedefController script = null; if (l.BotFrontObject != null) { script = l.BotFrontObject.AddComponent <Donut9LinedefController>(); } else if (l.MidFrontObject != null) { script = l.MidFrontObject.AddComponent <Donut9LinedefController>(); } if (script != null) { script.sectorController = sc; sc.Init(sectors[0], ringSector); } sectors[0].Dynamic = true; ringSector.Dynamic = true; } break; //level end switch case 11: { if (l.BotFrontObject != null) { End11LinedefController lc = l.BotFrontObject.AddComponent <End11LinedefController>(); lc.CurrentTexture = l.Front.tLow; l.BotFrontObject.transform.SetParent(holder); } else if (l.MidFrontObject != null) { End11LinedefController lc = l.MidFrontObject.AddComponent <End11LinedefController>(); lc.CurrentTexture = l.Front.tMid; l.MidFrontObject.transform.SetParent(holder); } } break; //raise floor to next, one use case 20: { List <Floor20SectorController> linked = new List <Floor20SectorController>(); foreach (Sector sector in Sector.TaggedSectors[l.lineTag]) { sector.floorObject.transform.SetParent(holder); Floor20SectorController sc = sector.floorObject.GetComponent <Floor20SectorController>(); if (sc == null) { sc = sector.floorObject.gameObject.AddComponent <Floor20SectorController>(); sc.Init(sector); } linked.Add(sc); sector.Dynamic = true; } if (l.BotFrontObject != null) { if (index == 1020) { l.BotFrontObject.transform.SetParent(GameManager.Instance.TemporaryObjectsHolder); } Floor20LinedefController lc = l.BotFrontObject.AddComponent <Floor20LinedefController>(); lc.sectorControllers = linked; lc.CurrentTexture = l.Front.tLow; l.BotFrontObject.transform.SetParent(holder); } else if (l.MidFrontObject != null) { Floor20LinedefController lc = l.MidFrontObject.AddComponent <Floor20LinedefController>(); lc.sectorControllers = linked; lc.CurrentTexture = l.Front.tMid; l.MidFrontObject.transform.SetParent(holder); } } break; //single use door, pokeable case 31: { if (l.TopFrontObject == null) { break; } if (l.Back == null) { break; } l.Back.Sector.ceilingObject.transform.SetParent(holder); Door31Controller lc = l.TopFrontObject.AddComponent <Door31Controller>(); SlowOneshotDoorController sc = l.Back.Sector.ceilingObject.GetComponent <SlowOneshotDoorController>(); if (sc == null) { sc = l.Back.Sector.ceilingObject.AddComponent <SlowOneshotDoorController>(); } sc.Init(l.Back.Sector); lc.sectorController = sc; l.Back.Sector.Dynamic = true; } break; //make sectors dark, walktrigger case 35: { if (!Sector.TaggedSectors.ContainsKey(l.lineTag)) { break; } BoxCollider mc = Mesher.CreateLineTriggerCollider( l, Mathf.Min(l.Front.Sector.minimumFloorHeight, l.Back.Sector.minimumFloorHeight), Mathf.Max(l.Front.Sector.maximumCeilingHeight, l.Back.Sector.maximumCeilingHeight), "Tag_" + l.lineTag + "_trigger", holder ); if (mc == null) { Debug.LogError("Linedef " + index + " could not create trigger. Type(" + l.lineType + ")"); break; } mc.isTrigger = true; LineTrigger lt = mc.gameObject.AddComponent <LineTrigger>(); lt.TriggerAction = (c) => { if (c.GetComponent <PlayerThing>() == null) { return; } foreach (Sector sector in Sector.TaggedSectors[l.lineTag]) { sector.brightness = (float)35 / 255f; sector.floorObject.ChangeBrightness(sector.brightness); } }; } break; //single use floor lower, walktrigger case 36: { if (!Sector.TaggedSectors.ContainsKey(l.lineTag)) { break; } List <Floor36Controller> linked = new List <Floor36Controller>(); foreach (Sector sector in Sector.TaggedSectors[l.lineTag]) { sector.floorObject.transform.SetParent(holder); Floor36Controller sc = sector.floorObject.GetComponent <Floor36Controller>(); if (sc == null) { sc = sector.floorObject.gameObject.AddComponent <Floor36Controller>(); sc.Init(sector); } linked.Add(sc); sector.Dynamic = true; } BoxCollider mc = Mesher.CreateLineTriggerCollider( l, Mathf.Min(l.Front.Sector.minimumFloorHeight, l.Back.Sector.minimumFloorHeight), Mathf.Max(l.Front.Sector.maximumCeilingHeight, l.Back.Sector.maximumCeilingHeight), "Tag_" + l.lineTag + "_trigger", holder ); if (mc == null) { Debug.LogError("Linedef " + index + " could not create trigger. Type(" + l.lineType + ")"); break; } mc.isTrigger = true; LineTrigger lt = mc.gameObject.AddComponent <LineTrigger>(); lt.TriggerAction = (c) => { PlayerThing player = c.GetComponent <PlayerThing>(); if (player == null) { return; } foreach (Floor36Controller lc in linked) { if (lc.CurrentState == Floor36Controller.State.AtTop) { lc.CurrentState = Floor36Controller.State.Lowering; } } }; } break; //single use door, shootable case 46: { if (l.TopFrontObject == null) { break; } if (l.Back == null) { break; } l.Back.Sector.ceilingObject.transform.SetParent(GameManager.Instance.transform); Door46Controller lc = l.TopFrontObject.AddComponent <Door46Controller>(); SlowOneshotDoorController sc = l.Back.Sector.ceilingObject.GetComponent <SlowOneshotDoorController>(); if (sc == null) { sc = l.Back.Sector.ceilingObject.AddComponent <SlowOneshotDoorController>(); } sc.Init(l.Back.Sector); lc.sectorController = sc; l.Back.Sector.Dynamic = true; } break; //scroll animation, left case 48: { foreach (GameObject g in l.gameObjects) { if (g != null) { g.AddComponent <ScrollLeftAnimation>(); } } } break; //secret level end switch case 51: { if (l.BotFrontObject != null) { End51LinedefController lc = l.BotFrontObject.AddComponent <End51LinedefController>(); lc.CurrentTexture = l.Front.tLow; l.BotFrontObject.transform.SetParent(holder); } else if (l.MidFrontObject != null) { End51LinedefController lc = l.MidFrontObject.AddComponent <End51LinedefController>(); lc.CurrentTexture = l.Front.tMid; l.MidFrontObject.transform.SetParent(holder); } } break; //common lift, pokeable case 62: { if (!Sector.TaggedSectors.ContainsKey(l.lineTag)) { break; } if (l.BotFrontObject == null) { break; } List <Slow3sLiftController> linked = new List <Slow3sLiftController>(); foreach (Sector sector in Sector.TaggedSectors[l.lineTag]) { sector.floorObject.transform.SetParent(holder); Slow3sLiftController script = sector.floorObject.GetComponent <Slow3sLiftController>(); if (script == null) { script = sector.floorObject.gameObject.AddComponent <Slow3sLiftController>(); script.Init(sector); } linked.Add(script); sector.Dynamic = true; } Lift62Controller lc = l.BotFrontObject.AddComponent <Lift62Controller>(); lc.liftControllers = linked; } break; //repeatable door, switch case 63: { if (!Sector.TaggedSectors.ContainsKey(l.lineTag)) { break; } List <SlowRepeatableDoorController> linked = new List <SlowRepeatableDoorController>(); foreach (Sector sector in Sector.TaggedSectors[l.lineTag]) { sector.ceilingObject.transform.SetParent(holder); SlowRepeatableDoorController sc = sector.ceilingObject.GetComponent <SlowRepeatableDoorController>(); if (sc == null) { sc = sector.ceilingObject.AddComponent <SlowRepeatableDoorController>(); sc.Init(sector); } linked.Add(sc); sector.Dynamic = true; } if (l.BotFrontObject != null) { Door63Controller lc = l.BotFrontObject.AddComponent <Door63Controller>(); lc.sectorControllers = linked; lc.CurrentTexture = l.Front.tLow; l.BotFrontObject.transform.SetParent(holder); } else if (l.MidFrontObject != null) { Door63Controller lc = l.MidFrontObject.AddComponent <Door63Controller>(); lc.sectorControllers = linked; lc.CurrentTexture = l.Front.tMid; l.MidFrontObject.transform.SetParent(holder); } } break; //common lift, walktrigger case 88: { if (!Sector.TaggedSectors.ContainsKey(l.lineTag)) { break; } List <Slow3sLiftController> linked = new List <Slow3sLiftController>(); foreach (Sector sector in Sector.TaggedSectors[l.lineTag]) { sector.floorObject.transform.SetParent(holder); Slow3sLiftController sc = sector.floorObject.GetComponent <Slow3sLiftController>(); if (sc == null) { sc = sector.floorObject.gameObject.AddComponent <Slow3sLiftController>(); sc.Init(sector); } linked.Add(sc); sector.Dynamic = true; } BoxCollider mc = Mesher.CreateLineTriggerCollider( l, Mathf.Min(l.Front.Sector.minimumFloorHeight, l.Back.Sector.minimumFloorHeight), Mathf.Max(l.Front.Sector.maximumCeilingHeight, l.Back.Sector.maximumCeilingHeight), "Tag_" + l.lineTag + "_trigger", holder ); if (mc == null) { Debug.LogError("Linedef " + index + " could not create trigger. Type(" + l.lineType + ")"); break; } mc.isTrigger = true; LineTrigger lt = mc.gameObject.AddComponent <LineTrigger>(); lt.TriggerAction = (c) => { foreach (Slow3sLiftController lc in linked) { if (lc.CurrentState == Slow3sLiftController.State.AtTop) { lc.CurrentState = Slow3sLiftController.State.Lowering; } } }; } break; //repeatable door, walktrigger case 90: { if (!Sector.TaggedSectors.ContainsKey(l.lineTag)) { break; } List <SlowRepeatableDoorController> linked = new List <SlowRepeatableDoorController>(); foreach (Sector sector in Sector.TaggedSectors[l.lineTag]) { sector.ceilingObject.transform.SetParent(holder); SlowRepeatableDoorController sc = sector.ceilingObject.GetComponent <SlowRepeatableDoorController>(); if (sc == null) { sc = sector.ceilingObject.gameObject.AddComponent <SlowRepeatableDoorController>(); sc.Init(sector); } linked.Add(sc); sector.Dynamic = true; } BoxCollider mc = Mesher.CreateLineTriggerCollider( l, Mathf.Min(l.Front.Sector.minimumFloorHeight, l.Back.Sector.minimumFloorHeight), Mathf.Max(l.Front.Sector.maximumCeilingHeight, l.Back.Sector.maximumCeilingHeight), "Tag_" + l.lineTag + "_trigger", holder ); if (mc == null) { Debug.LogError("Linedef " + index + " could not create trigger. Type(" + l.lineType + ")"); break; } mc.isTrigger = true; LineTrigger lt = mc.gameObject.AddComponent <LineTrigger>(); lt.TriggerAction = (c) => { PlayerThing player = c.GetComponent <PlayerThing>(); if (player == null) { return; } foreach (SlowRepeatableDoorController lc in linked) { if (lc.CurrentState == SlowRepeatableDoorController.State.Closed) { lc.CurrentState = SlowRepeatableDoorController.State.Opening; } } }; } break; //single use door, switch case 103: { if (!Sector.TaggedSectors.ContainsKey(l.lineTag)) { break; } List <SlowOneshotDoorController> linked = new List <SlowOneshotDoorController>(); foreach (Sector sector in Sector.TaggedSectors[l.lineTag]) { sector.ceilingObject.transform.SetParent(holder); SlowOneshotDoorController sc = sector.ceilingObject.GetComponent <SlowOneshotDoorController>(); if (sc == null) { sc = sector.ceilingObject.AddComponent <SlowOneshotDoorController>(); sc.Init(sector); } linked.Add(sc); sector.Dynamic = true; } if (l.BotFrontObject != null) { Door103Controller lc = l.BotFrontObject.AddComponent <Door103Controller>(); lc.sectorControllers = linked; lc.CurrentTexture = l.Front.tLow; l.BotFrontObject.transform.SetParent(holder); } else if (l.MidFrontObject != null) { Door103Controller lc = l.MidFrontObject.AddComponent <Door103Controller>(); lc.sectorControllers = linked; lc.CurrentTexture = l.Front.tMid; l.MidFrontObject.transform.SetParent(holder); } } break; } } }
public void ApplyLinedefBehavior() { Transform holder = new GameObject("DynamicMeshes").transform; holder.transform.SetParent(transform); foreach (Linedef l in linedefs) { if (l.lineType == 0) { continue; } switch (l.lineType) { default: break; case 1: case 26: //keycard doors case 27: case 28: { if (l.TopFrontObject == null) { break; } l.Back.Sector.ceilingObject.transform.SetParent(holder); Door1LinedefController script = l.TopFrontObject.AddComponent <Door1LinedefController>(); script.Init(l); } break; case 36: { if (!Sector.TaggedSectors.ContainsKey(l.lineTag)) { break; } List <Floor36Controller> linked = new List <Floor36Controller>(); foreach (Sector sector in Sector.TaggedSectors[l.lineTag]) { sector.floorObject.transform.SetParent(holder); Floor36Controller script = sector.floorObject.GetComponent <Floor36Controller>(); if (script == null) { script = sector.floorObject.AddComponent <Floor36Controller>(); script.Init(sector); } linked.Add(script); } BoxCollider mc = Mesher.Instance.CreateLineCollider( l, Mathf.Max(l.Front.Sector.floorHeight, l.Back.Sector.floorHeight), Mathf.Min(l.Front.Sector.ceilingHeight, l.Back.Sector.ceilingHeight), "Tag_" + l.lineTag + "_trigger", holder ); if (mc == null) { break; } mc.isTrigger = true; LineTrigger lt = mc.gameObject.AddComponent <LineTrigger>(); lt.TriggerAction = (c) => { if (c.gameObject != WadLoader.Instance.PlayerObject) { return; } foreach (Floor36Controller lc in linked) { if (lc.CurrentState == Floor36Controller.State.AtTop) { lc.CurrentState = Floor36Controller.State.Lowering; } } }; } break; case 48: { foreach (GameObject g in l.gameObjects) { if (g != null) { g.AddComponent <ScrollLeftAnimation>(); } } } break; case 88: { if (!Sector.TaggedSectors.ContainsKey(l.lineTag)) { break; } List <Platform88Controller> linked = new List <Platform88Controller>(); foreach (Sector sector in Sector.TaggedSectors[l.lineTag]) { // hacky handling for a scene reload - I don't actually understand why we're getting here *after* we've cleared the linedefs it's looping through if (sector.floorObject == null) { return; } sector.floorObject.transform.SetParent(holder); Platform88Controller script = sector.floorObject.GetComponent <Platform88Controller>(); if (script == null) { script = sector.floorObject.AddComponent <Platform88Controller>(); script.Init(sector); } linked.Add(script); } BoxCollider mc = Mesher.Instance.CreateLineCollider( l, Mathf.Max(l.Front.Sector.floorHeight, l.Back.Sector.floorHeight), Mathf.Min(l.Front.Sector.ceilingHeight, l.Back.Sector.ceilingHeight), "Tag_" + l.lineTag + "_trigger", holder ); if (mc == null) { break; } mc.isTrigger = true; LineTrigger lt = mc.gameObject.AddComponent <LineTrigger>(); lt.TriggerAction = (c) => { if (c.gameObject != WadLoader.Instance.PlayerObject) { return; } foreach (Platform88Controller lc in linked) { if (lc.CurrentState == Platform88Controller.State.AtTop) { lc.CurrentState = Platform88Controller.State.Lowering; lc.waitTime = 4f; } } }; } break; } } }