diff --git a/core/src/mindustry/content/TechTree.java b/core/src/mindustry/content/TechTree.java index dcb1a53b82..199c81a5f8 100644 --- a/core/src/mindustry/content/TechTree.java +++ b/core/src/mindustry/content/TechTree.java @@ -709,7 +709,7 @@ public class TechTree implements ContentList{ /** Item requirements for this content. */ public ItemStack[] requirements; /** Requirements that have been fulfilled. Always the same length as the requirement array. */ - public final ItemStack[] finishedRequirements; + public ItemStack[] finishedRequirements; /** Extra objectives needed to research this. */ public Seq objectives = new Seq<>(); /** Nodes that depend on this node. */ @@ -720,14 +720,8 @@ public class TechTree implements ContentList{ this.parent = parent; this.content = content; - this.requirements = requirements; this.depth = parent == null ? 0 : parent.depth + 1; - this.finishedRequirements = new ItemStack[requirements.length]; - - //load up the requirements that have been finished if settings are available - for(int i = 0; i < requirements.length; i++){ - finishedRequirements[i] = new ItemStack(requirements[i].item, Core.settings == null ? 0 : Core.settings.getInt("req-" + content.name + "-" + requirements[i].item.name)); - } + setupRequirements(requirements); var used = new ObjectSet(); @@ -742,6 +736,16 @@ public class TechTree implements ContentList{ all.add(this); } + public void setupRequirements(ItemStack[] requirements){ + this.requirements = requirements; + this.finishedRequirements = new ItemStack[requirements.length]; + + //load up the requirements that have been finished if settings are available + for(int i = 0; i < requirements.length; i++){ + finishedRequirements[i] = new ItemStack(requirements[i].item, Core.settings == null ? 0 : Core.settings.getInt("req-" + content.name + "-" + requirements[i].item.name)); + } + } + /** Resets finished requirements and saves. */ public void reset(){ for(ItemStack stack : finishedRequirements){ diff --git a/core/src/mindustry/core/Control.java b/core/src/mindustry/core/Control.java index bb4c1082b1..93fa1e68a2 100644 --- a/core/src/mindustry/core/Control.java +++ b/core/src/mindustry/core/Control.java @@ -247,12 +247,12 @@ public class Control implements ApplicationListener, Loadable{ saves.load(); } - /** Automatically unlocks things with no requirements. */ + /** Automatically unlocks things with no requirements and no locked parents. */ void checkAutoUnlocks(){ if(net.client()) return; for(TechNode node : TechTree.all){ - if(!node.content.unlocked() && node.requirements.length == 0 && !node.objectives.contains(o -> !o.complete())){ + if(!node.content.unlocked() && (node.parent == null || node.parent.content.unlocked()) && node.requirements.length == 0 && !node.objectives.contains(o -> !o.complete())){ node.content.unlock(); } } diff --git a/core/src/mindustry/mod/ContentParser.java b/core/src/mindustry/mod/ContentParser.java index 2227e6134f..6738257d79 100644 --- a/core/src/mindustry/mod/ContentParser.java +++ b/core/src/mindustry/mod/ContentParser.java @@ -121,6 +121,11 @@ public class ContentParser{ return sound; }); put(Objectives.Objective.class, (type, data) -> { + if(data.isString()){ + var cont = locateAny(data.asString()); + if(cont == null) throw new IllegalArgumentException("Unknown objective content: " + data.asString()); + return new Research((UnlockableContent)cont); + } var oc = resolve(data.getString("type", ""), SectorComplete.class); data.remove("type"); Objectives.Objective obj = make(oc); @@ -544,6 +549,16 @@ public class ContentParser{ return first != null ? first : Vars.content.getByName(type, currentMod.name + "-" + name); } + private T locateAny(String name){ + for(ContentType t : ContentType.all){ + var out = locate(t, name); + if(out != null){ + return (T)out; + } + } + return null; + } + T make(Class type){ try{ Constructor cons = type.getDeclaredConstructor(); @@ -680,18 +695,26 @@ public class ContentParser{ lastNode.remove(); } - TechNode node = new TechNode(null, unlock, customRequirements == null ? unlock.researchRequirements() : customRequirements); + TechNode node = new TechNode(null, unlock, customRequirements == null ? ItemStack.empty : customRequirements); LoadedMod cur = currentMod; postreads.add(() -> { currentContent = unlock; currentMod = cur; + //add custom objectives + if(research.has("objectives")){ + node.objectives.addAll(parser.readValue(Objective[].class, research.get("objectives"))); + } + //remove old node from parent if(node.parent != null){ node.parent.children.remove(node); } + if(customRequirements == null){ + node.setupRequirements(unlock.researchRequirements()); + } //find parent node. TechNode parent = TechTree.all.find(t -> t.content.name.equals(researchName) || t.content.name.equals(currentMod.name + "-" + researchName));