public override void StartQuest() { // If the quest has been started, continue nodeCanvas.missionName = findRoot().missionName; if (nodeCanvas.missionName == null) { Debug.LogError("A mission wasn't given a name. Every mission must have a name."); return; } // add objective list TaskManager.objectiveLocations.Add(nodeCanvas.missionName, new List <TaskManager.ObjectiveLocation>()); if (lastCheckpointName == (nodeCanvas.missionName + "_complete")) { // Retroactively add all parts from the completed quest as parts obtained by the player. if (PlayerCore.Instance) { foreach (var node in nodeCanvas.nodes) { if (node is StartTaskNode) { var startTask = node as StartTaskNode; if (startTask.partReward) { EntityBlueprint.PartInfo part = new EntityBlueprint.PartInfo(); part.partID = startTask.partID; part.abilityID = startTask.partAbilityID; part.tier = startTask.partTier; part.secondaryData = startTask.partSecondaryData; part = PartIndexScript.CullToPartIndexValues(part); if (!PlayerCore.Instance.cursave.partsObtained.Contains(part)) { PlayerCore.Instance.cursave.partsObtained.Add(part); } if (!PlayerCore.Instance.cursave.partsSeen.Contains(part)) { PlayerCore.Instance.cursave.partsSeen.Add(part); } } } } } return; } base.StartQuest(); SectorManager.OnSectorLoad += ((val) => { if (traverserLimiterDelegate != null) { traverserLimiterDelegate.Invoke(val); } }); if (currentNode == null) { TaskManager.Instance.RemoveTraverser(this); } }
IEnumerator WriteWorldCo(string path) { Debug.Log("Writing world..."); // Folder paths var canvasPlaceholderPath = System.IO.Path.Combine(Application.streamingAssetsPath, "CanvasPlaceholder"); var entityPlaceholderPath = System.IO.Path.Combine(Application.streamingAssetsPath, "EntityPlaceholder"); var wavePlaceholderPath = System.IO.Path.Combine(Application.streamingAssetsPath, "WavePlaceholder"); var factionPlaceholderPath = System.IO.Path.Combine(Application.streamingAssetsPath, "FactionPlaceholder"); var resourcePlaceholderPath = System.IO.Path.Combine(Application.streamingAssetsPath, "ResourcePlaceholder"); // Reinitialize node editor NodeEditor.ReInit(false); saveState = 1; yield return(null); sectors = new List <Sector>(); var items = cursor.placedItems; var wrappers = cursor.sectors; foreach (var wrapper in wrappers) { sectors.Add(wrapper.sector); } int minX = int.MaxValue; int maxY = int.MinValue; // Get the world bounds foreach (var sector in sectors) { if (sector.bounds.x < minX) { minX = sector.bounds.x; } if (sector.bounds.y > maxY) { maxY = sector.bounds.y; } } // ensure spawn point in some sector if (sectors.TrueForAll(sector => !sector.bounds.contains(cursor.spawnPoint.position))) { Debug.LogError("Spawn point not in sector bounds. Abort."); yield break; } // set up items and platforms int ID = 0; Dictionary <Sector, List <Sector.LevelEntity> > sectEnts = new Dictionary <Sector, List <Sector.LevelEntity> >(); Dictionary <Sector, List <string> > sectTargetIDS = new Dictionary <Sector, List <string> >(); foreach (var sector in sectors) { sectEnts.Add(sector, new List <Sector.LevelEntity>()); sectTargetIDS.Add(sector, new List <string>()); sector.tiles = new List <GroundPlatform.Tile>(); } // Add background spawns to part index partData.Clear(); foreach (var sector in sectors) { if (sector.backgroundSpawns != null) { foreach (var spawn in sector.backgroundSpawns) { AttemptAddShellCoreParts(spawn.entity, sector.sectorName, path); } } } Dictionary <string, string> itemSectorsByID = new Dictionary <string, string>(); foreach (var item in items) { Sector container = GetSurroundingSector(item.pos, item.dimension); if (container == null) { savingLevelScreen.SetActive(false); saveState = 3; Debug.LogError("No container for item. Abort."); yield break; } switch (item.type) { case ItemType.Platform: var index = GetPlatformIndices(container, item.pos); container.tiles.Add(new GroundPlatform.Tile() { pos = new Vector2Int(index.Item2, index.Item1), type = (byte)item.placeablesIndex, rotation = (byte)(((int)item.obj.transform.rotation.eulerAngles.z / 90) % 4) }); break; case ItemType.Other: case ItemType.Decoration: case ItemType.DecorationWithMetadata: case ItemType.Flag: Sector.LevelEntity ent = new Sector.LevelEntity(); if (cursor.characters.TrueForAll((WorldData.CharacterData x) => { return(x.ID != item.ID); })) { // Debug.Log(item.ID + " is not a character. " + ID); if (item.type == ItemType.DecorationWithMetadata) { int parsedId; if (item.assetID == "shard_rock" && int.TryParse(item.ID, out parsedId)) { Debug.LogError($"Shard in sector {container.sectorName} has a numeric ID. Abort."); yield break; } ent.blueprintJSON = item.shellcoreJSON; } int test; if (string.IsNullOrEmpty(item.ID) || int.TryParse(item.ID, out test)) { ent.ID = (ID++).ToString(); } else { ent.ID = item.ID; if (itemSectorsByID.ContainsKey(ent.ID)) { savingLevelScreen.SetActive(false); saveState = 4; Debug.LogError($"Two items in sectors {container.sectorName} and {itemSectorsByID[ent.ID]} were issued the same custom ID ({ent.ID}). Abort."); yield break; } else { itemSectorsByID.Add(ent.ID, container.sectorName); } } // Debug.Log(container.sectorName + " " + ent.ID); } else { // TODO: adjust faction Debug.Log("Character found. Adjusting ID and name"); ent.ID = item.ID; } // you can choose to give any object a custom name if (!string.IsNullOrEmpty(item.name)) { ent.name = item.name; } else { ent.name = item.obj.name; } ent.faction = item.faction; ent.position = item.pos; ent.assetID = item.assetID; ent.vendingID = item.vendingID; ent.patrolPath = item.patrolPath; if ((item.isTarget && container.type != Sector.SectorType.SiegeZone) || (container.type == Sector.SectorType.SiegeZone && item.assetID == "outpost_blueprint" && item.faction == 0) || (container.type == Sector.SectorType.SiegeZone && item.assetID == "bunker_blueprint" && item.faction == 0)) { sectTargetIDS[container].Add(ent.ID); } var charExists = cursor.characters.Exists(ch => ch.ID == ent.ID); if (ent.assetID == "shellcore_blueprint" || charExists) { if (container.type != Sector.SectorType.SiegeZone && !sectTargetIDS[container].Contains(ent.ID)) { sectTargetIDS[container].Add(ent.ID); } ent.blueprintJSON = item.shellcoreJSON; if (!charExists) { AttemptAddShellCoreParts(ent, container.sectorName, path); } } else if (ent.assetID == "trader_blueprint") { ent.blueprintJSON = item.shellcoreJSON; // Attempt to add trader parts into index. if (string.IsNullOrEmpty(ent.blueprintJSON)) { var dialogueDataPath = System.IO.Path.Combine(canvasPlaceholderPath, ent.ID, ".dialoguedata"); if (System.IO.File.Exists(dialogueDataPath)) { var XMLImport = new XMLImportExport(); var canvas = XMLImport.Import(dialogueDataPath) as DialogueCanvas; foreach (var node in canvas.nodes) { if (node is EndDialogue endDialogue && endDialogue.openTrader) { ShipBuilder.TraderInventory traderInventory = JsonUtility.FromJson <ShipBuilder.TraderInventory>(endDialogue.traderJSON); AttemptAddPartArray(traderInventory.parts, container.sectorName); } } } else { ent.blueprintJSON = JsonUtility.ToJson(new ShipBuilder.TraderInventory()); // Maybe make this error message more descriptive. Debug.LogWarning($"Trader has neither default trader JSON nor an associated dialogue file named '{ent.ID}.dialoguedata'. Replacing with empty trader inventory."); } } else { ShipBuilder.TraderInventory traderInventory = JsonUtility.FromJson <ShipBuilder.TraderInventory>(ent.blueprintJSON); AttemptAddPartArray(traderInventory.parts, container.sectorName); } } else if (ent.assetID == "groundcarrier_blueprint" || ent.assetID == "carrier_blueprint" || ent.assetID == "outpost_blueprint" || ent.assetID == "bunker_blueprint" || ent.assetID == "missile_station" || ent.assetID == "air_weapon_station") { ent.blueprintJSON = item.shellcoreJSON; } sectEnts[container].Add(ent); break; default: break; } } if (!System.IO.Directory.Exists(canvasPlaceholderPath)) { System.IO.Directory.CreateDirectory(canvasPlaceholderPath); } // create world data WorldData wdata = ScriptableObject.CreateInstance <WorldData>(); wdata.sectorMappings = new List <WorldData.OffloadMappings>(); wdata.dialogueMappings = new List <WorldData.OffloadMappings>(); // Add reward parts from tasks. if (System.IO.Directory.Exists(canvasPlaceholderPath)) { foreach (var canvasPath in System.IO.Directory.GetFiles(canvasPlaceholderPath)) { var pathWithoutExtension = System.IO.Path.GetFileNameWithoutExtension(canvasPath); var XMLImport = new XMLImportExport(); switch (System.IO.Path.GetExtension(canvasPath)) { case ".taskdata": var questCanvas = XMLImport.Import(canvasPath) as QuestCanvas; string missionName = null; foreach (var node in questCanvas.nodes) { if (node is StartMissionNode startMission) { missionName = startMission.missionName; } } foreach (var node in questCanvas.nodes) { if (node is StartTaskNode startTask && startTask.partReward) { EntityBlueprint.PartInfo part = new EntityBlueprint.PartInfo(); part.partID = startTask.partID; part.abilityID = startTask.partAbilityID; part.tier = startTask.partTier; part.secondaryData = startTask.partSecondaryData; part = PartIndexScript.CullToPartIndexValues(part); AddPart(part, missionName); } } if (missionName != null) { File.Move(canvasPath, System.IO.Path.Combine(System.IO.Path.GetDirectoryName(canvasPath), missionName + ".taskdata")); } break; case ".sectordata": var sectorCanvas = XMLImport.Import(canvasPath) as SectorCanvas; var sectorName = new SectorTraverser(sectorCanvas).findRoot().sectorName; wdata.sectorMappings.Add(new WorldData.OffloadMappings(sectorName, pathWithoutExtension)); //var newPath = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(canvasPath), sectorName + ".sectordata"); //if (!File.Exists(newPath)) // File.Move(canvasPath, newPath); break; case ".dialoguedata": var dialogueCanvas = XMLImport.Import(canvasPath) as DialogueCanvas; var entityID = new DialogueTraverser(dialogueCanvas).findRoot().EntityID; wdata.dialogueMappings.Add(new WorldData.OffloadMappings(entityID, pathWithoutExtension)); //File.Move(canvasPath, System.IO.Path.Combine(System.IO.Path.GetDirectoryName(canvasPath), entityID + ".dialoguedata")); break; } } } // try to write out resources. Factions are obtained from the FactionManager if (!System.IO.Directory.Exists(factionPlaceholderPath)) { System.IO.Directory.CreateDirectory(factionPlaceholderPath); } var resourceTxtPath = System.IO.Path.Combine(Application.streamingAssetsPath, "ResourceDataPlaceholder.txt"); if (System.IO.File.Exists(resourceTxtPath)) { // first, extract all the lines without the factions. List <string> lines = new List <string>(); using (StreamReader sr = File.OpenText(resourceTxtPath)) { string s; bool onFactions = false; while ((s = sr.ReadLine()) != null) { if (ResourceManager.resourceHeaders.Any(header => s.ToLower().StartsWith(header))) { if (s.ToLower().StartsWith("factions:")) { onFactions = true; } else { onFactions = false; } } if (!onFactions) { lines.Add(s); } } } // we then reconstruct the factions tab with FM data lines.Add("factions:"); foreach (var faction in factionManager.factions) { // avoid default factions if (FactionManager.defaultFactions.Contains(faction)) { continue; } lines.Add($"{faction.factionName}:Factions/{faction.factionName}.json"); } File.WriteAllLines(resourceTxtPath, lines); } // calculate land platform pathfinding directions foreach (var sector in sectors) { if (sector.tiles != null && sector.tiles.Count > 0) { sector.platforms = LandPlatformGenerator.DivideToPlatforms(sector.tiles); List <string> data = new List <string>(); foreach (var plat in sector.platforms) { data.Add(plat.Encode()); } sector.platformData = data.ToArray(); } else { sector.platforms = new GroundPlatform[0]; sector.platformData = new string[0]; } } // write all sectors into a file if (!System.IO.Directory.Exists(path)) { System.IO.Directory.CreateDirectory(path); } // Delete all unnecessary files if (System.IO.Directory.Exists(path)) { string[] resPaths = ResourceManager.Instance.GetFileNames(path); for (int i = 0; i < resPaths.Length; i++) { resPaths[i] = resPaths[i].Replace('\\', '/'); Debug.Log("Res path: " + resPaths[i]); } string[] directories = System.IO.Directory.GetDirectories(path); foreach (var dir in directories) { bool del = true; foreach (var f in System.IO.Directory.GetFiles(dir)) { Debug.Log("File in dir: " + System.IO.Path.Combine(dir, f)); if (!resPaths.Contains(System.IO.Path.Combine(dir, f).Replace('\\', '/'))) { System.IO.File.Delete(f); } del = false; } if (del) { System.IO.Directory.Delete(dir); } } string[] files = System.IO.Directory.GetFiles(path); foreach (var file in files) { string f = file.Replace('\\', '/'); if ((!resPaths.Contains(f) && f != System.IO.Path.Combine(path, "ResourceData.txt").Replace('\\', '/')) || legacyFactionFilesToDelete.Contains(file)) { System.IO.File.Delete(file); } } } wdata.initialSpawn = cursor.spawnPoint.position; wdata.defaultCharacters = cursor.characters.ToArray(); wdata.defaultBlueprintJSON = blueprintField.text; wdata.author = authorField.text; wdata.description = descriptionField.text; wdata.partIndexDataArray = partData.ToArray(); string wdjson = JsonUtility.ToJson(wdata); System.IO.File.WriteAllText(System.IO.Path.Combine(path, "world.worlddata"), wdjson); if (File.Exists(System.IO.Path.Combine(path, "ResourceData.txt"))) { File.Delete(System.IO.Path.Combine(path, "ResourceData.txt")); } if (File.Exists(resourceTxtPath)) { File.Copy(resourceTxtPath, System.IO.Path.Combine(path, "ResourceData.txt")); } TryCopy(canvasPlaceholderPath, System.IO.Path.Combine(path, "Canvases")); TryCopy(entityPlaceholderPath, System.IO.Path.Combine(path, "Entities")); TryCopy(wavePlaceholderPath, System.IO.Path.Combine(path, "Waves")); TryCopy(factionPlaceholderPath, System.IO.Path.Combine(path, "Factions")); TryCopy(resourcePlaceholderPath, System.IO.Path.Combine(path, "Resources")); foreach (var sector in sectors) { if (string.IsNullOrEmpty(sector.sectorName)) { sector.sectorName = GetDefaultName(sector, minX, maxY); } if (sector.hasMusic && string.IsNullOrEmpty(sector.musicID)) { sector.musicID = GetDefaultMusic(sector.type); } sector.entities = sectEnts[sector].ToArray(); sector.targets = sectTargetIDS[sector].ToArray(); // sector.backgroundColor = SectorColors.colors[(int)sector.type]; SectorData data = new SectorData(); data.sectorjson = JsonUtility.ToJson(sector); data.platformjson = ""; // For backwards compatibility... string output = JsonUtility.ToJson(data); string sectorPath = System.IO.Path.Combine(path, sector.sectorName + ".json"); System.IO.File.WriteAllText(sectorPath, output); } Debug.Log("JSON written to location: " + path); Debug.Log($"Index size: {partData.Count}"); savingLevelScreen.SetActive(false); saveState = 2; if (OnSectorSaved != null) { OnSectorSaved.Invoke(); } }
/// <summary> /// Helper method for death animation and state changing /// </summary> protected virtual void OnDeath() { entityBody.velocity = Vector2.zero; // set death, interactibility and immobility IsInvisible = false; Collider2D[] colliders = GetComponentsInChildren <Collider2D>(true); for (int i = 0; i < colliders.Length; i++) { colliders[i].enabled = true; } foreach (var ability in abilities) { if (ability) { ability.SetDestroyed(true); } } interactible = false; isDead = true; SetIntoCombat(); deathTimer = 0; // reset death timer transform.Find("Minimap Image").GetComponent <SpriteRenderer>().enabled = false; // remove from minimap AudioManager.PlayClipByID("clip_explosion1", transform.position); // Roll on each part if (!FactionManager.IsAllied(0, faction) && !(this as PlayerCore) && this is ShellCore shellCore && shellCore.GetCarrier() == null) { // extract non-shell parts var selectedParts = parts.FindAll(p => p != shell); if (selectedParts.Count > 0) { foreach (var part in selectedParts) { if (Random.value < partDropRate) { part.SetCollectible(true); if (sectorMngr) { AIData.strayParts.Add(part); } } } } } DetachAllParts(); var BZM = SectorManager.instance?.GetComponent <BattleZoneManager>(); if (lastDamagedBy is PlayerCore player) { player.AddCredits(Random.Range(1, 5)); if (this as ShellCore && !FactionManager.IsAllied(0, faction)) { foreach (var part in blueprint.parts) { player.cursave.partsSeen.Add(PartIndexScript.CullToPartIndexValues(part)); } } } if (OnEntityDeath != null) { OnEntityDeath.Invoke(this, lastDamagedBy); } if (BZM != null) { BZM.UpdateCounters(); } GameObject deathExplosion = Instantiate(deathExplosionPrefab, transform.position, Quaternion.identity); }
IEnumerator WriteWorldCo(string path) { Debug.Log("Writing world..."); // Folder paths var canvasPlaceholderPath = Application.streamingAssetsPath + "\\CanvasPlaceholder"; var entityPlaceholderPath = Application.streamingAssetsPath + "\\EntityPlaceholder"; var wavePlaceholderPath = Application.streamingAssetsPath + "\\WavePlaceholder"; // Reinitialize node editor NodeEditor.ReInit(false); saveState = 1; yield return(null); sectors = new List <Sector>(); var items = cursor.placedItems; var wrappers = cursor.sectors; foreach (var wrapper in wrappers) { sectors.Add(wrapper.sector); } int minX = int.MaxValue; int maxY = int.MinValue; // Get the world bounds foreach (var sector in sectors) { if (sector.bounds.x < minX) { minX = sector.bounds.x; } if (sector.bounds.y > maxY) { maxY = sector.bounds.y; } } // ensure spawn point in some sector if (sectors.TrueForAll(sector => !sector.bounds.contains(cursor.spawnPoint.position))) { Debug.LogError("Spawn point not in sector bounds. Abort."); yield break; } // set up items and platforms int ID = 0; Dictionary <Sector, List <Sector.LevelEntity> > sectEnts = new Dictionary <Sector, List <Sector.LevelEntity> >(); Dictionary <Sector, List <string> > sectTargetIDS = new Dictionary <Sector, List <string> >(); foreach (var sector in sectors) { sectEnts.Add(sector, new List <Sector.LevelEntity>()); sectTargetIDS.Add(sector, new List <string>()); sector.tiles = new List <GroundPlatform.Tile>(); } // Add background spawns to part index partData.Clear(); foreach (var sector in sectors) { if (sector.backgroundSpawns != null) { foreach (var spawn in sector.backgroundSpawns) { AttemptAddShellCoreParts(spawn.entity, sector.sectorName, path); } } } Dictionary <string, string> itemSectorsByID = new Dictionary <string, string>(); foreach (var item in items) { Sector container = GetSurroundingSector(item.pos); if (container == null) { savingLevelScreen.SetActive(false); saveState = 3; Debug.LogError("No container for item. Abort."); yield break; } switch (item.type) { case ItemType.Platform: var index = GetPlatformIndices(container, item.pos); container.tiles.Add(new GroundPlatform.Tile() { pos = new Vector2Int(index.Item2, index.Item1), type = (byte)item.placeablesIndex, rotation = (byte)(((int)item.obj.transform.rotation.eulerAngles.z / 90) % 4), directions = new Dictionary <Vector2Int, byte>() }); break; case ItemType.Other: case ItemType.Decoration: case ItemType.Flag: Sector.LevelEntity ent = new Sector.LevelEntity(); if (cursor.characters.TrueForAll((WorldData.CharacterData x) => { return(x.ID != item.ID); })) { // Debug.Log(item.ID + " is not a character. " + ID); int test; if (item.ID == null || item.ID == "" || int.TryParse(item.ID, out test)) { ent.ID = ID++ + ""; } else { ent.ID = item.ID; if (itemSectorsByID.ContainsKey(ent.ID)) { savingLevelScreen.SetActive(false); saveState = 4; Debug.LogError("Two items in sectors " + container.sectorName + " and " + itemSectorsByID[ent.ID] + " were issued the same custom ID. Abort."); yield break; } else { itemSectorsByID.Add(ent.ID, container.sectorName); } } // Debug.Log(container.sectorName + " " + ent.ID); } else { // TODO: adjust faction Debug.Log("Character found. Adjusting ID and name"); ent.ID = item.ID; } // you can choose to give any object a custom name if (item.name != null && item.name != "") { ent.name = item.name; } else { ent.name = item.obj.name; } ent.faction = item.faction; ent.position = item.pos; ent.assetID = item.assetID; ent.vendingID = item.vendingID; ent.patrolPath = item.patrolPath; if ((item.isTarget && container.type != Sector.SectorType.SiegeZone) || (container.type == Sector.SectorType.SiegeZone && item.assetID == "outpost_blueprint" && item.faction == 0) || (container.type == Sector.SectorType.SiegeZone && item.assetID == "bunker_blueprint" && item.faction == 0)) { sectTargetIDS[container].Add(ent.ID); } var charExists = cursor.characters.Exists(ch => ch.ID == ent.ID); if (ent.assetID == "shellcore_blueprint" || charExists) { if (container.type != Sector.SectorType.SiegeZone && !sectTargetIDS[container].Contains(ent.ID)) { sectTargetIDS[container].Add(ent.ID); } ent.blueprintJSON = item.shellcoreJSON; if (!charExists) { AttemptAddShellCoreParts(ent, container.sectorName, path); } } else if (ent.assetID == "trader_blueprint") { ent.blueprintJSON = item.shellcoreJSON; // Attempt to add trader parts into index. if (ent.blueprintJSON == null || ent.blueprintJSON == "") { var dialogueDataPath = $"{canvasPlaceholderPath}\\{ent.ID}.dialoguedata"; if (System.IO.File.Exists(dialogueDataPath)) { var XMLImport = new XMLImportExport(); var canvas = XMLImport.Import(dialogueDataPath) as DialogueCanvas; foreach (var node in canvas.nodes) { if (node is EndDialogue) { var endDialogue = node as EndDialogue; if (endDialogue.openTrader) { ShipBuilder.TraderInventory traderInventory = JsonUtility.FromJson <ShipBuilder.TraderInventory>(endDialogue.traderJSON); Debug.LogError(container.sectorName + "end dialog"); AttemptAddPartArray(traderInventory.parts, container.sectorName); } } } } else { ent.blueprintJSON = JsonUtility.ToJson(new ShipBuilder.TraderInventory()); // Maybe make this error message more descriptive. Debug.LogWarning($"Trader has neither default trader JSON nor an associated dialogue file named '{ent.ID}.dialoguedata'. Replacing with empty trader inventory."); } } else { ShipBuilder.TraderInventory traderInventory = JsonUtility.FromJson <ShipBuilder.TraderInventory>(ent.blueprintJSON); AttemptAddPartArray(traderInventory.parts, container.sectorName); } } else if (ent.assetID == "groundcarrier_blueprint" || ent.assetID == "carrier_blueprint" || ent.assetID == "outpost_blueprint" || ent.assetID == "bunker_blueprint") { ent.blueprintJSON = item.shellcoreJSON; } sectEnts[container].Add(ent); break; default: break; } } if (!System.IO.Directory.Exists(canvasPlaceholderPath)) { System.IO.Directory.CreateDirectory(canvasPlaceholderPath); } // Add reward parts from tasks. if (System.IO.Directory.Exists(canvasPlaceholderPath)) { foreach (var canvasPath in System.IO.Directory.GetFiles(canvasPlaceholderPath)) { if (System.IO.Path.GetExtension(canvasPath) == ".taskdata") { var XMLImport = new XMLImportExport(); var canvas = XMLImport.Import(canvasPath) as QuestCanvas; string missionName = null; foreach (var node in canvas.nodes) { if (node is StartMissionNode) { var startMission = node as StartMissionNode; missionName = startMission.missionName; } } foreach (var node in canvas.nodes) { if (node is StartTaskNode) { var startTask = node as StartTaskNode; if (startTask.partReward) { EntityBlueprint.PartInfo part = new EntityBlueprint.PartInfo(); part.partID = startTask.partID; part.abilityID = startTask.partAbilityID; part.tier = startTask.partTier; part.secondaryData = startTask.partSecondaryData; part = PartIndexScript.CullToPartIndexValues(part); AddPart(part, missionName); } } } } } } // calculate land platform pathfinding directions foreach (var sector in sectors) { if (sector.tiles != null && sector.tiles.Count > 0) { sector.platforms = LandPlatformGenerator.DivideToPlatforms(sector.tiles); List <string> data = new List <string>(); foreach (var plat in sector.platforms) { plat.GenerateDirections(); data.Add(plat.Encode()); } sector.platformData = data.ToArray(); } else { sector.platforms = new GroundPlatform[0]; sector.platformData = new string[0]; } } // write all sectors into a file if (!System.IO.Directory.Exists(path)) { System.IO.Directory.CreateDirectory(path); } // Delete all unnecessary files if (System.IO.Directory.Exists(path)) { string[] resPaths = ResourceManager.Instance.GetFileNames(path); for (int i = 0; i < resPaths.Length; i++) { resPaths[i] = resPaths[i].Replace('\\', '/'); Debug.Log("Res path: " + resPaths[i]); } string[] directories = System.IO.Directory.GetDirectories(path); foreach (var dir in directories) { bool del = true; foreach (var f in System.IO.Directory.GetFiles(dir)) { Debug.Log("File in dir: " + System.IO.Path.Combine(dir, f)); if (!resPaths.Contains(System.IO.Path.Combine(dir, f).Replace('\\', '/'))) { System.IO.File.Delete(f); del = false; } } if (del) { System.IO.Directory.Delete(dir); } } string[] files = System.IO.Directory.GetFiles(path); foreach (var file in files) { string f = file.Replace('\\', '/'); if (!resPaths.Contains(f) && f != System.IO.Path.Combine(path, "ResourceData.txt").Replace('\\', '/')) { System.IO.File.Delete(file); } } } // create world data WorldData wdata = ScriptableObject.CreateInstance <WorldData>(); wdata.initialSpawn = cursor.spawnPoint.position; wdata.defaultCharacters = cursor.characters.ToArray(); wdata.defaultBlueprintJSON = blueprintField.text; wdata.author = authorField.text; wdata.description = descriptionField.text; wdata.partIndexDataArray = partData.ToArray(); string wdjson = JsonUtility.ToJson(wdata); System.IO.File.WriteAllText(path + "\\world.worlddata", wdjson); TryCopy(canvasPlaceholderPath, path + "\\Canvases\\"); TryCopy(entityPlaceholderPath, path + "\\Entities\\"); TryCopy(wavePlaceholderPath, path + "\\Waves\\"); foreach (var sector in sectors) { if (sector.sectorName == null || sector.sectorName == "") { sector.sectorName = GetDefaultName(sector, minX, maxY); } if (sector.hasMusic && (sector.musicID == null || sector.musicID == "")) { sector.musicID = GetDefaultMusic(sector.type); } sector.entities = sectEnts[sector].ToArray(); sector.targets = sectTargetIDS[sector].ToArray(); // sector.backgroundColor = SectorColors.colors[(int)sector.type]; SectorData data = new SectorData(); data.sectorjson = JsonUtility.ToJson(sector); data.platformjson = ""; // For backwards compatibility... string output = JsonUtility.ToJson(data); string sectorPath = path + "\\." + sector.sectorName + ".json"; System.IO.File.WriteAllText(sectorPath, output); } Debug.Log("JSON written to location: " + path); Debug.Log($"Index size: {partData.Count}"); savingLevelScreen.SetActive(false); saveState = 2; if (OnSectorSaved != null) { OnSectorSaved.Invoke(); } }