diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/commands/CommandResetDungeons.java b/src/main/java/StevenDimDoors/mod_pocketDim/commands/CommandResetDungeons.java index aad0671..69eaace 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/commands/CommandResetDungeons.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/commands/CommandResetDungeons.java @@ -1,9 +1,10 @@ package StevenDimDoors.mod_pocketDim.commands; import java.util.ArrayList; +import java.util.HashSet; +import java.util.Stack; import net.minecraft.entity.player.EntityPlayer; -import net.minecraftforge.common.DimensionManager; import StevenDimDoors.mod_pocketDim.core.DimLink; import StevenDimDoors.mod_pocketDim.core.LinkTypes; import StevenDimDoors.mod_pocketDim.core.NewDimData; @@ -31,55 +32,73 @@ public class CommandResetDungeons extends DDCommandBase { if (command.length > 0) { - return DDCommandResult.TOO_FEW_ARGUMENTS; + return DDCommandResult.TOO_MANY_ARGUMENTS; + } + + int id; + int resetCount = 0; + int dungeonCount = 0; + HashSet deletedDimensions = new HashSet(); + ArrayList loadedDungeons = new ArrayList(); + + // Copy the list of dimensions to iterate over the copy. Otherwise, + // we would trigger an exception by modifying the original list. + ArrayList dimensions = new ArrayList(); + for (NewDimData dimension : PocketManager.getDimensions()) + { + dimensions.add(dimension); } - int dungeonCount = 0; - int resetCount = 0; - ArrayList dimsToDelete = new ArrayList(); - ArrayList dimsToFix = new ArrayList(); - - for (NewDimData data : PocketManager.getDimensions()) + // Iterate over the list of dimensions. Check which ones are dungeons. + // If a dungeon is found, try to delete it. If it can't be deleted, + // then it must be loaded and needs to be updated to prevent bugs. + for (NewDimData dimension : dimensions) { - - if(DimensionManager.getWorld(data.id())==null&&data.isDungeon()) + if (dimension.isDungeon()) { - resetCount++; dungeonCount++; - dimsToDelete.add(data.id()); - } - else if(data.isDungeon()) - { - dimsToFix.add(data.id()); - dungeonCount++; - for(DimLink link : data.links()) + id = dimension.id(); + if (PocketManager.deletePocket(dimension, true)) { - if(link.linkType()==LinkTypes.REVERSE) + resetCount++; + deletedDimensions.add(id); + } + else + { + loadedDungeons.add(dimension); + } + } + } + + // Modify the loaded dungeons to prevent bugs + for (NewDimData dungeon : loadedDungeons) + { + // Find top-most loaded dungeons and update their parents. + // They will automatically update their children. + // Dungeons with non-dungeon parents don't need to be fixed. + if (dungeon.parent() == null) + { + dungeon.setParentToRoot(); + } + + // Links to any deleted dungeons must be replaced + for (DimLink link : dungeon.links()) + { + if (link.hasDestination() && deletedDimensions.contains(link.destination().getDimension())) + { + if (link.linkType() == LinkTypes.DUNGEON) { - data.createLink(link.source(), LinkTypes.DUNGEON_EXIT, link.orientation()); + dungeon.createLink(link.source(), LinkTypes.DUNGEON, link.orientation()); } - if(link.linkType()==LinkTypes.DUNGEON) + else if (link.linkType() == LinkTypes.REVERSE) { - data.createLink(link.source(), LinkTypes.DUNGEON, link.orientation()); + dungeon.createLink(link.source(), LinkTypes.DUNGEON_EXIT, link.orientation()); } } } } - - for(Integer dimID:dimsToDelete) - { - PocketManager.deletePocket(PocketManager.getDimensionData(dimID), true); - } - /** - * temporary workaround - */ - for(Integer dimID: dimsToFix) - { - PocketManager.getDimensionData(dimID).setParentToRoot(); - } - //TODO- for some reason the parent field of loaded dimenions get reset to null if I call .setParentToRoot() before I delete the pockets. - //TODO implement blackList - //Notify the user of the results + + // Notify the user of the results sendChat(sender,("Reset complete. " + resetCount + " out of " + dungeonCount + " dungeons were reset.")); return DDCommandResult.SUCCESS; } diff --git a/src/main/java/StevenDimDoors/mod_pocketDim/core/NewDimData.java b/src/main/java/StevenDimDoors/mod_pocketDim/core/NewDimData.java index 15182ed..8ed8d83 100644 --- a/src/main/java/StevenDimDoors/mod_pocketDim/core/NewDimData.java +++ b/src/main/java/StevenDimDoors/mod_pocketDim/core/NewDimData.java @@ -4,6 +4,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Random; +import java.util.Stack; import java.util.TreeMap; import StevenDimDoors.mod_pocketDim.watcher.ClientLinkData; @@ -516,11 +517,42 @@ public abstract class NewDimData */ public void setParentToRoot() { + // Update this dimension's information + if (parent != null) + { + parent.children.remove(this); + } this.depth = 1; this.parent = this.root; this.root.children.add(this); this.root.modified = true; this.modified = true; + if (this.isDungeon) + { + this.packDepth = calculatePackDepth(this.parent, this.dungeon); + } + + // Update the depths for child dimensions using a depth-first traversal + Stack ordering = new Stack(); + ordering.addAll(this.children); + + while (!ordering.isEmpty()) + { + NewDimData current = ordering.pop(); + current.resetDepth(); + ordering.addAll(current.children); + } + } + + private void resetDepth() + { + // We assume that this is only applied to dimensions with parents + this.depth = this.parent.depth + 1; + if (this.isDungeon) + { + this.packDepth = calculatePackDepth(this.parent, this.dungeon); + } + this.modified = true; } public static int calculatePackDepth(NewDimData parent, DungeonData current)