Selectable tech tree
This commit is contained in:
@@ -172,6 +172,9 @@ available = New research available!
|
|||||||
unlock.incampaign = < Unlock in campaign for details >
|
unlock.incampaign = < Unlock in campaign for details >
|
||||||
completed = [accent]Completed
|
completed = [accent]Completed
|
||||||
techtree = Tech Tree
|
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.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.load = Load
|
||||||
research.discard = Discard
|
research.discard = Discard
|
||||||
|
|||||||
@@ -1096,7 +1096,8 @@ public class Blocks{
|
|||||||
craftEffect = new RadialEffect(Fx.heatReactorSmoke, 4, 90f, 7f);
|
craftEffect = new RadialEffect(Fx.heatReactorSmoke, 4, 90f, 7f);
|
||||||
|
|
||||||
itemCapacity = 20;
|
itemCapacity = 20;
|
||||||
consumes.item(Items.thorium, 2);
|
consumes.item(Items.thorium, 3);
|
||||||
|
consumes.liquid(Liquids.nitrogen, 1f / 60f);
|
||||||
outputItem = new ItemStack(Items.fissileMatter, 1);
|
outputItem = new ItemStack(Items.fissileMatter, 1);
|
||||||
}};
|
}};
|
||||||
|
|
||||||
@@ -2854,7 +2855,7 @@ public class Blocks{
|
|||||||
restitution = 0.03f;
|
restitution = 0.03f;
|
||||||
range = 180;
|
range = 180;
|
||||||
shootCone = 3f;
|
shootCone = 3f;
|
||||||
health = 300 * size * size;
|
health = 350 * size * size;
|
||||||
rotateSpeed = 1.6f;
|
rotateSpeed = 1.6f;
|
||||||
|
|
||||||
limitRange();
|
limitRange();
|
||||||
@@ -2862,9 +2863,9 @@ public class Blocks{
|
|||||||
|
|
||||||
//TODO implementation; splash damage? shotgun? AA? I have no ideas
|
//TODO implementation; splash damage? shotgun? AA? I have no ideas
|
||||||
fracture = new ItemTurret("fracture"){{
|
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(
|
ammo(
|
||||||
Items.tungsten, new ContinuousFlameBulletType(45f){{
|
Items.tungsten, new ContinuousFlameBulletType(50f){{
|
||||||
length = 105f;
|
length = 105f;
|
||||||
shootEffect = Fx.randLifeSpark;
|
shootEffect = Fx.randLifeSpark;
|
||||||
width = 4.5f;
|
width = 4.5f;
|
||||||
@@ -2903,7 +2904,7 @@ public class Blocks{
|
|||||||
range = 90;
|
range = 90;
|
||||||
shootCone = 15f;
|
shootCone = 15f;
|
||||||
inaccuracy = 0f;
|
inaccuracy = 0f;
|
||||||
health = 300 * size * size;
|
health = 420 * size * size;
|
||||||
rotateSpeed = 3f;
|
rotateSpeed = 3f;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
@@ -2954,7 +2955,7 @@ public class Blocks{
|
|||||||
range = 190;
|
range = 190;
|
||||||
shootCone = 15f;
|
shootCone = 15f;
|
||||||
inaccuracy = 20f;
|
inaccuracy = 20f;
|
||||||
health = 300 * size * size;
|
health = 400 * size * size;
|
||||||
rotateSpeed = 3f;
|
rotateSpeed = 3f;
|
||||||
|
|
||||||
//???
|
//???
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import static mindustry.content.TechTree.*;
|
|||||||
public class ErekirTechTree{
|
public class ErekirTechTree{
|
||||||
|
|
||||||
public static void load(){
|
public static void load(){
|
||||||
rootErekir = node(coreBastion, () -> {
|
Planets.erekir.techTree = nodeRoot("erekir", coreBastion, () -> {
|
||||||
node(duct, () -> {
|
node(duct, () -> {
|
||||||
node(ductRouter, () -> {
|
node(ductRouter, () -> {
|
||||||
node(ductBridge, () -> {
|
node(ductBridge, () -> {
|
||||||
@@ -142,11 +142,13 @@ public class ErekirTechTree{
|
|||||||
});
|
});
|
||||||
|
|
||||||
node(breach, () -> {
|
node(breach, () -> {
|
||||||
//fracture turret is broken and thus not listed
|
|
||||||
|
|
||||||
//TODO big tech jump here; incomplete turret
|
node(fracture, () -> {
|
||||||
node(sublimate, () -> {
|
|
||||||
|
|
||||||
|
//TODO big tech jump here; incomplete turret
|
||||||
|
node(sublimate, () -> {
|
||||||
|
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import static mindustry.content.UnitTypes.*;
|
|||||||
public class SerpuloTechTree{
|
public class SerpuloTechTree{
|
||||||
|
|
||||||
public static void load(){
|
public static void load(){
|
||||||
root = node(coreShard, () -> {
|
Planets.serpulo.techTree = nodeRoot("serpulo", coreShard, () -> {
|
||||||
|
|
||||||
node(conveyor, () -> {
|
node(conveyor, () -> {
|
||||||
|
|
||||||
|
|||||||
@@ -12,8 +12,14 @@ public class TechTree{
|
|||||||
private static TechNode context = null;
|
private static TechNode context = null;
|
||||||
|
|
||||||
public static Seq<TechNode> all = new Seq<>();
|
public static Seq<TechNode> all = new Seq<>();
|
||||||
//TODO deprecate and refactor the root system
|
public static Seq<TechNode> roots = new Seq<>();
|
||||||
public static TechNode root, rootErekir;
|
|
||||||
|
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){
|
public static TechNode node(UnlockableContent content, Runnable children){
|
||||||
return node(content, content.researchRequirements(), children);
|
return node(content, content.researchRequirements(), children);
|
||||||
@@ -69,6 +75,8 @@ public class TechTree{
|
|||||||
public static class TechNode{
|
public static class TechNode{
|
||||||
/** Depth in tech tree. */
|
/** Depth in tech tree. */
|
||||||
public int depth;
|
public int depth;
|
||||||
|
/** Name for root node - used in tech tree selector. */
|
||||||
|
public @Nullable String name;
|
||||||
/** Requirement node. */
|
/** Requirement node. */
|
||||||
public @Nullable TechNode parent;
|
public @Nullable TechNode parent;
|
||||||
/** Content to be researched. */
|
/** Content to be researched. */
|
||||||
@@ -103,6 +111,10 @@ public class TechTree{
|
|||||||
all.add(this);
|
all.add(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String localizedName(){
|
||||||
|
return Core.bundle.get("techtree." + name);
|
||||||
|
}
|
||||||
|
|
||||||
public void setupRequirements(ItemStack[] requirements){
|
public void setupRequirements(ItemStack[] requirements){
|
||||||
this.requirements = requirements;
|
this.requirements = requirements;
|
||||||
this.finishedRequirements = new ItemStack[requirements.length];
|
this.finishedRequirements = new ItemStack[requirements.length];
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import arc.math.geom.*;
|
|||||||
import arc.struct.*;
|
import arc.struct.*;
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import arc.util.noise.*;
|
import arc.util.noise.*;
|
||||||
|
import mindustry.content.TechTree.*;
|
||||||
import mindustry.ctype.*;
|
import mindustry.ctype.*;
|
||||||
import mindustry.graphics.*;
|
import mindustry.graphics.*;
|
||||||
import mindustry.graphics.g3d.*;
|
import mindustry.graphics.g3d.*;
|
||||||
@@ -86,6 +87,8 @@ public class Planet extends UnlockableContent{
|
|||||||
public Planet solarSystem;
|
public Planet solarSystem;
|
||||||
/** All planets orbiting this one, in ascending order of radius. */
|
/** All planets orbiting this one, in ascending order of radius. */
|
||||||
public Seq<Planet> children = new Seq<>();
|
public Seq<Planet> 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. */
|
/** Loads the mesh. Clientside only. Defaults to a boring sphere mesh. */
|
||||||
protected Prov<GenericMesh> meshLoader = () -> new ShaderSphereMesh(this, Shaders.unlit, 2), cloudMeshLoader = () -> null;
|
protected Prov<GenericMesh> meshLoader = () -> new ShaderSphereMesh(this, Shaders.unlit, 2), cloudMeshLoader = () -> null;
|
||||||
|
|
||||||
|
|||||||
@@ -34,8 +34,8 @@ import static mindustry.Vars.*;
|
|||||||
public class ResearchDialog extends BaseDialog{
|
public class ResearchDialog extends BaseDialog{
|
||||||
public final float nodeSize = Scl.scl(60f);
|
public final float nodeSize = Scl.scl(60f);
|
||||||
public ObjectSet<TechTreeNode> nodes = new ObjectSet<>();
|
public ObjectSet<TechTreeNode> nodes = new ObjectSet<>();
|
||||||
//TODO switch root system
|
public TechTreeNode root = new TechTreeNode(TechTree.roots.first(), null);
|
||||||
public TechTreeNode root = new TechTreeNode(TechTree.rootErekir, null);
|
public TechNode lastNode = root.node;
|
||||||
public Rect bounds = new Rect();
|
public Rect bounds = new Rect();
|
||||||
public ItemsDisplay itemDisplay;
|
public ItemsDisplay itemDisplay;
|
||||||
public View view;
|
public View view;
|
||||||
@@ -45,13 +45,47 @@ public class ResearchDialog extends BaseDialog{
|
|||||||
public ResearchDialog(){
|
public ResearchDialog(){
|
||||||
super("");
|
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);
|
margin(0f).marginBottom(8);
|
||||||
cont.stack(view = new View(), itemDisplay = new ItemsDisplay()).grow();
|
cont.stack(view = new View(), itemDisplay = new ItemsDisplay()).grow();
|
||||||
|
|
||||||
|
titleTable.toFront();
|
||||||
|
|
||||||
shouldPause = true;
|
shouldPause = true;
|
||||||
|
|
||||||
shown(() -> {
|
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(){
|
items = new ItemSeq(){
|
||||||
//store sector item amounts for modifications
|
//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(){
|
void treeLayout(){
|
||||||
float spacing = 20f;
|
float spacing = 20f;
|
||||||
LayoutNode node = new LayoutNode(root, null);
|
LayoutNode node = new LayoutNode(root, null);
|
||||||
@@ -293,6 +349,13 @@ public class ResearchDialog extends BaseDialog{
|
|||||||
public Table infoTable = new Table();
|
public Table infoTable = new Table();
|
||||||
|
|
||||||
{
|
{
|
||||||
|
rebuildAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void rebuildAll(){
|
||||||
|
clear();
|
||||||
|
hoverNode = null;
|
||||||
|
infoTable.clear();
|
||||||
infoTable.touchable = Touchable.enabled;
|
infoTable.touchable = Touchable.enabled;
|
||||||
|
|
||||||
for(TechTreeNode node : nodes){
|
for(TechTreeNode node : nodes){
|
||||||
|
|||||||
@@ -24,4 +24,4 @@ android.useAndroidX=true
|
|||||||
#used for slow jitpack builds; TODO see if this actually works
|
#used for slow jitpack builds; TODO see if this actually works
|
||||||
org.gradle.internal.http.socketTimeout=100000
|
org.gradle.internal.http.socketTimeout=100000
|
||||||
org.gradle.internal.http.connectionTimeout=100000
|
org.gradle.internal.http.connectionTimeout=100000
|
||||||
archash=3dc6a7fac5
|
archash=f65ae0d8f7
|
||||||
|
|||||||
Reference in New Issue
Block a user