diff --git a/core/assets-raw/sprites/blocks/defense/overdrive-dome-top.png b/core/assets-raw/sprites/blocks/defense/overdrive-dome-top.png new file mode 100644 index 0000000000..4daa23ba53 Binary files /dev/null and b/core/assets-raw/sprites/blocks/defense/overdrive-dome-top.png differ diff --git a/core/assets-raw/sprites/blocks/defense/overdrive-dome.png b/core/assets-raw/sprites/blocks/defense/overdrive-dome.png new file mode 100644 index 0000000000..61515689d0 Binary files /dev/null and b/core/assets-raw/sprites/blocks/defense/overdrive-dome.png differ diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index ccb520cafe..1301009bd6 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -459,7 +459,7 @@ locked = Locked complete = [lightgray]Complete: requirement.wave = Reach Wave {0} in {1} requirement.core = Destroy Enemy Core in {0} -requirement.unlock = Unlock {0} +requirement.research = Research {0} resume = Resume Zone:\n[lightgray]{0} bestwave = [lightgray]Best Wave: {0} #TODO fix/remove this diff --git a/core/src/mindustry/content/SectorPresets.java b/core/src/mindustry/content/SectorPresets.java index c979bc9dda..1161dc2159 100644 --- a/core/src/mindustry/content/SectorPresets.java +++ b/core/src/mindustry/content/SectorPresets.java @@ -33,8 +33,8 @@ public class SectorPresets implements ContentList{ new SectorWave(groundZero, 60), //new Unlock(Blocks.daggerFactory), //new Unlock(Blocks.draugFactory), - new Unlock(Blocks.door), - new Unlock(Blocks.waterExtractor) + new Research(Blocks.door), + new Research(Blocks.waterExtractor) ); }}; @@ -42,8 +42,8 @@ public class SectorPresets implements ContentList{ conditionWave = 10; requirements = with( new SectorWave(groundZero, 10), - new Unlock(Blocks.junction), - new Unlock(Blocks.router) + new Research(Blocks.junction), + new Research(Blocks.router) ); }}; @@ -51,8 +51,8 @@ public class SectorPresets implements ContentList{ conditionWave = 10; requirements = with( new SectorWave(frozenForest, 10), - new Unlock(Blocks.mender), - new Unlock(Blocks.combustionGenerator) + new Research(Blocks.mender), + new Research(Blocks.combustionGenerator) ); }}; @@ -62,10 +62,10 @@ public class SectorPresets implements ContentList{ requirements = with( new SectorWave(groundZero, 20), new SectorWave(craters, 15), - new Unlock(Blocks.graphitePress), - new Unlock(Blocks.combustionGenerator), - new Unlock(Blocks.kiln), - new Unlock(Blocks.mechanicalPump) + new Research(Blocks.graphitePress), + new Research(Blocks.combustionGenerator), + new Research(Blocks.kiln), + new Research(Blocks.mechanicalPump) ); }}; @@ -74,9 +74,9 @@ public class SectorPresets implements ContentList{ launchPeriod = 10; requirements = with( new SectorWave(frozenForest, 15), - new Unlock(Blocks.pneumaticDrill), - new Unlock(Blocks.powerNode), - new Unlock(Blocks.turbineGenerator) + new Research(Blocks.pneumaticDrill), + new Research(Blocks.powerNode), + new Research(Blocks.turbineGenerator) ); }}; @@ -85,8 +85,8 @@ public class SectorPresets implements ContentList{ new SectorWave(stainedMountains, 15), //new Unlock(Blocks.daggerFactory), //new Unlock(Blocks.crawlerFactory), - new Unlock(Blocks.door), - new Unlock(Blocks.siliconSmelter) + new Research(Blocks.door), + new Research(Blocks.siliconSmelter) ); }}; @@ -96,8 +96,8 @@ public class SectorPresets implements ContentList{ requirements = with( new SectorWave(craters, 40), new Launched(fungalPass), - new Unlock(Blocks.cultivator), - new Unlock(Blocks.sporePress) + new Research(Blocks.cultivator), + new Research(Blocks.sporePress) //new Unlock(Blocks.titanFactory), //new Unlock(Blocks.wraithFactory) ); @@ -108,9 +108,9 @@ public class SectorPresets implements ContentList{ launchPeriod = 10; requirements = with( new SectorWave(ruinousShores, 20), - new Unlock(Blocks.coalCentrifuge), - new Unlock(Blocks.conduit), - new Unlock(Blocks.wave) + new Research(Blocks.coalCentrifuge), + new Research(Blocks.conduit), + new Research(Blocks.wave) ); }}; @@ -119,8 +119,8 @@ public class SectorPresets implements ContentList{ launchPeriod = 2; requirements = with( new SectorWave(tarFields, 20), - new Unlock(Blocks.thermalGenerator), - new Unlock(Blocks.thoriumReactor) + new Research(Blocks.thermalGenerator), + new Research(Blocks.thoriumReactor) ); }}; @@ -130,8 +130,8 @@ public class SectorPresets implements ContentList{ launchPeriod = 15; requirements = with( new Launched(fungalPass), - new Unlock(Blocks.thermalGenerator), - new Unlock(Blocks.laserDrill) + new Research(Blocks.thermalGenerator), + new Research(Blocks.laserDrill) ); }}; diff --git a/core/src/mindustry/content/TechTree.java b/core/src/mindustry/content/TechTree.java index 02a130f93a..1850cc8869 100644 --- a/core/src/mindustry/content/TechTree.java +++ b/core/src/mindustry/content/TechTree.java @@ -472,6 +472,8 @@ public class TechTree implements ContentList{ this.depth = parent == null ? 0 : parent.depth + 1; this.progress = Core.settings == null ? 0 : Core.settings.getFloat("research-" + content.name, 0f); + objectives = Seq.with(requirements).select(i -> !i.item.alwaysUnlocked).map(i -> new Research(i.item)).toArray(Objective.class); + map.put(content, this); context = this; children.run(); diff --git a/core/src/mindustry/ctype/UnlockableContent.java b/core/src/mindustry/ctype/UnlockableContent.java index a74241a518..211854c453 100644 --- a/core/src/mindustry/ctype/UnlockableContent.java +++ b/core/src/mindustry/ctype/UnlockableContent.java @@ -42,6 +42,10 @@ public abstract class UnlockableContent extends MappableContent{ } + public String emoji(){ + return Fonts.getUnicodeStr(name); + } + /** Returns a specific content icon, or the region {contentType}-{name} if not found.*/ public TextureRegion icon(Cicon icon){ if(cicons[icon.ordinal()] == null){ diff --git a/core/src/mindustry/game/Objectives.java b/core/src/mindustry/game/Objectives.java index 6f8913b9e2..27f5bcf5c3 100644 --- a/core/src/mindustry/game/Objectives.java +++ b/core/src/mindustry/game/Objectives.java @@ -3,29 +3,29 @@ package mindustry.game; import arc.*; import arc.scene.ui.layout.*; import arc.util.ArcAnnotate.*; +import mindustry.ctype.*; import mindustry.type.*; -import mindustry.world.*; /** Holds objective classes. */ public class Objectives{ - public static class Unlock implements Objective{ - public @NonNull Block block; + public static class Research implements Objective{ + public @NonNull UnlockableContent content; - public Unlock(Block block){ - this.block = block; + public Research(UnlockableContent content){ + this.content = content; } - protected Unlock(){} + protected Research(){} @Override public boolean complete(){ - return block.unlocked(); + return content.unlocked(); } @Override public String display(){ - return Core.bundle.format("requirement.unlock", block.localizedName); + return Core.bundle.format("requirement.research", content.emoji() + " " + content.localizedName); } } diff --git a/core/src/mindustry/ui/dialogs/ResearchDialog.java b/core/src/mindustry/ui/dialogs/ResearchDialog.java index ed7b7bc32b..126096d565 100644 --- a/core/src/mindustry/ui/dialogs/ResearchDialog.java +++ b/core/src/mindustry/ui/dialogs/ResearchDialog.java @@ -256,7 +256,7 @@ public class ResearchDialog extends BaseDialog{ } }); } - }else if(items().has(node.node.requirements) && locked(node.node)){ + }else if(canUnlock(node.node) && locked(node.node)){ unlock(node.node); } }); @@ -313,6 +313,10 @@ public class ResearchDialog extends BaseDialog{ panY = ry - bounds.y - oy; } + boolean canUnlock(TechNode node){ + return items().has(node.requirements) && !Structs.contains(node.objectives, o -> !o.complete()); + } + void unlock(TechNode node){ node.content.unlock(); items().remove(node.requirements); @@ -378,8 +382,7 @@ public class ResearchDialog extends BaseDialog{ r.add("$complete").colspan(2).left(); r.row(); for(Objective o : node.objectives){ - r.image(Icon.right).padRight(4); - r.add(o.display()).color(Color.lightGray); + r.add(o.display()).color(Color.lightGray).left().padLeft(15f); r.image(o.complete() ? Icon.ok : Icon.cancel, o.complete() ? Color.lightGray : Color.scarlet).padLeft(3); r.row(); } @@ -395,7 +398,7 @@ public class ResearchDialog extends BaseDialog{ if(mobile && locked(node)){ b.row(); b.button("$research", Icon.ok, Styles.nodet, () -> unlock(node)) - .disabled(i -> !items().has(node.requirements)).growX().height(44f).colspan(3); + .disabled(i -> !canUnlock(node)).growX().height(44f).colspan(3); } }); diff --git a/core/src/mindustry/world/blocks/units/Reconstructor.java b/core/src/mindustry/world/blocks/units/Reconstructor.java index 38e02628d3..0920efbb00 100644 --- a/core/src/mindustry/world/blocks/units/Reconstructor.java +++ b/core/src/mindustry/world/blocks/units/Reconstructor.java @@ -150,7 +150,8 @@ public class Reconstructor extends UnitBlock{ } public boolean hasUpgrade(UnitType type){ - return upgrade(type) != null; + UnitType t = upgrade(type); + return t != null && t.unlockedNow(); } public UnitType upgrade(UnitType type){