diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index 4f1c23ca53..b3f3f44fd6 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -172,6 +172,9 @@ available = New research available! unlock.incampaign = < Unlock in campaign for details > completed = [accent]Completed techtree = Tech Tree +techtree.select = Tech Tree Selection +techtree.serpulo = Serpulo +techtree.erekir = Erekir research.legacy = [accent]5.0[] research data found.\nDo you want to [accent]load this data[], or [accent]discard it[] and restart research in the new campaign (recommended)? research.load = Load research.discard = Discard diff --git a/core/src/mindustry/content/Blocks.java b/core/src/mindustry/content/Blocks.java index 9740adedd6..2c972f0d9c 100644 --- a/core/src/mindustry/content/Blocks.java +++ b/core/src/mindustry/content/Blocks.java @@ -1096,7 +1096,8 @@ public class Blocks{ craftEffect = new RadialEffect(Fx.heatReactorSmoke, 4, 90f, 7f); itemCapacity = 20; - consumes.item(Items.thorium, 2); + consumes.item(Items.thorium, 3); + consumes.liquid(Liquids.nitrogen, 1f / 60f); outputItem = new ItemStack(Items.fissileMatter, 1); }}; @@ -2854,7 +2855,7 @@ public class Blocks{ restitution = 0.03f; range = 180; shootCone = 3f; - health = 300 * size * size; + health = 350 * size * size; rotateSpeed = 1.6f; limitRange(); @@ -2862,9 +2863,9 @@ public class Blocks{ //TODO implementation; splash damage? shotgun? AA? I have no ideas fracture = new ItemTurret("fracture"){{ - requirements(Category.turret, with(Items.tungsten, 35, Items.silicon, 35)); + requirements(Category.turret, with(Items.tungsten, 30, Items.graphite, 30, Items.silicon, 35)); ammo( - Items.tungsten, new ContinuousFlameBulletType(45f){{ + Items.tungsten, new ContinuousFlameBulletType(50f){{ length = 105f; shootEffect = Fx.randLifeSpark; width = 4.5f; @@ -2903,7 +2904,7 @@ public class Blocks{ range = 90; shootCone = 15f; inaccuracy = 0f; - health = 300 * size * size; + health = 420 * size * size; rotateSpeed = 3f; }}; @@ -2954,7 +2955,7 @@ public class Blocks{ range = 190; shootCone = 15f; inaccuracy = 20f; - health = 300 * size * size; + health = 400 * size * size; rotateSpeed = 3f; //??? diff --git a/core/src/mindustry/content/ErekirTechTree.java b/core/src/mindustry/content/ErekirTechTree.java index 8f395dcb24..984135db69 100644 --- a/core/src/mindustry/content/ErekirTechTree.java +++ b/core/src/mindustry/content/ErekirTechTree.java @@ -6,7 +6,7 @@ import static mindustry.content.TechTree.*; public class ErekirTechTree{ public static void load(){ - rootErekir = node(coreBastion, () -> { + Planets.erekir.techTree = nodeRoot("erekir", coreBastion, () -> { node(duct, () -> { node(ductRouter, () -> { node(ductBridge, () -> { @@ -142,11 +142,13 @@ public class ErekirTechTree{ }); node(breach, () -> { - //fracture turret is broken and thus not listed - //TODO big tech jump here; incomplete turret - node(sublimate, () -> { + node(fracture, () -> { + //TODO big tech jump here; incomplete turret + node(sublimate, () -> { + + }); }); }); diff --git a/core/src/mindustry/content/SerpuloTechTree.java b/core/src/mindustry/content/SerpuloTechTree.java index 60bf379ba6..504a0d2724 100644 --- a/core/src/mindustry/content/SerpuloTechTree.java +++ b/core/src/mindustry/content/SerpuloTechTree.java @@ -12,7 +12,7 @@ import static mindustry.content.UnitTypes.*; public class SerpuloTechTree{ public static void load(){ - root = node(coreShard, () -> { + Planets.serpulo.techTree = nodeRoot("serpulo", coreShard, () -> { node(conveyor, () -> { diff --git a/core/src/mindustry/content/TechTree.java b/core/src/mindustry/content/TechTree.java index 4cbbfd58b9..c77e786b32 100644 --- a/core/src/mindustry/content/TechTree.java +++ b/core/src/mindustry/content/TechTree.java @@ -12,8 +12,14 @@ public class TechTree{ private static TechNode context = null; public static Seq all = new Seq<>(); - //TODO deprecate and refactor the root system - public static TechNode root, rootErekir; + public static Seq roots = new Seq<>(); + + public static TechNode nodeRoot(String name, UnlockableContent content, Runnable children){ + var root = node(content, content.researchRequirements(), children); + root.name = name; + roots.add(root); + return root; + } public static TechNode node(UnlockableContent content, Runnable children){ return node(content, content.researchRequirements(), children); @@ -69,6 +75,8 @@ public class TechTree{ public static class TechNode{ /** Depth in tech tree. */ public int depth; + /** Name for root node - used in tech tree selector. */ + public @Nullable String name; /** Requirement node. */ public @Nullable TechNode parent; /** Content to be researched. */ @@ -103,6 +111,10 @@ public class TechTree{ all.add(this); } + public String localizedName(){ + return Core.bundle.get("techtree." + name); + } + public void setupRequirements(ItemStack[] requirements){ this.requirements = requirements; this.finishedRequirements = new ItemStack[requirements.length]; diff --git a/core/src/mindustry/type/Planet.java b/core/src/mindustry/type/Planet.java index f0d22d7453..016d358b83 100644 --- a/core/src/mindustry/type/Planet.java +++ b/core/src/mindustry/type/Planet.java @@ -9,6 +9,7 @@ import arc.math.geom.*; import arc.struct.*; import arc.util.*; import arc.util.noise.*; +import mindustry.content.TechTree.*; import mindustry.ctype.*; import mindustry.graphics.*; import mindustry.graphics.g3d.*; @@ -86,6 +87,8 @@ public class Planet extends UnlockableContent{ public Planet solarSystem; /** All planets orbiting this one, in ascending order of radius. */ public Seq children = new Seq<>(); + /** Default root node shown when the tech tree is opened here. */ + public @Nullable TechNode techTree; /** Loads the mesh. Clientside only. Defaults to a boring sphere mesh. */ protected Prov meshLoader = () -> new ShaderSphereMesh(this, Shaders.unlit, 2), cloudMeshLoader = () -> null; diff --git a/core/src/mindustry/ui/dialogs/ResearchDialog.java b/core/src/mindustry/ui/dialogs/ResearchDialog.java index cbb210d018..fab74aa679 100644 --- a/core/src/mindustry/ui/dialogs/ResearchDialog.java +++ b/core/src/mindustry/ui/dialogs/ResearchDialog.java @@ -34,8 +34,8 @@ import static mindustry.Vars.*; public class ResearchDialog extends BaseDialog{ public final float nodeSize = Scl.scl(60f); public ObjectSet nodes = new ObjectSet<>(); - //TODO switch root system - public TechTreeNode root = new TechTreeNode(TechTree.rootErekir, null); + public TechTreeNode root = new TechTreeNode(TechTree.roots.first(), null); + public TechNode lastNode = root.node; public Rect bounds = new Rect(); public ItemsDisplay itemDisplay; public View view; @@ -45,13 +45,47 @@ public class ResearchDialog extends BaseDialog{ public ResearchDialog(){ super(""); - titleTable.remove(); + titleTable.clear(); + titleTable.button(b -> { + //TODO custom icon here. + b.image(Icon.tree).padRight(8).size(iconMed); + b.add().growX(); + b.label(() -> root.node.localizedName()).color(Pal.accent); + b.add().growX(); + b.add().size(iconMed); + }, () -> { + new BaseDialog("@techtree.select"){{ + cont.pane(t -> { + t.table(Tex.button, in -> { + in.defaults().width(300f).height(60f); + for(TechNode node : TechTree.roots){ + in.button(node.localizedName(), Styles.cleart, () -> { + rebuildTree(node); + hide(); + }).row(); + } + }); + }); + + addCloseButton(); + }}.show(); + }).minWidth(300f); + margin(0f).marginBottom(8); cont.stack(view = new View(), itemDisplay = new ItemsDisplay()).grow(); + titleTable.toFront(); + shouldPause = true; shown(() -> { + Planet currPlanet = ui.planet.isShown() ? + ui.planet.state.planet : + state.isCampaign() ? state.rules.sector.planet : null; + + if(currPlanet != null && currPlanet.techTree != null){ + switchTree(currPlanet.techTree); + } items = new ItemSeq(){ //store sector item amounts for modifications @@ -176,6 +210,28 @@ public class ResearchDialog extends BaseDialog{ }); } + public void switchTree(TechNode node){ + if(lastNode == node || node == null) return; + nodes.clear(); + root = new TechTreeNode(node, null); + lastNode = node; + view.rebuildAll(); + } + + public void rebuildTree(TechNode node){ + switchTree(node); + view.panX = 0f; + view.panY = -200f; + view.setScale(1f); + + view.hoverNode = null; + view.infoTable.remove(); + view.infoTable.clear(); + + checkNodes(root); + treeLayout(); + } + void treeLayout(){ float spacing = 20f; LayoutNode node = new LayoutNode(root, null); @@ -293,6 +349,13 @@ public class ResearchDialog extends BaseDialog{ public Table infoTable = new Table(); { + rebuildAll(); + } + + public void rebuildAll(){ + clear(); + hoverNode = null; + infoTable.clear(); infoTable.touchable = Touchable.enabled; for(TechTreeNode node : nodes){ diff --git a/gradle.properties b/gradle.properties index 208c2f90ba..ad213e4ec8 100644 --- a/gradle.properties +++ b/gradle.properties @@ -24,4 +24,4 @@ android.useAndroidX=true #used for slow jitpack builds; TODO see if this actually works org.gradle.internal.http.socketTimeout=100000 org.gradle.internal.http.connectionTimeout=100000 -archash=3dc6a7fac5 +archash=f65ae0d8f7