11package biotech .content ;
22
3+ import arc .Core ;
4+ import arc .func .Cons ;
5+ import arc .scene .style .Drawable ;
6+ import arc .scene .style .TextureRegionDrawable ;
7+ import arc .struct .ObjectFloatMap ;
8+ import arc .struct .ObjectSet ;
39import arc .struct .Seq ;
10+ import arc .util .Nullable ;
411import mindustry .content .TechTree ;
12+ import mindustry .ctype .Content ;
513import mindustry .ctype .UnlockableContent ;
614import mindustry .game .Objectives ;
715import mindustry .type .ItemStack ;
16+ import mindustry .type .Planet ;
817
918public class BioTechTree extends TechTree {
1019
@@ -13,8 +22,8 @@ public class BioTechTree extends TechTree {
1322 public static Seq <BioTechNode > all = new Seq <>();
1423 public static Seq <BioTechNode > roots = new Seq <>();
1524
16- public static TechNode bioNodeRoot (String name , UnlockableContent content , Runnable children ){
17- return nodeRoot (name , content , false , children );
25+ public static BioTechNode bioNodeRoot (String name , UnlockableContent content , Runnable children ){
26+ return bioNodeRoot (name , content , false , children );
1827 }
1928
2029 public static BioTechNode bioNodeRoot (String name , UnlockableContent content , boolean requireUnlock , Runnable children ){
@@ -60,12 +69,108 @@ public static BioTechNode bioNode(UnlockableContent block){
6069 }
6170
6271 public static class BioTechNode extends TechNode {
63- int importance ;
64- public final Seq <BioTechNode > children = new Seq <>();
65-
66- public BioTechNode (TechNode parent , UnlockableContent content , ItemStack [] requirements , int importance ) {
67- super (parent , content , requirements );
72+ public int importance ;
73+ public final Seq <BioTechNode > bioChildren = new Seq <>();
74+ public @ Nullable BioTechNode bioParent ;
75+
76+ public BioTechNode (BioTechNode bioParent , UnlockableContent content , ItemStack [] requirements , int importance ) {
77+ super (bioParent , content , requirements );
78+
79+ if (bioParent != null ){
80+ bioParent .bioChildren .add (this );
81+ planet = bioParent .planet ;
82+ researchCostMultipliers = bioParent .researchCostMultipliers ;
83+ }else if (researchCostMultipliers == null ){
84+ researchCostMultipliers = new ObjectFloatMap <>();
85+ }
86+
87+ this .bioParent = bioParent ;
6888 this .importance = importance ;
89+ this .content = content ;
90+ this .depth = bioParent == null ? 0 : bioParent .depth + 1 ;
91+
92+ if (researchCostMultipliers .size > 0 ){
93+ requirements = ItemStack .copy (requirements );
94+ for (ItemStack requirement : requirements ){
95+ requirement .amount = (int )(requirement .amount * researchCostMultipliers .get (requirement .item , 1 ));
96+ }
97+ }
98+
99+ setupRequirements (requirements );
100+
101+ var used = new ObjectSet <Content >();
102+
103+ //add dependencies as objectives.
104+ content .getDependencies (d -> {
105+ if (used .add (d )){
106+ objectives .add (new Objectives .Research (d ));
107+ }
108+ });
109+
110+ content .techNode = this ;
111+ content .techNodes .add (this );
112+ all .add (this );
113+ }
114+
115+ /** Recursively iterates through everything that is a child of this node. Includes itself. */
116+ public void bioEach (Cons <BioTechNode > consumer ){
117+ consumer .get (this );
118+ for (var child : bioChildren ){
119+ child .bioEach (consumer );
120+ }
121+ }
122+
123+ /** Adds the specified database tab to all the content in this tree. */
124+ public void addDatabaseTab (UnlockableContent tab ){
125+ bioEach (node -> node .content .databaseTabs .add (tab ));
126+ }
127+
128+ /** Adds the specified planet to the shownPlanets of all the content in this tree. */
129+ public void addPlanet (Planet planet ){
130+ bioEach (node -> node .content .shownPlanets .add (planet ));
131+ }
132+
133+ public Drawable icon (){
134+ return icon == null ? new TextureRegionDrawable (content .uiIcon ) : icon ;
135+ }
136+
137+ public String localizedName (){
138+ return Core .bundle .get ("techtree." + name , name );
139+ }
140+
141+ public void setupRequirements (ItemStack [] requirements ){
142+ this .requirements = requirements ;
143+ this .finishedRequirements = new ItemStack [requirements .length ];
144+
145+ //load up the requirements that have been finished if settings are available
146+ for (int i = 0 ; i < requirements .length ; i ++){
147+ finishedRequirements [i ] = new ItemStack (requirements [i ].item , Core .settings == null ? 0 : Core .settings .getInt ("req-" + content .name + "-" + requirements [i ].item .name ));
148+ }
149+ }
150+
151+ /** Resets finished requirements and saves. */
152+ public void reset (){
153+ for (ItemStack stack : finishedRequirements ){
154+ stack .amount = 0 ;
155+ }
156+ save ();
157+ }
158+
159+ /** Removes this node from the tech tree. */
160+ public void remove (){
161+ all .remove (this );
162+ if (bioParent != null ){
163+ bioParent .bioChildren .remove (this );
164+ }
165+ }
166+
167+ /** Flushes research progress to settings. */
168+ public void save (){
169+
170+ //save finished requirements by item type
171+ for (ItemStack stack : finishedRequirements ){
172+ Core .settings .put ("req-" + content .name + "-" + stack .item .name , stack .amount );
173+ }
69174 }
70175 }
71- }
176+ }
0 commit comments