private static void ReadSidesOrThrow(MapData map, MapComponents components) { ByteReader reader = ByteReader.From(ByteOrder.Little, components.Sidedefs.Value.Data); int count = reader.Length / BytesPerSide; for (int index = 0; index < count; index++) { MapSidedef sidedef = new MapSidedef(index) { Offset = new Vec2I(reader.Short(), reader.Short()), UpperTexture = reader.StringWithoutNulls(8), LowerTexture = reader.StringWithoutNulls(8), MiddleTexture = reader.StringWithoutNulls(8), SectorID = reader.UShort() }; if (!sidedef.SectorID.InRangeExclusive(0, map.Sectors.Count)) { throw new Exception($"Sidedef {index} has out of range sector: {sidedef.SectorID}"); } map.Sidedefs.Add(sidedef); } }
/// <summary> /// Reads the map components and tries to generate the map. /// </summary> /// <param name="components">The map components.</param> /// <param name="map">The map that was generated, or null if this /// returns false.</param> /// <returns>True on success, false on failure.</returns> public static bool TryRead(MapComponents components, out MapData map) { switch (components.MapType) { case MapType.Doom: if (DoomMapReader.TryRead(components, out map)) { return(true); } break; case MapType.Hexen: // TODO break; case MapType.UDMF: // TODO break; default: Debug.Assert(false, $"Unknown map type: {components.MapType}"); break; } map = null; return(false); }
/// <summary> /// Reads the map components and tries to parse a doom map. /// </summary> /// <param name="components">The map components.</param> /// <param name="map">The map that was generated, or null if this /// returns false.</param> /// <returns>True on success, false on failure.</returns> public static bool TryRead(MapComponents components, out MapData map) { if (!components.IsValid() || components.MapType != MapType.Doom) { map = null; return(false); } try { map = new MapData(components.Name); ReadVerticesOrThrow(map, components); ReadSectorsOrThrow(map, components); ReadSidesOrThrow(map, components); ReadLinesOrThrow(map, components); ReadThingsOrThrow(map, components); return(true); } catch { map = null; return(false); } }
static GameObject CreateFromResource(string itemName, string holderName, bool unique = false) { if (unique) { GameObject o = GameObject.Find(MapComponents.FixName(itemName)); if (o != null) { Debug.LogError(itemName + " already exists!"); Selection.activeGameObject = o; return(null); } } GameObject obj = Instantiate(Resources.Load <GameObject>(itemName)); obj.name = itemName; obj.transform.position = GetSpawnPos(); if (holderName != null && holderName.Length > 0) { GameObject holder = GameObject.Find(holderName); if (holder == null) { holder = new GameObject(holderName); } obj.transform.SetParent(holder.transform); } Selection.activeGameObject = obj; return(obj); }
static GameObject Create(string itemName, string icon, string holderName, bool unique = false) { if (unique) { GameObject o = MapComponents.FindFixed(itemName); if (o != null) { Debug.LogError(itemName + " already exists!"); Selection.activeGameObject = o; return(null); } } GameObject obj = new GameObject(itemName); obj.transform.position = GetSpawnPos(); SetIcon(obj, icon); if (holderName != null && holderName.Length > 0) { GameObject holder = GameObject.Find(holderName); if (holder == null) { holder = new GameObject(holderName); } obj.transform.SetParent(holder.transform); } Selection.activeGameObject = obj; return(obj); }
void CoreUI() { GUILayout.Space(5); if (MapComponents.FindFixed("StartPad") == null) { if (FoldoutButton("Start Pad", 1)) { CreateStartPad(); } } else { FoldoutLabel("<color=green>Start Pad in Scene.</color>", 1); } if (MapComponents.FindFixed("EndPad") == null) { if (FoldoutButton("End Pad", 1)) { CreateEndPad(); } } else { FoldoutLabel("<color=green>End Pad in Scene.</color>", 1); } if (MapComponents.FindFixed("LevelBounds") == null) { if (FoldoutButton("Level Bounds", 1)) { CreateLvlBounds(); } } else { if (FoldoutButton("Recalculate Level Bounds", 1)) { UpdateLevelBounds(); } } if (FindObjectOfType <LevelTiming>() == null) { if (FoldoutButton("Level Timing", 1)) { CreateTimingObj(); } } else { FoldoutLabel("<color=green>Level Timing in Scene.</color>", 1); } GUILayout.Space(5); }
private static void ReadVerticesOrThrow(MapData map, MapComponents components) { ByteReader reader = ByteReader.From(ByteOrder.Little, components.Vertices.Value.Data); int count = reader.Length / BytesPerVertex; for (int index = 0; index < count; index++) { MapVertex vertex = new MapVertex(index, reader.Short(), reader.Short()); map.Vertices.Add(vertex); } }
bool EnsureMapComponentsLoaded() { if (mapComp == null) { mapComp = Resources.Load <MapComponents>("MapComponents"); } if (mapComp == null) { Debug.Log("Could not find MapComponent in Resources folder"); return(false); } return(true); }
void GameplayUI() { int gemCount = MapComponents.GetNumOf("Gem"); FoldoutLabel("Pickups", 1); GUILayout.Space(2); if (FoldoutButton("Gem", 1)) { CreateGem(); } if (FoldoutButton("Super Jump", 1)) { CreateSJ(); } if (FoldoutButton("Super Speed", 1)) { CreateSS(); } if (FoldoutButton("Feather Fall", 1)) { CreateFF(); } if (FoldoutButton("Time Travel", 1)) { CreateTT(); } if (FoldoutButton("Trophy", 1)) { CreateTrophy(); } GUILayout.Space(2); FoldoutLabel("Gems: <color=#0085ff>" + gemCount + "</color>", 1); GUILayout.Space(10); FoldoutLabel("Interactive", 1); GUILayout.Space(2); if (FoldoutButton("Bumper", 1)) { CreateBumper(); } if (FoldoutButton("Checkpoint", 1)) { CreateCheckpoint(); } if (FoldoutButton("Tutorial", 1)) { CreateTutorial(); } GUILayout.Space(5); }
private static void ReadLinesOrThrow(MapData map, MapComponents components) { ByteReader reader = ByteReader.From(ByteOrder.Little, components.Linedefs.Value.Data); int count = reader.Length / BytesPerLine; for (int index = 0; index < count; index++) { MapLinedef linedef = new MapLinedef(index) { StartVertex = reader.UShort(), EndVertex = reader.UShort() }; ushort flags = reader.UShort(); ushort type = reader.UShort(); ushort sectorTag = reader.UShort(); SetLineSpecial(linedef, flags, type, sectorTag); linedef.FrontSide = reader.UShort(); int backID = reader.UShort(); if (backID != NoSidedef) { linedef.BackSide = backID; } if (!linedef.StartVertex.InRangeExclusive(0, map.Vertices.Count)) { throw new Exception($"Line {index} has out of range start vertex: {linedef.StartVertex}"); } if (!linedef.EndVertex.InRangeExclusive(0, map.Vertices.Count)) { throw new Exception($"Line {index} has out of range start vertex: {linedef.EndVertex}"); } if (!linedef.FrontSide.InRangeExclusive(0, map.Sidedefs.Count)) { throw new Exception($"Line {index} has out of range front sidedef: {linedef.FrontSide}"); } if (linedef.BackSide != null && !linedef.FrontSide.InRangeExclusive(0, map.Sidedefs.Count)) { throw new Exception($"Line {index} has out of range back sidedef: {linedef.BackSide.Value}"); } map.Linedefs.Add(linedef); } }
private static void ReadThingsOrThrow(MapData map, MapComponents components) { ByteReader reader = ByteReader.From(ByteOrder.Little, components.Things.Value.Data); int count = reader.Length / BytesPerThing; for (int index = 0; index < count; index++) { MapThing thing = new MapThing(index); float x = new Fixed(reader.Short(), 0).Float(); float y = new Fixed(reader.Short(), 0).Float(); thing.Position = (x, y); thing.AngleDegrees = reader.UShort(); thing.EditorID = reader.UShort(); SetThingFlags(thing, reader.UShort()); map.Things.Add(thing); } }
static void UpdateLevelBounds() { BoxCollider bc = null; GameObject bounds = MapComponents.FindFixed("LevelBounds"); if (bounds != null) { bc = bounds.GetComponent <BoxCollider>(); } if (bc != null) { Bounds b = new Bounds(Vector3.zero, Vector3.zero); foreach (Collider r in FindObjectsOfType <MeshCollider>()) { b.Encapsulate(r.bounds); } bounds.transform.position = b.center + (Vector3.up * 10); bc.center = Vector3.zero; bc.size = b.size + new Vector3(10, 20, 10); } }
private static void ReadSectorsOrThrow(MapData map, MapComponents components) { ByteReader reader = ByteReader.From(ByteOrder.Little, components.Sectors.Value.Data); int count = reader.Length / BytesPerSector; for (int index = 0; index < count; index++) { MapSector sector = new MapSector(index) { FloorHeight = reader.Short(), CeilingHeight = reader.Short(), FloorTexture = reader.StringWithoutNulls(8).ToUpper(), CeilingTexture = reader.StringWithoutNulls(8).ToUpper(), LightLevel = reader.Short() }; SetSpecialBits(sector, reader.UShort()); sector.Tag = reader.UShort(); map.Sectors.Add(sector); } }
// Serialize prefab state; return true if we did it because we can skip // the rest of normal processing in that case. bool SerializePrefab(GameObject go, LevelObject lo) { if (IsSafeToBake(go)) { return(false); } // If it only has one component which is a light, we can bail - it's the // sun which is extracted in another way. if (go.GetComponents <Component>().Length == 2 && go.GetComponent <Light>() != null) { return(false); } if (MapComponents.FixName(go.name) == "CheckPoint" || MapComponents.FixName(go.name) == "LevelBounds" || go.GetComponent <TutorialMessage>() != null) { lo.prefabItem = GetPrefabID(MapComponents.FixName(go.name), null); return(true); } int validChildren = 0; for (int i = 0; i < go.transform.childCount; i++) { if (go.transform.GetChild(i).GetComponent <IgnoreObject>() == null) { validChildren++; } } if (validChildren == 0 && go.GetComponents <Component>().Length < 2) { lo.prefabItem = GetPrefabID(go.name, null); return(true); } return(false); }
LevelObject SerializeGameObject(GameObject go, bool rejectStatic = true) { var lo = new LevelObject(); lo.name = MapComponents.FixName(go.name); go.name = lo.name; SerializeTransform(go, lo); SerializeTutorial(go, lo); SerializeBoxCollider(go, lo); SerializeMisc(go, lo); SerializeMover(go, lo); if (SerializePrefab(go, lo)) { return(lo); } SerializeMesh(go, lo, rejectStatic); bool skipChildren; bool doKeep = SerializeKnownComponents(go, lo, out skipChildren); lo.LargestChildVertexCount = lo.mesh != null ? lo.mesh.vertexCount : 0; for (var i = 0; i < go.transform.childCount; i++) { var child = go.transform.GetChild(i); if (skipChildren) { continue; } if (child.gameObject.activeInHierarchy == false) { continue; } if (IsGameObjectPrunable(child.gameObject)) { continue; } var result = SerializeGameObject(go.transform.GetChild(i).gameObject); if (result == null) { continue; } lo.children.Add(result); lo.LargestChildVertexCount = Mathf.Max(lo.LargestChildVertexCount, lo.LargestChildVertexCount); } // Bail if we are empty and have no children. if (lo.children.Count == 0 && lo.mesh.vertexCount == 0 && (lo.prefabItem == null || lo.prefabItem == "") && !doKeep) { return(null); } return(lo); }
public IEnumerator <MapComponents> GetEnumerator() { IEntry lastEntry = null; bool makingMap = false; MapComponents components = new MapComponents(mapName); foreach (IEntry entry in wad) { bool isMapEntry = IsMapEntry(entry.Path.Name); if (makingMap) { if (isMapEntry) { components.Track(entry); } else { makingMap = false; if (components.IsValid()) { yield return(components); } components = new MapComponents(mapName); glLevelName = ""; } } else if (isMapEntry) { if (lastEntry != null) { glLevelName = $"GL_{lastEntry.Path.Name}"; // This is a way of checking if our 'hacky override' to // support external map naming should be done or not. If // there is no level name to override (empty string for the // name) then we know we should use the marker name. if (mapName.Empty) { components = new MapComponents(lastEntry.Path.Name); } } // It is the case that we could have a map with no marker // entry at the beginning. Such a case is a malformed map // and the builder will know what to do here if the last // entry is null. components.TrackMapMarker(lastEntry); components.Track(entry); makingMap = true; } lastEntry = entry; } // If we run out of entries but have a map that is potentially done // yet not processed, return it. if (components.IsValid()) { yield return(components); } }
public static void BakeScene() { hasResult = false; var assembly = Assembly.GetAssembly(typeof(SceneView)); var type = assembly.GetType("UnityEditor.LogEntries"); var method = type.GetMethod("Clear"); method.Invoke(new object(), null); LevelSerializer.failCause = ""; Debug.Log("Starting Level Export"); if (MapComponents.GetNumOf("SpawnPoint") == 0) { if (MapComponents.GetNumOf("StartPad") != 1) { LevelSerializer.failCause = "Singleplayer Level needs one StartPad!"; } if (MapComponents.GetNumOf("EndPad") != 1) { LevelSerializer.failCause = "Singleplayer Level needs one EndPad!"; } if (FindObjectsOfType <LevelTiming>().Length != 1) { LevelSerializer.failCause = "Singleplayer Level needs one Level Times object!"; } } else { if (MapComponents.GetNumOf("StartPad") > 0) { LevelSerializer.failCause = "Multiplayer Maps can't have StartPads."; } if (MapComponents.GetNumOf("EndPad") > 0) { LevelSerializer.failCause = "Multiplayer Maps can't have EndPads."; } if (FindObjectsOfType <LevelTiming>().Length > 0) { LevelSerializer.failCause = "Multiplayer Maps can't have timers."; } } if (MapComponents.GetNumOf("LevelBounds") != 1) { LevelSerializer.failCause = "Level needs one Level Bounds!"; } else { GameObject bounds = MapComponents.FindFixed("LevelBounds"); BoxCollider box = bounds.GetComponent <BoxCollider>(); if (box.size.x > 4096 || box.size.y > 4096 || box.size.z > 4096) { LevelSerializer.failCause = "Map is too large! Ensure leve bounds dimensions are under 4096."; } } var serializer = new LevelSerializer(); ByteStream levelBits = new ByteStream(); if (LevelSerializer.failCause.Length == 0) { serializer.Serialize(ref levelBits); } if (LevelSerializer.failCause.Length == 0) { string filePath = "Assets/" + LevelSerializer.GetCurrentSceneLevelId() + ".level"; FileStream file; if (!File.Exists(filePath)) { file = File.Create(filePath); } else { file = File.Open(filePath, FileMode.Truncate, FileAccess.Write); } file.Write(levelBits.Buffer, 0, levelBits.Position); file.Close(); Debug.Log("<color=green>Level Exported:</color> " + filePath); } else { Debug.Log("<color=#ff3232>Export Failed:</color> " + LevelSerializer.failCause); } hasResult = true; }