Research system progress
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 1.4 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.2 KiB |
@@ -582,7 +582,6 @@ blocks.shots = Shots
|
|||||||
blocks.reload = Shots/Second
|
blocks.reload = Shots/Second
|
||||||
blocks.ammo = Ammo
|
blocks.ammo = Ammo
|
||||||
|
|
||||||
bar.corereq = Core Required
|
|
||||||
bar.drilltierreq = Better Drill Required
|
bar.drilltierreq = Better Drill Required
|
||||||
bar.drillspeed = Drill Speed: {0}/s
|
bar.drillspeed = Drill Speed: {0}/s
|
||||||
bar.pumpspeed = Pump Speed: {0}/s
|
bar.pumpspeed = Pump Speed: {0}/s
|
||||||
|
|||||||
@@ -170,7 +170,7 @@ public class Vars implements Loadable{
|
|||||||
public static Net net;
|
public static Net net;
|
||||||
public static ContentLoader content;
|
public static ContentLoader content;
|
||||||
public static GameState state;
|
public static GameState state;
|
||||||
public static GlobalData data;
|
public static CampaignData data;
|
||||||
public static EntityCollisions collisions;
|
public static EntityCollisions collisions;
|
||||||
public static DefaultWaves defaultWaves;
|
public static DefaultWaves defaultWaves;
|
||||||
public static mindustry.audio.LoopControl loops;
|
public static mindustry.audio.LoopControl loops;
|
||||||
@@ -256,7 +256,7 @@ public class Vars implements Loadable{
|
|||||||
bases = new BaseRegistry();
|
bases = new BaseRegistry();
|
||||||
|
|
||||||
state = new GameState();
|
state = new GameState();
|
||||||
data = new GlobalData();
|
data = new CampaignData();
|
||||||
|
|
||||||
mobile = Core.app.isMobile() || testMobile;
|
mobile = Core.app.isMobile() || testMobile;
|
||||||
ios = Core.app.isIOS();
|
ios = Core.app.isIOS();
|
||||||
|
|||||||
@@ -1848,6 +1848,7 @@ public class Blocks implements ContentList{
|
|||||||
requirements(Category.effect, BuildVisibility.campaignOnly, ItemStack.with(Items.copper, 200, Items.lead, 100));
|
requirements(Category.effect, BuildVisibility.campaignOnly, ItemStack.with(Items.copper, 200, Items.lead, 100));
|
||||||
|
|
||||||
size = 3;
|
size = 3;
|
||||||
|
alwaysUnlocked = true;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
//endregion campaign
|
//endregion campaign
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package mindustry.content;
|
package mindustry.content;
|
||||||
|
|
||||||
|
import arc.*;
|
||||||
import arc.math.*;
|
import arc.math.*;
|
||||||
import arc.struct.*;
|
import arc.struct.*;
|
||||||
import arc.util.ArcAnnotate.*;
|
import arc.util.ArcAnnotate.*;
|
||||||
@@ -11,12 +12,15 @@ import mindustry.world.*;
|
|||||||
import static mindustry.content.Blocks.*;
|
import static mindustry.content.Blocks.*;
|
||||||
|
|
||||||
public class TechTree implements ContentList{
|
public class TechTree implements ContentList{
|
||||||
|
private static ObjectMap<UnlockableContent, TechNode> map = new ObjectMap<>();
|
||||||
|
|
||||||
public static Seq<TechNode> all;
|
public static Seq<TechNode> all;
|
||||||
public static TechNode root;
|
public static TechNode root;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void load(){
|
public void load(){
|
||||||
TechNode.context = null;
|
TechNode.context = null;
|
||||||
|
map = new ObjectMap<>();
|
||||||
all = new Seq<>();
|
all = new Seq<>();
|
||||||
|
|
||||||
root = node(coreShard, () -> {
|
root = node(coreShard, () -> {
|
||||||
@@ -312,6 +316,14 @@ public class TechTree implements ContentList{
|
|||||||
return node(block, () -> {});
|
return node(block, () -> {});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static @Nullable TechNode get(UnlockableContent content){
|
||||||
|
return map.get(content);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TechNode getNotNull(UnlockableContent content){
|
||||||
|
return map.getThrow(content, () -> new RuntimeException(content + " does not have a tech node"));
|
||||||
|
}
|
||||||
|
|
||||||
public static class TechNode{
|
public static class TechNode{
|
||||||
private static TechNode context;
|
private static TechNode context;
|
||||||
|
|
||||||
@@ -325,12 +337,14 @@ public class TechTree implements ContentList{
|
|||||||
public ItemStack[] requirements;
|
public ItemStack[] requirements;
|
||||||
/** Extra objectives needed to research this. TODO implement */
|
/** Extra objectives needed to research this. TODO implement */
|
||||||
public Objective[] objectives = {};
|
public Objective[] objectives = {};
|
||||||
/** Research turns required to research this content. */
|
/** Time required to research this content, in seconds. */
|
||||||
public int turns = 3; //TODO keep track of turns that have been used so far
|
public float time = 60; //TODO implement
|
||||||
/** Nodes that depend on this node. */
|
/** Nodes that depend on this node. */
|
||||||
public final Seq<TechNode> children = new Seq<>();
|
public final Seq<TechNode> children = new Seq<>();
|
||||||
|
/** Research progress, in seconds. */
|
||||||
|
public float progress;
|
||||||
|
|
||||||
TechNode(TechNode ccontext, UnlockableContent content, ItemStack[] requirements, Runnable children){
|
TechNode(@Nullable TechNode ccontext, UnlockableContent content, ItemStack[] requirements, Runnable children){
|
||||||
if(ccontext != null){
|
if(ccontext != null){
|
||||||
ccontext.children.add(this);
|
ccontext.children.add(this);
|
||||||
}
|
}
|
||||||
@@ -339,7 +353,9 @@ public class TechTree implements ContentList{
|
|||||||
this.content = content;
|
this.content = content;
|
||||||
this.requirements = requirements;
|
this.requirements = requirements;
|
||||||
this.depth = parent == null ? 0 : parent.depth + 1;
|
this.depth = parent == null ? 0 : parent.depth + 1;
|
||||||
|
this.progress = Core.settings.getFloat("research-" + content.name, 0f);
|
||||||
|
|
||||||
|
map.put(content, this);
|
||||||
context = this;
|
context = this;
|
||||||
children.run();
|
children.run();
|
||||||
context = ccontext;
|
context = ccontext;
|
||||||
@@ -349,5 +365,10 @@ public class TechTree implements ContentList{
|
|||||||
TechNode(UnlockableContent content, ItemStack[] requirements, Runnable children){
|
TechNode(UnlockableContent content, ItemStack[] requirements, Runnable children){
|
||||||
this(context, content, requirements, children);
|
this(context, content, requirements, children);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Flushes research progress to settings. */
|
||||||
|
public void save(){
|
||||||
|
Core.settings.put("research-" + content.name, progress);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -459,9 +459,6 @@ public class Control implements ApplicationListener, Loadable{
|
|||||||
|
|
||||||
input.updateState();
|
input.updateState();
|
||||||
|
|
||||||
//autosave global data if it's modified
|
|
||||||
data.checkSave();
|
|
||||||
|
|
||||||
music.update();
|
music.update();
|
||||||
loops.update();
|
loops.update();
|
||||||
Time.updateGlobal();
|
Time.updateGlobal();
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import arc.util.*;
|
|||||||
import mindustry.annotations.Annotations.*;
|
import mindustry.annotations.Annotations.*;
|
||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
import mindustry.core.GameState.*;
|
import mindustry.core.GameState.*;
|
||||||
import mindustry.ctype.*;
|
|
||||||
import mindustry.game.EventType.*;
|
import mindustry.game.EventType.*;
|
||||||
import mindustry.game.*;
|
import mindustry.game.*;
|
||||||
import mindustry.game.Teams.*;
|
import mindustry.game.Teams.*;
|
||||||
@@ -114,13 +113,6 @@ public class Logic implements ApplicationListener{
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Handles the event of content being used by either the player or some block. */
|
|
||||||
public void handleContent(UnlockableContent content){
|
|
||||||
if(!headless){
|
|
||||||
data.unlockContent(content);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Adds starting items, resets wave time, and sets state to playing. */
|
/** Adds starting items, resets wave time, and sets state to playing. */
|
||||||
public void play(){
|
public void play(){
|
||||||
state.set(State.playing);
|
state.set(State.playing);
|
||||||
@@ -251,8 +243,9 @@ public class Logic implements ApplicationListener{
|
|||||||
Time.runTask(30f, () -> {
|
Time.runTask(30f, () -> {
|
||||||
for(Tilec entity : state.teams.playerCores()){
|
for(Tilec entity : state.teams.playerCores()){
|
||||||
for(Item item : content.items()){
|
for(Item item : content.items()){
|
||||||
data.addItem(item, entity.items().get(item));
|
//TODO where do the items go?
|
||||||
Events.fire(new LaunchItemEvent(new ItemStack(item, entity.items().get(item))));
|
//data.addItem(item, entity.items().get(item));
|
||||||
|
//Events.fire(new LaunchItemEvent(new ItemStack(item, entity.items().get(item))));
|
||||||
}
|
}
|
||||||
entity.tile().remove();
|
entity.tile().remove();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
package mindustry.ctype;
|
package mindustry.ctype;
|
||||||
|
|
||||||
import arc.*;
|
import arc.*;
|
||||||
import arc.util.ArcAnnotate.*;
|
|
||||||
import mindustry.annotations.Annotations.*;
|
|
||||||
import arc.graphics.g2d.*;
|
import arc.graphics.g2d.*;
|
||||||
import arc.scene.ui.layout.*;
|
import arc.scene.ui.layout.*;
|
||||||
import mindustry.*;
|
import arc.util.ArcAnnotate.*;
|
||||||
|
import mindustry.annotations.Annotations.*;
|
||||||
import mindustry.graphics.*;
|
import mindustry.graphics.*;
|
||||||
import mindustry.ui.Cicon;
|
import mindustry.ui.*;
|
||||||
|
|
||||||
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
/** Base interface for an unlockable content type. */
|
/** Base interface for an unlockable content type. */
|
||||||
public abstract class UnlockableContent extends MappableContent{
|
public abstract class UnlockableContent extends MappableContent{
|
||||||
@@ -63,12 +64,12 @@ public abstract class UnlockableContent extends MappableContent{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public final boolean unlocked(){
|
public final boolean unlocked(){
|
||||||
return Vars.data.isUnlocked(this);
|
return data.isUnlocked(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @return whether this content is unlocked, or the player is in a custom game. */
|
/** @return whether this content is unlocked, or the player is in a custom (non-campaign) game. */
|
||||||
public final boolean unlockedCur(){
|
public final boolean unlockedNow(){
|
||||||
return Vars.data.isUnlocked(this) || !Vars.state.isCampaign();
|
return data.isUnlocked(this) || !state.isCampaign();
|
||||||
}
|
}
|
||||||
|
|
||||||
public final boolean locked(){
|
public final boolean locked(){
|
||||||
|
|||||||
@@ -1,22 +1,18 @@
|
|||||||
package mindustry.editor;
|
package mindustry.editor;
|
||||||
|
|
||||||
import arc.*;
|
import arc.*;
|
||||||
import arc.struct.IntSet;
|
import arc.graphics.*;
|
||||||
import arc.struct.IntSet.IntSetIterator;
|
import arc.graphics.g2d.*;
|
||||||
import arc.graphics.Color;
|
import arc.math.*;
|
||||||
import arc.graphics.Texture;
|
import arc.struct.*;
|
||||||
import arc.graphics.g2d.Draw;
|
|
||||||
import arc.graphics.g2d.TextureRegion;
|
|
||||||
import arc.math.Mathf;
|
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import mindustry.content.Blocks;
|
import mindustry.content.*;
|
||||||
import mindustry.game.EventType.*;
|
import mindustry.game.EventType.*;
|
||||||
import mindustry.game.Team;
|
import mindustry.game.*;
|
||||||
import mindustry.graphics.IndexedRenderer;
|
import mindustry.graphics.*;
|
||||||
import mindustry.world.Block;
|
import mindustry.world.*;
|
||||||
import mindustry.world.Tile;
|
|
||||||
|
|
||||||
import static mindustry.Vars.tilesize;
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
public class MapRenderer implements Disposable{
|
public class MapRenderer implements Disposable{
|
||||||
private static final int chunkSize = 64;
|
private static final int chunkSize = 64;
|
||||||
@@ -62,13 +58,7 @@ public class MapRenderer implements Disposable{
|
|||||||
public void draw(float tx, float ty, float tw, float th){
|
public void draw(float tx, float ty, float tw, float th){
|
||||||
Draw.flush();
|
Draw.flush();
|
||||||
|
|
||||||
IntSetIterator it = updates.iterator();
|
updates.each(i -> render(i % width, i / width));
|
||||||
while(it.hasNext){
|
|
||||||
int i = it.next();
|
|
||||||
int x = i % width;
|
|
||||||
int y = i / width;
|
|
||||||
render(x, y);
|
|
||||||
}
|
|
||||||
updates.clear();
|
updates.clear();
|
||||||
|
|
||||||
updates.addAll(delayedUpdates);
|
updates.addAll(delayedUpdates);
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ import arc.util.io.*;
|
|||||||
import mindustry.annotations.Annotations.*;
|
import mindustry.annotations.Annotations.*;
|
||||||
import mindustry.audio.*;
|
import mindustry.audio.*;
|
||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
import mindustry.ctype.*;
|
|
||||||
import mindustry.entities.*;
|
import mindustry.entities.*;
|
||||||
import mindustry.game.EventType.*;
|
import mindustry.game.EventType.*;
|
||||||
import mindustry.game.*;
|
import mindustry.game.*;
|
||||||
@@ -552,8 +551,6 @@ abstract class TileComp implements Posc, Teamc, Healthc, Tilec, Timerc, QuadTree
|
|||||||
public void offload(Item item){
|
public void offload(Item item){
|
||||||
int dump = this.dump;
|
int dump = this.dump;
|
||||||
|
|
||||||
useContent(item);
|
|
||||||
|
|
||||||
for(int i = 0; i < proximity.size; i++){
|
for(int i = 0; i < proximity.size; i++){
|
||||||
incrementDump(proximity.size);
|
incrementDump(proximity.size);
|
||||||
Tilec other = proximity.get((i + dump) % proximity.size);
|
Tilec other = proximity.get((i + dump) % proximity.size);
|
||||||
@@ -571,7 +568,6 @@ abstract class TileComp implements Posc, Teamc, Healthc, Tilec, Timerc, QuadTree
|
|||||||
*/
|
*/
|
||||||
public boolean put(Item item){
|
public boolean put(Item item){
|
||||||
int dump = this.dump;
|
int dump = this.dump;
|
||||||
useContent(item);
|
|
||||||
|
|
||||||
for(int i = 0; i < proximity.size; i++){
|
for(int i = 0; i < proximity.size; i++){
|
||||||
incrementDump(proximity.size);
|
incrementDump(proximity.size);
|
||||||
@@ -814,14 +810,6 @@ abstract class TileComp implements Posc, Teamc, Healthc, Tilec, Timerc, QuadTree
|
|||||||
public void unitRemoved(Unitc unit){
|
public void unitRemoved(Unitc unit){
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Call when some content is produced. This unlocks the content if it is applicable. */
|
|
||||||
public void useContent(UnlockableContent content){
|
|
||||||
//only unlocks content in zones
|
|
||||||
if(!headless && team() == player.team() && state.isCampaign()){
|
|
||||||
logic.handleContent(content);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Called when arbitrary configuration is applied to a tile. */
|
/** Called when arbitrary configuration is applied to a tile. */
|
||||||
public void configured(@Nullable Playerc player, @Nullable Object value){
|
public void configured(@Nullable Playerc player, @Nullable Object value){
|
||||||
//null is of type void.class; anonymous classes use their superclass.
|
//null is of type void.class; anonymous classes use their superclass.
|
||||||
|
|||||||
@@ -0,0 +1,47 @@
|
|||||||
|
package mindustry.game;
|
||||||
|
|
||||||
|
import arc.*;
|
||||||
|
import arc.struct.*;
|
||||||
|
import mindustry.ctype.*;
|
||||||
|
import mindustry.game.EventType.*;
|
||||||
|
|
||||||
|
/** Stores unlocks and tech tree state. */
|
||||||
|
public class CampaignData{
|
||||||
|
private ObjectSet<String> unlocked = new ObjectSet<>();
|
||||||
|
|
||||||
|
/** @return whether or not this piece of content is unlocked yet. */
|
||||||
|
public boolean isUnlocked(UnlockableContent content){
|
||||||
|
return content.alwaysUnlocked || unlocked.contains(content.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Makes this piece of content 'unlocked', if possible.
|
||||||
|
* If this piece of content is already unlocked, nothing changes.
|
||||||
|
*/
|
||||||
|
public void unlockContent(UnlockableContent content){
|
||||||
|
if(content.alwaysUnlocked) return;
|
||||||
|
|
||||||
|
//fire unlock event so other classes can use it
|
||||||
|
if(unlocked.add(content.name)){
|
||||||
|
content.onUnlock();
|
||||||
|
Events.fire(new UnlockEvent(content));
|
||||||
|
|
||||||
|
save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Clears all unlocked content. Automatically saves. */
|
||||||
|
public void reset(){
|
||||||
|
save();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public void load(){
|
||||||
|
unlocked = Core.settings.getJson("unlocked-content", ObjectSet.class, ObjectSet::new);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void save(){
|
||||||
|
Core.settings.putJson("unlocked-content", String.class, unlocked);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,183 +0,0 @@
|
|||||||
package mindustry.game;
|
|
||||||
|
|
||||||
import arc.*;
|
|
||||||
import arc.files.*;
|
|
||||||
import arc.math.*;
|
|
||||||
import arc.struct.*;
|
|
||||||
import arc.util.io.*;
|
|
||||||
import mindustry.*;
|
|
||||||
import mindustry.content.*;
|
|
||||||
import mindustry.ctype.*;
|
|
||||||
import mindustry.game.EventType.*;
|
|
||||||
import mindustry.type.*;
|
|
||||||
|
|
||||||
import java.io.*;
|
|
||||||
import java.util.zip.*;
|
|
||||||
|
|
||||||
import static mindustry.Vars.*;
|
|
||||||
|
|
||||||
/** Stores player unlocks. Clientside only. */
|
|
||||||
public class GlobalData{
|
|
||||||
private ObjectSet<String> unlocked = new ObjectSet<>();
|
|
||||||
private ObjectIntMap<Item> items = new ObjectIntMap<>();
|
|
||||||
private boolean modified;
|
|
||||||
|
|
||||||
public void exportData(Fi file) throws IOException{
|
|
||||||
Seq<Fi> files = new Seq<>();
|
|
||||||
files.add(Core.settings.getSettingsFile());
|
|
||||||
files.addAll(customMapDirectory.list());
|
|
||||||
files.addAll(saveDirectory.list());
|
|
||||||
files.addAll(screenshotDirectory.list());
|
|
||||||
files.addAll(modDirectory.list());
|
|
||||||
files.addAll(schematicDirectory.list());
|
|
||||||
String base = Core.settings.getDataDirectory().path();
|
|
||||||
|
|
||||||
try(OutputStream fos = file.write(false, 2048); ZipOutputStream zos = new ZipOutputStream(fos)){
|
|
||||||
for(Fi add : files){
|
|
||||||
if(add.isDirectory()) continue;
|
|
||||||
zos.putNextEntry(new ZipEntry(add.path().substring(base.length())));
|
|
||||||
Streams.copy(add.read(), zos);
|
|
||||||
zos.closeEntry();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void importData(Fi file){
|
|
||||||
Fi dest = Core.files.local("zipdata.zip");
|
|
||||||
file.copyTo(dest);
|
|
||||||
Fi zipped = new ZipFi(dest);
|
|
||||||
|
|
||||||
Fi base = Core.settings.getDataDirectory();
|
|
||||||
if(!zipped.child("settings.bin").exists()){
|
|
||||||
throw new IllegalArgumentException("Not valid save data.");
|
|
||||||
}
|
|
||||||
|
|
||||||
//purge existing tmp data, keep everything else
|
|
||||||
tmpDirectory.deleteDirectory();
|
|
||||||
|
|
||||||
zipped.walk(f -> f.copyTo(base.child(f.path())));
|
|
||||||
dest.delete();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void modified(){
|
|
||||||
modified = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getItem(Item item){
|
|
||||||
return items.get(item, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addItem(Item item, int amount){
|
|
||||||
if(amount > 0){
|
|
||||||
unlockContent(item);
|
|
||||||
}
|
|
||||||
amount = Math.max(amount, 0);
|
|
||||||
|
|
||||||
items.getAndIncrement(item, 0, amount);
|
|
||||||
state.stats.itemsDelivered.getAndIncrement(item, 0, amount);
|
|
||||||
|
|
||||||
//clamp to capacity
|
|
||||||
items.put(item, Mathf.clamp(items.get(item), 0, getItemCapacity()));
|
|
||||||
|
|
||||||
//clamp overflow
|
|
||||||
if(state.stats.itemsDelivered.get(item, 0) < 0) state.stats.itemsDelivered.put(item, Integer.MAX_VALUE);
|
|
||||||
|
|
||||||
modified = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasItems(Seq<ItemStack> stacks){
|
|
||||||
return !stacks.contains(s -> items.get(s.item, 0) < s.amount);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasItems(ItemStack[] stacks){
|
|
||||||
for(ItemStack stack : stacks){
|
|
||||||
if(!has(stack.item, stack.amount)){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeItems(ItemStack[] stacks){
|
|
||||||
for(ItemStack stack : stacks){
|
|
||||||
remove(stack.item, stack.amount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeItems(Seq<ItemStack> stacks){
|
|
||||||
for(ItemStack stack : stacks){
|
|
||||||
remove(stack.item, stack.amount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void remove(Item item, int amount){
|
|
||||||
items.getAndIncrement(item, 0, -amount);
|
|
||||||
|
|
||||||
modified = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean has(Item item, int amount){
|
|
||||||
return items.get(item, 0) >= amount;
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO: make it upgradeable
|
|
||||||
public int getItemCapacity(){
|
|
||||||
return 10000;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Returns whether or not this piece of content is unlocked yet. */
|
|
||||||
public boolean isUnlocked(UnlockableContent content){
|
|
||||||
return content.alwaysUnlocked || unlocked.contains(content.name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Makes this piece of content 'unlocked', if possible.
|
|
||||||
* If this piece of content is already unlocked, nothing changes.
|
|
||||||
* Results are not saved until you call {@link #save()}.
|
|
||||||
*/
|
|
||||||
public void unlockContent(UnlockableContent content){
|
|
||||||
if(content.alwaysUnlocked) return;
|
|
||||||
|
|
||||||
//fire unlock event so other classes can use it
|
|
||||||
if(unlocked.add(content.name)){
|
|
||||||
modified = true;
|
|
||||||
content.onUnlock();
|
|
||||||
Events.fire(new UnlockEvent(content));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Clears all unlocked content. Automatically saves. */
|
|
||||||
public void reset(){
|
|
||||||
save();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void checkSave(){
|
|
||||||
if(modified){
|
|
||||||
save();
|
|
||||||
modified = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public void load(){
|
|
||||||
items.clear();
|
|
||||||
unlocked = Core.settings.getJson("unlocked-content", ObjectSet.class, ObjectSet::new);
|
|
||||||
for(Item item : Vars.content.items()){
|
|
||||||
items.put(item, Core.settings.getInt("item-" + item.name, 0));
|
|
||||||
}
|
|
||||||
|
|
||||||
//set up default values
|
|
||||||
if(!Core.settings.has("item-" + Items.copper.name)){
|
|
||||||
addItem(Items.copper, 50);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void save(){
|
|
||||||
Core.settings.putJson("unlocked-content", String.class, unlocked);
|
|
||||||
for(Item item : Vars.content.items()){
|
|
||||||
Core.settings.put("item-" + item.name, items.get(item, 0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -278,7 +278,7 @@ public class Schematics implements Loadable{
|
|||||||
/** Creates an array of build requests from a schematic's data, centered on the provided x+y coordinates. */
|
/** Creates an array of build requests from a schematic's data, centered on the provided x+y coordinates. */
|
||||||
public Seq<BuildPlan> toRequests(Schematic schem, int x, int y){
|
public Seq<BuildPlan> toRequests(Schematic schem, int x, int y){
|
||||||
return schem.tiles.map(t -> new BuildPlan(t.x + x - schem.width/2, t.y + y - schem.height/2, t.rotation, t.block).original(t.x, t.y, schem.width, schem.height).configure(t.config))
|
return schem.tiles.map(t -> new BuildPlan(t.x + x - schem.width/2, t.y + y - schem.height/2, t.rotation, t.block).original(t.x, t.y, schem.width, schem.height).configure(t.config))
|
||||||
.removeAll(s -> !s.block.isVisible() || !s.block.unlockedCur());
|
.removeAll(s -> !s.block.isVisible() || !s.block.unlockedNow());
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Adds a schematic to the list, also copying it into the files.*/
|
/** Adds a schematic to the list, also copying it into the files.*/
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ public class Universe{
|
|||||||
load();
|
load();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Update regardless of whether the player is in the campaign. */
|
||||||
public void updateGlobal(){
|
public void updateGlobal(){
|
||||||
//currently only updates one solar system
|
//currently only updates one solar system
|
||||||
updatePlanet(Planets.sun);
|
updatePlanet(Planets.sun);
|
||||||
@@ -40,6 +41,7 @@ public class Universe{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Update planet rotations, global time and relevant state. */
|
||||||
public void update(){
|
public void update(){
|
||||||
secondCounter += Time.delta() / 60f;
|
secondCounter += Time.delta() / 60f;
|
||||||
|
|
||||||
@@ -119,9 +121,11 @@ public class Universe{
|
|||||||
}
|
}
|
||||||
|
|
||||||
//calculate passive item generation
|
//calculate passive item generation
|
||||||
|
//TODO make exports only update for sector with items
|
||||||
|
//TODO items should be added directly to cores!
|
||||||
int[] exports = getTotalExports();
|
int[] exports = getTotalExports();
|
||||||
for(int i = 0; i < exports.length; i++){
|
for(int i = 0; i < exports.length; i++){
|
||||||
data.addItem(content.item(i), exports[i]);
|
//data.addItem(content.item(i), exports[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Events.fire(new TurnEvent());
|
Events.fire(new TurnEvent());
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ public class DesktopInput extends InputHandler{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if((player.dead() || state.isPaused()) && !ui.chatfrag.shown()){
|
if((player.dead() || state.isPaused()) && !ui.chatfrag.shown()){
|
||||||
if(!(scene.getKeyboardFocus() instanceof TextField)){
|
if(!(scene.getKeyboardFocus() instanceof TextField) && !scene.hasDialog()){
|
||||||
//move camera around
|
//move camera around
|
||||||
float camSpeed = !Core.input.keyDown(Binding.boost) ? 3f : 8f;
|
float camSpeed = !Core.input.keyDown(Binding.boost) ? 3f : 8f;
|
||||||
Core.camera.position.add(Tmp.v1.setZero().add(Core.input.axis(Binding.move_x), Core.input.axis(Binding.move_y)).nor().scl(Time.delta() * camSpeed));
|
Core.camera.position.add(Tmp.v1.setZero().add(Core.input.axis(Binding.move_x), Core.input.axis(Binding.move_y)).nor().scl(Time.delta() * camSpeed));
|
||||||
|
|||||||
@@ -651,7 +651,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
|||||||
if(Core.settings.getBool("blockreplace")){
|
if(Core.settings.getBool("blockreplace")){
|
||||||
lineRequests.each(req -> {
|
lineRequests.each(req -> {
|
||||||
Block replace = req.block.getReplacement(req, lineRequests);
|
Block replace = req.block.getReplacement(req, lineRequests);
|
||||||
if(replace.unlockedCur()){
|
if(replace.unlockedNow()){
|
||||||
req.block = replace;
|
req.block = replace;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import arc.struct.*;
|
|||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import arc.util.io.*;
|
import arc.util.io.*;
|
||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
|
import mindustry.content.TechTree.*;
|
||||||
import mindustry.core.*;
|
import mindustry.core.*;
|
||||||
import mindustry.ctype.*;
|
import mindustry.ctype.*;
|
||||||
import mindustry.game.*;
|
import mindustry.game.*;
|
||||||
@@ -75,6 +76,11 @@ public abstract class SaveVersion extends SaveFileReader{
|
|||||||
state.secinfo.prepare();
|
state.secinfo.prepare();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//flush tech node progress
|
||||||
|
for(TechNode node : TechTree.all){
|
||||||
|
node.save();
|
||||||
|
}
|
||||||
|
|
||||||
writeStringMap(stream, StringMap.of(
|
writeStringMap(stream, StringMap.of(
|
||||||
"saved", Time.millis(),
|
"saved", Time.millis(),
|
||||||
"playtime", headless ? 0 : control.saves.getTotalPlaytime(),
|
"playtime", headless ? 0 : control.saves.getTotalPlaytime(),
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ import arc.util.io.*;
|
|||||||
import arc.util.pooling.*;
|
import arc.util.pooling.*;
|
||||||
import mindustry.ai.types.*;
|
import mindustry.ai.types.*;
|
||||||
import mindustry.annotations.Annotations.*;
|
import mindustry.annotations.Annotations.*;
|
||||||
|
import mindustry.content.*;
|
||||||
|
import mindustry.content.TechTree.*;
|
||||||
import mindustry.ctype.*;
|
import mindustry.ctype.*;
|
||||||
import mindustry.entities.bullet.*;
|
import mindustry.entities.bullet.*;
|
||||||
import mindustry.entities.units.*;
|
import mindustry.entities.units.*;
|
||||||
@@ -67,6 +69,11 @@ public class TypeIO{
|
|||||||
for(int i = 0; i < ((Point2[])object).length; i++){
|
for(int i = 0; i < ((Point2[])object).length; i++){
|
||||||
write.i(((Point2[])object)[i].pack());
|
write.i(((Point2[])object)[i].pack());
|
||||||
}
|
}
|
||||||
|
}else if(object instanceof TechNode){
|
||||||
|
TechNode map = (TechNode)object;
|
||||||
|
write.b(9);
|
||||||
|
write.b((byte)map.content.getContentType().ordinal());
|
||||||
|
write.s(map.content.id);
|
||||||
}else{
|
}else{
|
||||||
throw new IllegalArgumentException("Unknown object type: " + object.getClass());
|
throw new IllegalArgumentException("Unknown object type: " + object.getClass());
|
||||||
}
|
}
|
||||||
@@ -84,6 +91,7 @@ public class TypeIO{
|
|||||||
case 6: short length = read.s(); IntSeq arr = new IntSeq(); for(int i = 0; i < length; i ++) arr.add(read.i()); return arr;
|
case 6: short length = read.s(); IntSeq arr = new IntSeq(); for(int i = 0; i < length; i ++) arr.add(read.i()); return arr;
|
||||||
case 7: return new Point2(read.i(), read.i());
|
case 7: return new Point2(read.i(), read.i());
|
||||||
case 8: byte len = read.b(); Point2[] out = new Point2[len]; for(int i = 0; i < len; i ++) out[i] = Point2.unpack(read.i()); return out;
|
case 8: byte len = read.b(); Point2[] out = new Point2[len]; for(int i = 0; i < len; i ++) out[i] = Point2.unpack(read.i()); return out;
|
||||||
|
case 9: return TechTree.getNotNull(content.getByID(ContentType.all[read.b()], read.s()));
|
||||||
default: throw new IllegalArgumentException("Unknown object type: " + type);
|
default: throw new IllegalArgumentException("Unknown object type: " + type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,7 +80,6 @@ public class Map implements Comparable<Map>, Publishable{
|
|||||||
|
|
||||||
public void setHighScore(int score){
|
public void setHighScore(int score){
|
||||||
Core.settings.put("hiscore" + file.nameWithoutExtension(), score);
|
Core.settings.put("hiscore" + file.nameWithoutExtension(), score);
|
||||||
Vars.data.modified();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the result of applying this map's rules to the specified gamemode.*/
|
/** Returns the result of applying this map's rules to the specified gamemode.*/
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ public class SectorPreset extends UnlockableContent{
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean canUnlock(){
|
public boolean canUnlock(){
|
||||||
return data.isUnlocked(this) || !requirements.contains(r -> !r.complete());
|
return unlocked() || !requirements.contains(r -> !r.complete());
|
||||||
}
|
}
|
||||||
|
|
||||||
public Seq<ItemStack> getLaunchCost(){
|
public Seq<ItemStack> getLaunchCost(){
|
||||||
@@ -74,7 +74,6 @@ public class SectorPreset extends UnlockableContent{
|
|||||||
public void setLaunched(){
|
public void setLaunched(){
|
||||||
updateObjectives(() -> {
|
updateObjectives(() -> {
|
||||||
Core.settings.put(name + "-launched", true);
|
Core.settings.put(name + "-launched", true);
|
||||||
data.modified();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,7 +83,6 @@ public class SectorPreset extends UnlockableContent{
|
|||||||
if(value < wave){
|
if(value < wave){
|
||||||
updateObjectives(() -> {
|
updateObjectives(() -> {
|
||||||
Core.settings.put(name + "-wave", wave);
|
Core.settings.put(name + "-wave", wave);
|
||||||
data.modified();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -133,7 +131,6 @@ public class SectorPreset extends UnlockableContent{
|
|||||||
|
|
||||||
stacks.sort();
|
stacks.sort();
|
||||||
launchCost = stacks;
|
launchCost = stacks;
|
||||||
data.modified();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Whether this zone has met its condition; if true, the player can leave. */
|
/** Whether this zone has met its condition; if true, the player can leave. */
|
||||||
@@ -148,7 +145,6 @@ public class SectorPreset extends UnlockableContent{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init(){
|
public void init(){
|
||||||
|
|
||||||
for(ItemStack stack : startingItems){
|
for(ItemStack stack : startingItems){
|
||||||
defaultStartingItems.add(new ItemStack(stack.item, stack.amount));
|
defaultStartingItems.add(new ItemStack(stack.item, stack.amount));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ public abstract class Weather extends MappableContent{
|
|||||||
private static final float fadeTime = 60 * 4;
|
private static final float fadeTime = 60 * 4;
|
||||||
|
|
||||||
Weather weather;
|
Weather weather;
|
||||||
float intensity = 1f, opacity = 1f, life;
|
float intensity = 1f, opacity = 0f, life;
|
||||||
|
|
||||||
void init(Weather weather){
|
void init(Weather weather){
|
||||||
this.weather = weather;
|
this.weather = weather;
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ public class ItemsDisplay extends Table{
|
|||||||
t.marginRight(30f);
|
t.marginRight(30f);
|
||||||
t.left();
|
t.left();
|
||||||
for(Item item : content.items()){
|
for(Item item : content.items()){
|
||||||
if(item.type == ItemType.material && data.isUnlocked(item)){
|
if(item.type == ItemType.material && item.unlocked()){
|
||||||
t.label(() -> format(item)).left();
|
t.label(() -> format(item)).left();
|
||||||
t.image(item.icon(Cicon.small)).size(8 * 3).padLeft(4).padRight(4);
|
t.image(item.icon(Cicon.small)).size(8 * 3).padLeft(4).padRight(4);
|
||||||
t.add(item.localizedName).color(Color.lightGray).left();
|
t.add(item.localizedName).color(Color.lightGray).left();
|
||||||
@@ -51,10 +51,11 @@ public class ItemsDisplay extends Table{
|
|||||||
|
|
||||||
private String format(Item item){
|
private String format(Item item){
|
||||||
builder.setLength(0);
|
builder.setLength(0);
|
||||||
builder.append(ui.formatAmount(data.getItem(item)));
|
builder.append("[TODO implement]");
|
||||||
if(state.isGame() && player.team().data().hasCore() && player.team().core().items().get(item) > 0){
|
//builder.append(ui.formatAmount(data.getItem(item)));
|
||||||
|
if(state.isGame() && player.team().data().hasCore() && player.team().core().items.get(item) > 0){
|
||||||
builder.append(" [unlaunched]+ ");
|
builder.append(" [unlaunched]+ ");
|
||||||
builder.append(ui.formatAmount(state.teams.get(player.team()).core().items().get(item)));
|
builder.append(ui.formatAmount(state.teams.get(player.team()).core().items.get(item)));
|
||||||
}
|
}
|
||||||
return builder.toString();
|
return builder.toString();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ public class LanguageDialog extends BaseDialog{
|
|||||||
Table langs = new Table();
|
Table langs = new Table();
|
||||||
langs.marginRight(24f).marginLeft(24f);
|
langs.marginRight(24f).marginLeft(24f);
|
||||||
ScrollPane pane = new ScrollPane(langs);
|
ScrollPane pane = new ScrollPane(langs);
|
||||||
pane.setFadeScrollBars(false);
|
pane.setScrollingDisabled(true, false);
|
||||||
|
|
||||||
ButtonGroup<TextButton> group = new ButtonGroup<>();
|
ButtonGroup<TextButton> group = new ButtonGroup<>();
|
||||||
|
|
||||||
|
|||||||
@@ -40,11 +40,12 @@ public class PausedDialog extends BaseDialog{
|
|||||||
cont.button("$back", Icon.left, this::hide).colspan(2).width(dw * 2 + 20f);
|
cont.button("$back", Icon.left, this::hide).colspan(2).width(dw * 2 + 20f);
|
||||||
|
|
||||||
cont.row();
|
cont.row();
|
||||||
if(state.isCampaign()){
|
//if(state.isCampaign()){
|
||||||
cont.button("$techtree", Icon.tree, ui.tech::show);
|
// cont.button("$techtree", Icon.tree, ui.tech::show);
|
||||||
}else{
|
//}else{
|
||||||
cont.button("$database", Icon.book, ui.database::show);
|
// cont.button("$database", Icon.book, ui.database::show);
|
||||||
}
|
//}
|
||||||
|
cont.button("placeholder", Icon.warning, () -> ui.showInfo("go away"));
|
||||||
cont.button("$settings", Icon.settings, ui.settings::show);
|
cont.button("$settings", Icon.settings, ui.settings::show);
|
||||||
|
|
||||||
if(!state.rules.tutorial){
|
if(!state.rules.tutorial){
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package mindustry.ui.dialogs;
|
package mindustry.ui.dialogs;
|
||||||
|
|
||||||
import arc.graphics.*;
|
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
import mindustry.type.*;
|
import mindustry.type.*;
|
||||||
import mindustry.ui.*;
|
import mindustry.ui.*;
|
||||||
@@ -23,14 +22,15 @@ public class ResourcesDialog extends BaseDialog{
|
|||||||
t.margin(10f);
|
t.margin(10f);
|
||||||
int[] exports = universe.getTotalExports();
|
int[] exports = universe.getTotalExports();
|
||||||
for(Item item : content.items()){
|
for(Item item : content.items()){
|
||||||
if(exports[item.id] > 0 || data.getItem(item) > 0){
|
//TODO display total items
|
||||||
|
if(exports[item.id] > 0){
|
||||||
t.image(item.icon(Cicon.small)).padRight(4);
|
t.image(item.icon(Cicon.small)).padRight(4);
|
||||||
t.add(ui.formatAmount(data.getItem(item))).color(Color.lightGray);
|
//t.add(ui.formatAmount(data.getItem(item))).color(Color.lightGray);
|
||||||
if(exports[item.id] > 0){
|
//if(exports[item.id] > 0){
|
||||||
t.add("+ [accent]" + ui.formatAmount(exports[item.id]) + " [lightgray]/T");
|
t.add("+ [accent]" + ui.formatAmount(exports[item.id]) + " [lightgray]/T");
|
||||||
}else{
|
//}else{
|
||||||
t.add();
|
// t.add();
|
||||||
}
|
//}
|
||||||
t.row();
|
t.row();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import arc.scene.ui.TextButton.*;
|
|||||||
import arc.scene.ui.layout.*;
|
import arc.scene.ui.layout.*;
|
||||||
import arc.struct.*;
|
import arc.struct.*;
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
|
import arc.util.io.*;
|
||||||
import mindustry.core.GameState.*;
|
import mindustry.core.GameState.*;
|
||||||
import mindustry.core.*;
|
import mindustry.core.*;
|
||||||
import mindustry.game.EventType.*;
|
import mindustry.game.EventType.*;
|
||||||
@@ -21,7 +22,11 @@ import mindustry.graphics.*;
|
|||||||
import mindustry.input.*;
|
import mindustry.input.*;
|
||||||
import mindustry.ui.*;
|
import mindustry.ui.*;
|
||||||
|
|
||||||
import static arc.Core.bundle;
|
import java.io.*;
|
||||||
|
import java.util.zip.*;
|
||||||
|
|
||||||
|
import static arc.Core.*;
|
||||||
|
import static mindustry.Vars.net;
|
||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
public class SettingsMenuDialog extends SettingsDialog{
|
public class SettingsMenuDialog extends SettingsDialog{
|
||||||
@@ -107,7 +112,7 @@ public class SettingsMenuDialog extends SettingsDialog{
|
|||||||
if(ios){
|
if(ios){
|
||||||
Fi file = Core.files.local("mindustry-data-export.zip");
|
Fi file = Core.files.local("mindustry-data-export.zip");
|
||||||
try{
|
try{
|
||||||
data.exportData(file);
|
exportData(file);
|
||||||
}catch(Exception e){
|
}catch(Exception e){
|
||||||
ui.showException(e);
|
ui.showException(e);
|
||||||
}
|
}
|
||||||
@@ -115,7 +120,7 @@ public class SettingsMenuDialog extends SettingsDialog{
|
|||||||
}else{
|
}else{
|
||||||
platform.showFileChooser(false, "zip", file -> {
|
platform.showFileChooser(false, "zip", file -> {
|
||||||
try{
|
try{
|
||||||
data.exportData(file);
|
exportData(file);
|
||||||
ui.showInfo("$data.exported");
|
ui.showInfo("$data.exported");
|
||||||
}catch(Exception e){
|
}catch(Exception e){
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
@@ -129,7 +134,7 @@ public class SettingsMenuDialog extends SettingsDialog{
|
|||||||
|
|
||||||
t.button("$data.import", Icon.download, style, () -> ui.showConfirm("$confirm", "$data.import.confirm", () -> platform.showFileChooser(true, "zip", file -> {
|
t.button("$data.import", Icon.download, style, () -> ui.showConfirm("$confirm", "$data.import.confirm", () -> platform.showFileChooser(true, "zip", file -> {
|
||||||
try{
|
try{
|
||||||
data.importData(file);
|
importData(file);
|
||||||
Core.app.exit();
|
Core.app.exit();
|
||||||
}catch(IllegalArgumentException e){
|
}catch(IllegalArgumentException e){
|
||||||
ui.showErrorMessage("$data.invalid");
|
ui.showErrorMessage("$data.invalid");
|
||||||
@@ -365,6 +370,43 @@ public class SettingsMenuDialog extends SettingsDialog{
|
|||||||
graphics.checkPref("flow", true);
|
graphics.checkPref("flow", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void exportData(Fi file) throws IOException{
|
||||||
|
Seq<Fi> files = new Seq<>();
|
||||||
|
files.add(Core.settings.getSettingsFile());
|
||||||
|
files.addAll(customMapDirectory.list());
|
||||||
|
files.addAll(saveDirectory.list());
|
||||||
|
files.addAll(screenshotDirectory.list());
|
||||||
|
files.addAll(modDirectory.list());
|
||||||
|
files.addAll(schematicDirectory.list());
|
||||||
|
String base = Core.settings.getDataDirectory().path();
|
||||||
|
|
||||||
|
try(OutputStream fos = file.write(false, 2048); ZipOutputStream zos = new ZipOutputStream(fos)){
|
||||||
|
for(Fi add : files){
|
||||||
|
if(add.isDirectory()) continue;
|
||||||
|
zos.putNextEntry(new ZipEntry(add.path().substring(base.length())));
|
||||||
|
Streams.copy(add.read(), zos);
|
||||||
|
zos.closeEntry();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void importData(Fi file){
|
||||||
|
Fi dest = Core.files.local("zipdata.zip");
|
||||||
|
file.copyTo(dest);
|
||||||
|
Fi zipped = new ZipFi(dest);
|
||||||
|
|
||||||
|
Fi base = Core.settings.getDataDirectory();
|
||||||
|
if(!zipped.child("settings.bin").exists()){
|
||||||
|
throw new IllegalArgumentException("Not valid save data.");
|
||||||
|
}
|
||||||
|
|
||||||
|
//purge existing tmp data, keep everything else
|
||||||
|
tmpDirectory.deleteDirectory();
|
||||||
|
|
||||||
|
zipped.walk(f -> f.copyTo(base.child(f.path())));
|
||||||
|
dest.delete();
|
||||||
|
}
|
||||||
|
|
||||||
private void back(){
|
private void back(){
|
||||||
rebuildMenu();
|
rebuildMenu();
|
||||||
prefs.clearChildren();
|
prefs.clearChildren();
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package mindustry.ui.dialogs;
|
package mindustry.ui.dialogs;
|
||||||
|
|
||||||
import arc.*;
|
import arc.*;
|
||||||
|
import arc.func.*;
|
||||||
import arc.graphics.*;
|
import arc.graphics.*;
|
||||||
import arc.graphics.g2d.*;
|
import arc.graphics.g2d.*;
|
||||||
import arc.input.*;
|
import arc.input.*;
|
||||||
@@ -35,15 +36,17 @@ public class TechTreeDialog extends BaseDialog{
|
|||||||
private ObjectSet<TechTreeNode> nodes = new ObjectSet<>();
|
private ObjectSet<TechTreeNode> nodes = new ObjectSet<>();
|
||||||
private TechTreeNode root = new TechTreeNode(TechTree.root, null);
|
private TechTreeNode root = new TechTreeNode(TechTree.root, null);
|
||||||
private Rect bounds = new Rect();
|
private Rect bounds = new Rect();
|
||||||
private ItemsDisplay items;
|
|
||||||
private View view;
|
private View view;
|
||||||
|
private Cons<TechNode> selector = c -> {};
|
||||||
|
|
||||||
public TechTreeDialog(){
|
public TechTreeDialog(){
|
||||||
super("");
|
super("");
|
||||||
|
|
||||||
titleTable.remove();
|
titleTable.remove();
|
||||||
margin(0f).marginBottom(8);
|
margin(0f).marginBottom(8);
|
||||||
Stack stack = cont.stack(view = new View(), items = new ItemsDisplay()).grow().get();
|
Stack stack = cont.stack(view = new View()/*, items = new ItemsDisplay()*/).grow().get();
|
||||||
|
|
||||||
|
shouldPause = true;
|
||||||
|
|
||||||
Events.on(ContentReloadEvent.class, e -> {
|
Events.on(ContentReloadEvent.class, e -> {
|
||||||
nodes.clear();
|
nodes.clear();
|
||||||
@@ -72,7 +75,7 @@ public class TechTreeDialog extends BaseDialog{
|
|||||||
addListener(new InputListener(){
|
addListener(new InputListener(){
|
||||||
@Override
|
@Override
|
||||||
public boolean scrolled(InputEvent event, float x, float y, float amountX, float amountY){
|
public boolean scrolled(InputEvent event, float x, float y, float amountX, float amountY){
|
||||||
view.setScale(Mathf.clamp(view.getScaleX() - amountY / 40f, 0.25f, 1f));
|
view.setScale(Mathf.clamp(view.getScaleX() - amountY / 10f * view.getScaleX(), 0.25f, 1f));
|
||||||
view.setOrigin(Align.center);
|
view.setOrigin(Align.center);
|
||||||
view.setTransform(true);
|
view.setTransform(true);
|
||||||
return true;
|
return true;
|
||||||
@@ -112,6 +115,15 @@ public class TechTreeDialog extends BaseDialog{
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Dialog show(Cons<TechNode> selector){
|
||||||
|
this.selector = selector;
|
||||||
|
return super.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Dialog show(){
|
||||||
|
return show(c -> {});
|
||||||
|
}
|
||||||
|
|
||||||
void treeLayout(){
|
void treeLayout(){
|
||||||
float spacing = 20f;
|
float spacing = 20f;
|
||||||
LayoutNode node = new LayoutNode(root, null);
|
LayoutNode node = new LayoutNode(root, null);
|
||||||
@@ -163,8 +175,6 @@ public class TechTreeDialog extends BaseDialog{
|
|||||||
l.visible = !locked;
|
l.visible = !locked;
|
||||||
checkNodes(l);
|
checkNodes(l);
|
||||||
}
|
}
|
||||||
|
|
||||||
items.rebuild();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void showToast(String info){
|
void showToast(String info){
|
||||||
@@ -247,9 +257,13 @@ public class TechTreeDialog extends BaseDialog{
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}else if(data.hasItems(node.node.requirements) && locked(node.node)){
|
}else if(locked(node.node)){
|
||||||
unlock(node.node);
|
selector.get(node.node);
|
||||||
}
|
}
|
||||||
|
//TODO select it
|
||||||
|
//else if(data.hasItems(node.node.requirements) && locked(node.node)){
|
||||||
|
// unlock(node.node);
|
||||||
|
//}
|
||||||
});
|
});
|
||||||
button.hovered(() -> {
|
button.hovered(() -> {
|
||||||
if(!mobile && hoverNode != button && node.visible){
|
if(!mobile && hoverNode != button && node.visible){
|
||||||
@@ -269,7 +283,7 @@ public class TechTreeDialog extends BaseDialog{
|
|||||||
button.update(() -> {
|
button.update(() -> {
|
||||||
float offset = (Core.graphics.getHeight() % 2) / 2f;
|
float offset = (Core.graphics.getHeight() % 2) / 2f;
|
||||||
button.setPosition(node.x + panX + width / 2f, node.y + panY + height / 2f + offset, Align.center);
|
button.setPosition(node.x + panX + width / 2f, node.y + panY + height / 2f + offset, Align.center);
|
||||||
button.getStyle().up = !locked(node.node) ? Tex.buttonOver : !data.hasItems(node.node.requirements) ? Tex.buttonRed : Tex.button;
|
button.getStyle().up = !locked(node.node) ? Tex.buttonOver : Tex.button;
|
||||||
((TextureRegionDrawable)button.getStyle().imageUp)
|
((TextureRegionDrawable)button.getStyle().imageUp)
|
||||||
.setRegion(node.visible ? node.node.content.icon(Cicon.medium) : Icon.lock.getRegion());
|
.setRegion(node.visible ? node.node.content.icon(Cicon.medium) : Icon.lock.getRegion());
|
||||||
button.getImage().setColor(!locked(node.node) ? Color.white : Color.gray);
|
button.getImage().setColor(!locked(node.node) ? Color.white : Color.gray);
|
||||||
@@ -304,9 +318,11 @@ public class TechTreeDialog extends BaseDialog{
|
|||||||
panY = ry - bounds.y - oy;
|
panY = ry - bounds.y - oy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
void unlock(TechNode node){
|
void unlock(TechNode node){
|
||||||
data.unlockContent(node.content);
|
data.unlockContent(node.content);
|
||||||
data.removeItems(node.requirements);
|
//TODO this should not happen
|
||||||
|
//data.removeItems(node.requirements);
|
||||||
showToast(Core.bundle.format("researched", node.content.localizedName));
|
showToast(Core.bundle.format("researched", node.content.localizedName));
|
||||||
checkNodes(root);
|
checkNodes(root);
|
||||||
hoverNode = null;
|
hoverNode = null;
|
||||||
@@ -315,7 +331,7 @@ public class TechTreeDialog extends BaseDialog{
|
|||||||
Core.scene.act();
|
Core.scene.act();
|
||||||
Sounds.unlock.play();
|
Sounds.unlock.play();
|
||||||
Events.fire(new ResearchEvent(node.content));
|
Events.fire(new ResearchEvent(node.content));
|
||||||
}
|
}*/
|
||||||
|
|
||||||
void rebuild(){
|
void rebuild(){
|
||||||
ImageButton button = hoverNode;
|
ImageButton button = hoverNode;
|
||||||
@@ -357,8 +373,8 @@ public class TechTreeDialog extends BaseDialog{
|
|||||||
list.left();
|
list.left();
|
||||||
list.image(req.item.icon(Cicon.small)).size(8 * 3).padRight(3);
|
list.image(req.item.icon(Cicon.small)).size(8 * 3).padRight(3);
|
||||||
list.add(req.item.localizedName).color(Color.lightGray);
|
list.add(req.item.localizedName).color(Color.lightGray);
|
||||||
list.label(() -> " " + Math.min(data.getItem(req.item), req.amount) + " / " + req.amount)
|
list.label(() -> " " + (player.team().core() != null ? Math.min(player.team().core().items.get(req.item), req.amount) + " / " : "") + req.amount)
|
||||||
.update(l -> l.setColor(data.has(req.item, req.amount) ? Color.lightGray : Color.scarlet));
|
.update(l -> {}/*l.setColor(data.has(req.item, req.amount) ? Color.lightGray : Color.scarlet)*/);//TODO
|
||||||
}).fillX().left();
|
}).fillX().left();
|
||||||
t.row();
|
t.row();
|
||||||
}
|
}
|
||||||
@@ -383,11 +399,13 @@ public class TechTreeDialog extends BaseDialog{
|
|||||||
}
|
}
|
||||||
}).pad(9);
|
}).pad(9);
|
||||||
|
|
||||||
|
//TODO research select button
|
||||||
|
/*
|
||||||
if(mobile && locked(node)){
|
if(mobile && locked(node)){
|
||||||
b.row();
|
b.row();
|
||||||
b.button("$research", Icon.ok, Styles.nodet, () -> unlock(node))
|
b.button("$research", Icon.ok, Styles.nodet, () -> unlock(node))
|
||||||
.disabled(i -> !data.hasItems(node.requirements)).growX().height(44f).colspan(3);
|
.disabled(i -> !data.hasItems(node.requirements)).growX().height(44f).colspan(3);
|
||||||
}
|
}*/
|
||||||
});
|
});
|
||||||
|
|
||||||
infoTable.row();
|
infoTable.row();
|
||||||
|
|||||||
@@ -426,7 +426,7 @@ public class PlacementFragment extends Fragment{
|
|||||||
}
|
}
|
||||||
|
|
||||||
boolean unlocked(Block block){
|
boolean unlocked(Block block){
|
||||||
return !state.isCampaign() || data.isUnlocked(block);
|
return block.unlockedNow();
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean hasInfoBox(){
|
boolean hasInfoBox(){
|
||||||
|
|||||||
@@ -388,12 +388,12 @@ public class Block extends UnlockableContent{
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Configure when a null value is passed.*/
|
/** Configure when a null value is passed.*/
|
||||||
public void configClear(Cons<Tilec> cons){
|
public <E extends Tilec> void configClear(Cons<E> cons){
|
||||||
configurations.put(void.class, (tile, value) -> cons.get((Tilec)tile));
|
configurations.put(void.class, (tile, value) -> cons.get((E)tile));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Listen for a config by class type. */
|
/** Listen for a config by class type. */
|
||||||
public <T> void config(Class<T> type, Cons2<Tilec, T> config){
|
public <T, E extends Tilec> void config(Class<T> type, Cons2<E, T> config){
|
||||||
configurations.put(type, config);
|
configurations.put(type, config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ public class ItemSelection{
|
|||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
for(T item : items){
|
for(T item : items){
|
||||||
if(!data.isUnlocked(item) && state.isCampaign()) continue;
|
if(!item.unlockedNow()) continue;
|
||||||
|
|
||||||
ImageButton button = cont.button(Tex.whiteui, Styles.clearToggleTransi, 24, () -> control.input.frag.config.hideConfig()).group(group).get();
|
ImageButton button = cont.button(Tex.whiteui, Styles.clearToggleTransi, 24, () -> control.input.frag.config.hideConfig()).group(group).get();
|
||||||
button.changed(() -> consumer.get(button.isChecked() ? item : null));
|
button.changed(() -> consumer.get(button.isChecked() ? item : null));
|
||||||
|
|||||||
@@ -177,7 +177,8 @@ public class LaunchPad extends Block{
|
|||||||
//actually launch the items upon removal
|
//actually launch the items upon removal
|
||||||
if(team() == Vars.state.rules.defaultTeam){
|
if(team() == Vars.state.rules.defaultTeam){
|
||||||
for(ItemStack stack : stacks){
|
for(ItemStack stack : stacks){
|
||||||
Vars.data.addItem(stack.item, stack.amount);
|
//TODO where do the items go?
|
||||||
|
//Vars.data.addItem(stack.item, stack.amount);
|
||||||
Events.fire(new LaunchItemEvent(stack));
|
Events.fire(new LaunchItemEvent(stack));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,25 +1,27 @@
|
|||||||
package mindustry.world.blocks.campaign;
|
package mindustry.world.blocks.campaign;
|
||||||
|
|
||||||
import arc.*;
|
|
||||||
import arc.graphics.*;
|
import arc.graphics.*;
|
||||||
import arc.graphics.g2d.*;
|
import arc.graphics.g2d.*;
|
||||||
import arc.math.*;
|
import arc.math.*;
|
||||||
import arc.math.geom.*;
|
import arc.scene.style.*;
|
||||||
import arc.scene.ui.layout.*;
|
import arc.scene.ui.layout.*;
|
||||||
import arc.util.ArcAnnotate.*;
|
import arc.util.ArcAnnotate.*;
|
||||||
|
import arc.util.*;
|
||||||
import arc.util.io.*;
|
import arc.util.io.*;
|
||||||
import mindustry.*;
|
|
||||||
import mindustry.annotations.Annotations.*;
|
import mindustry.annotations.Annotations.*;
|
||||||
|
import mindustry.content.*;
|
||||||
|
import mindustry.content.TechTree.*;
|
||||||
import mindustry.ctype.*;
|
import mindustry.ctype.*;
|
||||||
import mindustry.game.*;
|
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
|
import mindustry.graphics.*;
|
||||||
import mindustry.type.*;
|
import mindustry.type.*;
|
||||||
|
import mindustry.ui.*;
|
||||||
import mindustry.world.*;
|
import mindustry.world.*;
|
||||||
import mindustry.world.blocks.storage.*;
|
import mindustry.world.consumers.*;
|
||||||
|
|
||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
public class ResearchBlock extends StorageBlock{
|
public class ResearchBlock extends Block{
|
||||||
public float researchSpeed = 1f;
|
public float researchSpeed = 1f;
|
||||||
public @Load("@-top") TextureRegion topRegion;
|
public @Load("@-top") TextureRegion topRegion;
|
||||||
|
|
||||||
@@ -31,7 +33,11 @@ public class ResearchBlock extends StorageBlock{
|
|||||||
hasPower = true;
|
hasPower = true;
|
||||||
hasItems = true;
|
hasItems = true;
|
||||||
configurable = true;
|
configurable = true;
|
||||||
itemCapacity = 0;
|
itemCapacity = 100;
|
||||||
|
|
||||||
|
//TODO requirements shrink as time goes on
|
||||||
|
consumes.add(new ConsumeItemDynamic((ResearchBlockEntity entity) -> entity.researching != null ? entity.researching.requirements : ItemStack.empty));
|
||||||
|
config(TechNode.class, ResearchBlockEntity::setTo);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -40,33 +46,100 @@ public class ResearchBlock extends StorageBlock{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canPlaceOn(Tile tile, Team team){
|
public void setBars(){
|
||||||
if(tile == null) return false;
|
super.setBars();
|
||||||
|
|
||||||
//only allow placing next to cores
|
bars.add("progress", (ResearchBlockEntity e) -> new Bar("bar.progress", Pal.ammo, () -> e.researching == null ? 0f : e.researching.progress / e.researching.time));
|
||||||
for(Point2 edge : Edges.getEdges(size)){
|
|
||||||
Tile other = tile.getNearby(edge);
|
|
||||||
if(other != null && other.block() instanceof CoreBlock && other.team() == team){
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public class ResearchBlockEntity extends TileEntity{
|
||||||
public void drawPlace(int x, int y, int rotation, boolean valid){
|
public @Nullable TechNode researching;
|
||||||
boolean hasCore = canPlaceOn(world.tile(x, y), player.team());
|
|
||||||
if(!hasCore){
|
|
||||||
drawPlaceText(Core.bundle.get("bar.corereq"), x, y, valid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class ResearchBlockEntity extends StorageBlockEntity{
|
public double[] accumulator;
|
||||||
public @Nullable UnlockableContent researching;
|
public double[] totalAccumulator;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateTile(){
|
public void updateTile(){
|
||||||
|
if(researching != null){
|
||||||
|
double totalTicks = researching.time * 60.0;
|
||||||
|
double amount = researchSpeed * edelta() / totalTicks;
|
||||||
|
|
||||||
|
double maxProgress = checkRequired(amount, false);
|
||||||
|
|
||||||
|
for(int i = 0; i < researching.requirements.length; i++){
|
||||||
|
int reqamount = Math.round(state.rules.buildCostMultiplier * researching.requirements[i].amount);
|
||||||
|
accumulator[i] += Math.min(reqamount * maxProgress, reqamount - totalAccumulator[i] + 0.00001); //add min amount progressed to the accumulator
|
||||||
|
totalAccumulator[i] = Math.min(totalAccumulator[i] + reqamount * maxProgress, reqamount);
|
||||||
|
}
|
||||||
|
|
||||||
|
maxProgress = checkRequired(maxProgress, true);
|
||||||
|
|
||||||
|
float increment = (float)(maxProgress * researching.time);
|
||||||
|
researching.progress += increment;
|
||||||
|
|
||||||
|
//check if it has been researched
|
||||||
|
if(researching.progress >= researching.time){
|
||||||
|
data.unlockContent(researching.content);
|
||||||
|
|
||||||
|
setTo(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private double checkRequired(double amount, boolean remove){
|
||||||
|
double maxProgress = amount;
|
||||||
|
|
||||||
|
for(int i = 0; i < researching.requirements.length; i++){
|
||||||
|
int ramount = researching.requirements[i].amount;
|
||||||
|
int required = (int)(accumulator[i]); //calculate items that are required now
|
||||||
|
|
||||||
|
if(!items.has(researching.requirements[i].item) && ramount > 0){
|
||||||
|
maxProgress = 0f;
|
||||||
|
}else if(required > 0){ //if this amount is positive...
|
||||||
|
//calculate how many items it can actually use
|
||||||
|
int maxUse = Math.min(required, items.get(researching.requirements[i].item));
|
||||||
|
//get this as a fraction
|
||||||
|
double fraction = maxUse / (double)required;
|
||||||
|
|
||||||
|
//move max progress down if this fraction is less than 1
|
||||||
|
maxProgress = Math.min(maxProgress, maxProgress * fraction);
|
||||||
|
|
||||||
|
accumulator[i] -= maxUse;
|
||||||
|
|
||||||
|
//remove stuff that is actually used
|
||||||
|
if(remove){
|
||||||
|
items.remove(researching.requirements[i].item, maxUse);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//else, no items are required yet, so just keep going
|
||||||
|
}
|
||||||
|
|
||||||
|
return maxProgress;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setTo(@Nullable TechNode value){
|
||||||
|
researching = value;
|
||||||
|
if(value != null){
|
||||||
|
accumulator = new double[researching.requirements.length];
|
||||||
|
totalAccumulator = new double[researching.requirements.length];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void display(Table table){
|
||||||
|
super.display(table);
|
||||||
|
|
||||||
|
TextureRegionDrawable reg = new TextureRegionDrawable();
|
||||||
|
|
||||||
|
table.row();
|
||||||
|
table.table(t -> {
|
||||||
|
t.image().update(i -> {
|
||||||
|
i.setDrawable(researching == null ? Icon.cancel : reg.set(researching.content.icon(Cicon.medium)));
|
||||||
|
i.setScaling(Scaling.fit);
|
||||||
|
i.setColor(researching == null ? Color.lightGray : Color.white);
|
||||||
|
}).size(32).pad(3);
|
||||||
|
t.label(() -> researching == null ? "$none" : researching.content.localizedName).color(Color.lightGray);
|
||||||
|
}).left().padTop(4);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -85,14 +158,25 @@ public class ResearchBlock extends StorageBlock{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean acceptItem(Tilec source, Item item){
|
public boolean acceptItem(Tilec source, Item item){
|
||||||
//research blocks can only transfer items to the core
|
return items.get(item) < getMaximumAccepted(item);
|
||||||
return linkedCore != null && super.acceptItem(source, item);
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaximumAccepted(Item item){
|
||||||
|
if(researching == null) return 0;
|
||||||
|
for(int i = 0; i < researching.requirements.length; i++){
|
||||||
|
if(researching.requirements[i].item == item) return researching.requirements[i].amount;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean configTapped(){
|
public boolean configTapped(){
|
||||||
//TODO select target
|
//configure with tech node
|
||||||
Vars.ui.tech.show();
|
ui.tech.show(node -> {
|
||||||
|
configure(node);
|
||||||
|
ui.tech.hide();
|
||||||
|
});
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -102,8 +186,8 @@ public class ResearchBlock extends StorageBlock{
|
|||||||
super.write(write);
|
super.write(write);
|
||||||
|
|
||||||
if(researching != null){
|
if(researching != null){
|
||||||
write.b(researching.getContentType().ordinal());
|
write.b(researching.content.getContentType().ordinal());
|
||||||
write.s(researching.id);
|
write.s(researching.content.id);
|
||||||
}else{
|
}else{
|
||||||
write.b(-1);
|
write.b(-1);
|
||||||
}
|
}
|
||||||
@@ -115,7 +199,7 @@ public class ResearchBlock extends StorageBlock{
|
|||||||
|
|
||||||
byte type = read.b();
|
byte type = read.b();
|
||||||
if(type != -1){
|
if(type != -1){
|
||||||
researching = Vars.content.getByID(ContentType.all[type], read.s());
|
setTo(TechTree.get(content.getByID(ContentType.all[type], read.s())));
|
||||||
}else{
|
}else{
|
||||||
researching = null;
|
researching = null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,12 +28,11 @@ public class Door extends Wall{
|
|||||||
solidifes = true;
|
solidifes = true;
|
||||||
consumesTap = true;
|
consumesTap = true;
|
||||||
|
|
||||||
config(Boolean.class, (entity, open) -> {
|
config(Boolean.class, (DoorEntity entity, Boolean open) -> {
|
||||||
DoorEntity door = (DoorEntity)entity;
|
entity.open = open;
|
||||||
door.open = open;
|
pathfinder.updateTile(entity.tile());
|
||||||
pathfinder.updateTile(door.tile());
|
(open ? closefx : openfx).at(entity);
|
||||||
(open ? closefx : openfx).at(door);
|
Sounds.door.at(entity);
|
||||||
Sounds.door.at(door);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ public class ItemTurret extends Turret{
|
|||||||
@Override
|
@Override
|
||||||
public void build(Tilec tile, Table table){
|
public void build(Tilec tile, Table table){
|
||||||
MultiReqImage image = new MultiReqImage();
|
MultiReqImage image = new MultiReqImage();
|
||||||
content.items().each(i -> filter.get(i) && (!state.isCampaign() || data.isUnlocked(i)), item -> image.add(new ReqImage(new ItemImage(item.icon(Cicon.medium)),
|
content.items().each(i -> filter.get(i) && i.unlockedNow(), item -> image.add(new ReqImage(new ItemImage(item.icon(Cicon.medium)),
|
||||||
() -> tile != null && !((ItemTurretEntity)tile).ammo.isEmpty() && ((ItemEntry)((ItemTurretEntity)tile).ammo.peek()).item == item)));
|
() -> tile != null && !((ItemTurretEntity)tile).ammo.isEmpty() && ((ItemEntry)((ItemTurretEntity)tile).ammo.peek()).item == item)));
|
||||||
|
|
||||||
table.add(image).size(8 * 4);
|
table.add(image).size(8 * 4);
|
||||||
|
|||||||
@@ -44,9 +44,9 @@ public class ItemBridge extends Block{
|
|||||||
canOverdrive = false;
|
canOverdrive = false;
|
||||||
|
|
||||||
//point2 config is relative
|
//point2 config is relative
|
||||||
config(Point2.class, (tile, i) -> ((ItemBridgeEntity)tile).link = Point2.pack(i.x + tile.tileX(), i.y + tile.tileY()));
|
config(Point2.class, (ItemBridgeEntity tile, Point2 i) -> tile.link = Point2.pack(i.x + tile.tileX(), i.y + tile.tileY()));
|
||||||
//integer is not
|
//integer is not
|
||||||
config(Integer.class, (tile, i) -> ((ItemBridgeEntity)tile).link = i);
|
config(Integer.class, (ItemBridgeEntity tile, Integer i) -> tile.link = i);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -42,8 +42,8 @@ public class MassDriver extends Block{
|
|||||||
hasPower = true;
|
hasPower = true;
|
||||||
outlineIcon = true;
|
outlineIcon = true;
|
||||||
//point2 is relative
|
//point2 is relative
|
||||||
config(Point2.class, (tile, point) -> ((MassDriverEntity)tile).link = Point2.pack(point.x + tile.tileX(), point.y + tile.tileY()));
|
config(Point2.class, (MassDriverEntity tile, Point2 point) -> tile.link = Point2.pack(point.x + tile.tileX(), point.y + tile.tileY()));
|
||||||
config(Integer.class, (tile, point) -> ((MassDriverEntity)tile).link = point);
|
config(Integer.class, (MassDriverEntity tile, Integer point) -> tile.link = point);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -28,8 +28,8 @@ public class Sorter extends Block{
|
|||||||
unloadable = false;
|
unloadable = false;
|
||||||
saveConfig = true;
|
saveConfig = true;
|
||||||
|
|
||||||
config(Item.class, (tile, item) -> ((SorterEntity)tile).sortItem = item);
|
config(Item.class, (SorterEntity tile, Item item) -> tile.sortItem = item);
|
||||||
configClear(tile -> ((SorterEntity)tile).sortItem = null);
|
configClear((SorterEntity tile) -> tile.sortItem = null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -33,17 +33,9 @@ public class BlockForge extends PayloadAcceptor{
|
|||||||
hasPower = true;
|
hasPower = true;
|
||||||
rotate = true;
|
rotate = true;
|
||||||
|
|
||||||
config(Block.class, (tile, block) -> ((BlockForgeEntity)tile).recipe = block);
|
config(Block.class, (BlockForgeEntity tile, Block block) -> tile.recipe = block);
|
||||||
|
|
||||||
consumes.add(new ConsumeItemDynamic(e -> {
|
consumes.add(new ConsumeItemDynamic((BlockForgeEntity e) -> e.recipe != null ? e.recipe.requirements : ItemStack.empty));
|
||||||
BlockForgeEntity entity = (BlockForgeEntity)e;
|
|
||||||
|
|
||||||
if(entity.recipe != null){
|
|
||||||
return entity.recipe.requirements;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ItemStack.empty;
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -43,11 +43,11 @@ public class ImpactReactor extends PowerGenerator{
|
|||||||
public void setBars(){
|
public void setBars(){
|
||||||
super.setBars();
|
super.setBars();
|
||||||
|
|
||||||
bars.add("poweroutput", entity -> new Bar(() ->
|
bars.add("poweroutput", (GeneratorEntity entity) -> new Bar(() ->
|
||||||
Core.bundle.format("bar.poweroutput",
|
Core.bundle.format("bar.poweroutput",
|
||||||
Strings.fixed(Math.max(entity.getPowerProduction() - consumes.getPower().usage, 0) * 60 * entity.timeScale(), 1)),
|
Strings.fixed(Math.max(entity.getPowerProduction() - consumes.getPower().usage, 0) * 60 * entity.timeScale(), 1)),
|
||||||
() -> Pal.powerBar,
|
() -> Pal.powerBar,
|
||||||
() -> ((GeneratorEntity)entity).productionEfficiency));
|
() -> entity.productionEfficiency));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ public class LightBlock extends Block{
|
|||||||
configurable = true;
|
configurable = true;
|
||||||
saveConfig = true;
|
saveConfig = true;
|
||||||
|
|
||||||
config(Integer.class, (tile, value) -> ((LightEntity)tile).color = value);
|
config(Integer.class, (LightEntity tile, Integer value) -> tile.color = value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class LightEntity extends TileEntity{
|
public class LightEntity extends TileEntity{
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ public class NuclearReactor extends PowerGenerator{
|
|||||||
@Override
|
@Override
|
||||||
public void setBars(){
|
public void setBars(){
|
||||||
super.setBars();
|
super.setBars();
|
||||||
bars.add("heat", entity -> new Bar("bar.heat", Pal.lightOrange, () -> ((NuclearReactorEntity)entity).heat));
|
bars.add("heat", (NuclearReactorEntity entity) -> new Bar("bar.heat", Pal.lightOrange, () -> entity.heat));
|
||||||
}
|
}
|
||||||
|
|
||||||
public class NuclearReactorEntity extends GeneratorEntity{
|
public class NuclearReactorEntity extends GeneratorEntity{
|
||||||
|
|||||||
@@ -32,11 +32,11 @@ public class PowerGenerator extends PowerDistributor{
|
|||||||
super.setBars();
|
super.setBars();
|
||||||
|
|
||||||
if(hasPower && outputsPower && !consumes.hasPower()){
|
if(hasPower && outputsPower && !consumes.hasPower()){
|
||||||
bars.add("power", entity -> new Bar(() ->
|
bars.add("power", (GeneratorEntity entity) -> new Bar(() ->
|
||||||
Core.bundle.format("bar.poweroutput",
|
Core.bundle.format("bar.poweroutput",
|
||||||
Strings.fixed(entity.getPowerProduction() * 60 * entity.timeScale(), 1)),
|
Strings.fixed(entity.getPowerProduction() * 60 * entity.timeScale(), 1)),
|
||||||
() -> Pal.powerBar,
|
() -> Pal.powerBar,
|
||||||
() -> ((GeneratorEntity)entity).productionEfficiency));
|
() -> entity.productionEfficiency));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,11 +31,11 @@ public class Cultivator extends GenericCrafter{
|
|||||||
@Override
|
@Override
|
||||||
public void setBars(){
|
public void setBars(){
|
||||||
super.setBars();
|
super.setBars();
|
||||||
bars.add("multiplier", entity -> new Bar(() ->
|
bars.add("multiplier", (CultivatorEntity entity) -> new Bar(() ->
|
||||||
Core.bundle.formatFloat("bar.efficiency",
|
Core.bundle.formatFloat("bar.efficiency",
|
||||||
((((CultivatorEntity)entity).boost + 1f) * ((CultivatorEntity)entity).warmup) * 100f, 1),
|
((entity.boost + 1f) * entity.warmup) * 100f, 1),
|
||||||
() -> Pal.ammo,
|
() -> Pal.ammo,
|
||||||
() -> ((CultivatorEntity)entity).warmup));
|
() -> entity.warmup));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -86,11 +86,8 @@ public class Drill extends Block{
|
|||||||
public void setBars(){
|
public void setBars(){
|
||||||
super.setBars();
|
super.setBars();
|
||||||
|
|
||||||
bars.add("drillspeed", e -> {
|
bars.add("drillspeed", (DrillEntity e) ->
|
||||||
DrillEntity entity = (DrillEntity)e;
|
new Bar(() -> Core.bundle.format("bar.drillspeed", Strings.fixed(e.lastDrillSpeed * 60 * e.timeScale(), 2)), () -> Pal.ammo, () -> e.warmup));
|
||||||
|
|
||||||
return new Bar(() -> Core.bundle.format("bar.drillspeed", Strings.fixed(entity.lastDrillSpeed * 60 * entity.timeScale(), 2)), () -> Pal.ammo, () -> entity.warmup);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Item getDrop(Tile tile){
|
public Item getDrop(Tile tile){
|
||||||
@@ -285,7 +282,6 @@ public class Drill extends Block{
|
|||||||
|
|
||||||
if(dominantItems > 0 && progress >= delay && items.total() < itemCapacity){
|
if(dominantItems > 0 && progress >= delay && items.total() < itemCapacity){
|
||||||
offload(dominantItem);
|
offload(dominantItem);
|
||||||
useContent(dominantItem);
|
|
||||||
|
|
||||||
index ++;
|
index ++;
|
||||||
progress %= delay;
|
progress %= delay;
|
||||||
|
|||||||
@@ -116,14 +116,12 @@ public class GenericCrafter extends Block{
|
|||||||
consume();
|
consume();
|
||||||
|
|
||||||
if(outputItem != null){
|
if(outputItem != null){
|
||||||
useContent(outputItem.item);
|
|
||||||
for(int i = 0; i < outputItem.amount; i++){
|
for(int i = 0; i < outputItem.amount; i++){
|
||||||
offload(outputItem.item);
|
offload(outputItem.item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(outputLiquid != null){
|
if(outputLiquid != null){
|
||||||
useContent(outputLiquid.liquid);
|
|
||||||
handleLiquid(this, outputLiquid.liquid, outputLiquid.amount);
|
handleLiquid(this, outputLiquid.liquid, outputLiquid.amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -45,7 +45,6 @@ public class LiquidConverter extends GenericCrafter{
|
|||||||
if(cons.valid()){
|
if(cons.valid()){
|
||||||
float use = Math.min(cl.amount * edelta(), liquidCapacity - liquids.get(outputLiquid.liquid));
|
float use = Math.min(cl.amount * edelta(), liquidCapacity - liquids.get(outputLiquid.liquid));
|
||||||
|
|
||||||
useContent(outputLiquid.liquid);
|
|
||||||
progress += use / cl.amount;
|
progress += use / cl.amount;
|
||||||
liquids.add(outputLiquid.liquid, use);
|
liquids.add(outputLiquid.liquid, use);
|
||||||
if(progress >= craftTime){
|
if(progress >= craftTime){
|
||||||
|
|||||||
@@ -13,8 +13,6 @@ import mindustry.world.meta.*;
|
|||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
public class Pump extends LiquidBlock{
|
public class Pump extends LiquidBlock{
|
||||||
public final int timerContentCheck = timers++;
|
|
||||||
|
|
||||||
/** Pump amount, total. */
|
/** Pump amount, total. */
|
||||||
protected float pumpAmount = 1f;
|
protected float pumpAmount = 1f;
|
||||||
|
|
||||||
@@ -115,10 +113,6 @@ public class Pump extends LiquidBlock{
|
|||||||
liquids.add(liquidDrop, maxPump);
|
liquids.add(liquidDrop, maxPump);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(liquids.currentAmount() > 0f && timer(timerContentCheck, 10)){
|
|
||||||
useContent(liquids.current());
|
|
||||||
}
|
|
||||||
|
|
||||||
dumpLiquid(liquids.current());
|
dumpLiquid(liquids.current());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,11 +43,11 @@ public class SolidPump extends Pump{
|
|||||||
@Override
|
@Override
|
||||||
public void setBars(){
|
public void setBars(){
|
||||||
super.setBars();
|
super.setBars();
|
||||||
bars.add("efficiency", entity -> new Bar(() ->
|
bars.add("efficiency", (SolidPumpEntity entity) -> new Bar(() ->
|
||||||
Core.bundle.formatFloat("bar.pumpspeed",
|
Core.bundle.formatFloat("bar.pumpspeed",
|
||||||
((SolidPumpEntity)entity).lastPump / Time.delta() * 60, 1),
|
entity.lastPump / Time.delta() * 60, 1),
|
||||||
() -> Pal.ammo,
|
() -> Pal.ammo,
|
||||||
() -> ((SolidPumpEntity)entity).warmup));
|
() -> entity.warmup));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -124,7 +124,6 @@ public class SolidPump extends Pump{
|
|||||||
liquids.add(result, maxPump);
|
liquids.add(result, maxPump);
|
||||||
lastPump = maxPump;
|
lastPump = maxPump;
|
||||||
warmup = Mathf.lerpDelta(warmup, 1f, 0.02f);
|
warmup = Mathf.lerpDelta(warmup, 1f, 0.02f);
|
||||||
if(timer(timerContentCheck, 10)) useContent(result);
|
|
||||||
if(Mathf.chance(delta() * updateEffectChance))
|
if(Mathf.chance(delta() * updateEffectChance))
|
||||||
updateEffect.at(getX() + Mathf.range(size * 2f), getY() + Mathf.range(size * 2f));
|
updateEffect.at(getX() + Mathf.range(size * 2f), getY() + Mathf.range(size * 2f));
|
||||||
}else{
|
}else{
|
||||||
|
|||||||
@@ -24,8 +24,8 @@ public class ItemSource extends Block{
|
|||||||
configurable = true;
|
configurable = true;
|
||||||
saveConfig = true;
|
saveConfig = true;
|
||||||
|
|
||||||
config(Item.class, (tile, item) -> ((ItemSourceEntity)tile).outputItem = item);
|
config(Item.class, (ItemSourceEntity tile, Item item) -> tile.outputItem = item);
|
||||||
configClear(tile -> ((ItemSourceEntity)tile).outputItem = null);
|
configClear((ItemSourceEntity tile) -> tile.outputItem = null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -25,8 +25,8 @@ public class LiquidSource extends Block{
|
|||||||
outputsLiquid = true;
|
outputsLiquid = true;
|
||||||
saveConfig = true;
|
saveConfig = true;
|
||||||
|
|
||||||
config(Liquid.class, (tile, l) -> ((LiquidSourceEntity)tile).source = l);
|
config(Liquid.class, (LiquidSourceEntity tile, Liquid l) -> tile.source = l);
|
||||||
configClear(tile -> ((LiquidSourceEntity)tile).source = null);
|
configClear((LiquidSourceEntity tile) -> tile.source = null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -69,11 +69,11 @@ public class CoreBlock extends StorageBlock{
|
|||||||
public void setStats(){
|
public void setStats(){
|
||||||
super.setStats();
|
super.setStats();
|
||||||
|
|
||||||
bars.add("capacity", e ->
|
bars.add("capacity", (CoreEntity e) ->
|
||||||
new Bar(
|
new Bar(
|
||||||
() -> Core.bundle.format("bar.capacity", ui.formatAmount(((CoreEntity)e).storageCapacity)),
|
() -> Core.bundle.format("bar.capacity", ui.formatAmount(e.storageCapacity)),
|
||||||
() -> Pal.items,
|
() -> Pal.items,
|
||||||
() -> e.items().total() / (float)(((CoreEntity)e).storageCapacity * content.items().count(i -> i.type == ItemType.material))
|
() -> e.items().total() / ((float)e.storageCapacity * content.items().count(i -> i.type == ItemType.material))
|
||||||
));
|
));
|
||||||
|
|
||||||
bars.add("units", e ->
|
bars.add("units", e ->
|
||||||
|
|||||||
@@ -29,9 +29,7 @@ public class MessageBlock extends Block{
|
|||||||
solid = true;
|
solid = true;
|
||||||
destructible = true;
|
destructible = true;
|
||||||
|
|
||||||
config(String.class, (tile, text) -> {
|
config(String.class, (MessageBlockEntity tile, String text) -> {
|
||||||
MessageBlockEntity entity = (MessageBlockEntity)tile;
|
|
||||||
|
|
||||||
if(net.server() && text.length() > maxTextLength){
|
if(net.server() && text.length() > maxTextLength){
|
||||||
throw new ValidateException(player, "Player has gone above text limit.");
|
throw new ValidateException(player, "Player has gone above text limit.");
|
||||||
}
|
}
|
||||||
@@ -51,8 +49,8 @@ public class MessageBlock extends Block{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
entity.message = result.toString();
|
tile.message = result.toString();
|
||||||
entity.lines = entity.message.split("\n");
|
tile.lines = tile.message.split("\n");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,12 +27,8 @@ public class Unloader extends Block{
|
|||||||
saveConfig = true;
|
saveConfig = true;
|
||||||
itemCapacity = 0;
|
itemCapacity = 0;
|
||||||
|
|
||||||
config(Item.class, (tile, item) -> {
|
config(Item.class, (UnloaderEntity tile, Item item) -> tile.sortItem = item);
|
||||||
tile.items().clear();
|
configClear((UnloaderEntity tile) -> tile.sortItem = null);
|
||||||
((UnloaderEntity)tile).sortItem = item;
|
|
||||||
});
|
|
||||||
|
|
||||||
configClear(tile -> ((UnloaderEntity)tile).sortItem = null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ public class Reconstructor extends UnitBlock{
|
|||||||
@Override
|
@Override
|
||||||
public void setBars(){
|
public void setBars(){
|
||||||
super.setBars();
|
super.setBars();
|
||||||
bars.add("progress", entity -> new Bar("bar.progress", Pal.ammo, ((ReconstructorEntity)entity)::fraction));
|
bars.add("progress", (ReconstructorEntity entity) -> new Bar("bar.progress", Pal.ammo, entity::fraction));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -37,20 +37,12 @@ public class UnitFactory extends UnitBlock{
|
|||||||
outputsPayload = true;
|
outputsPayload = true;
|
||||||
rotate = true;
|
rotate = true;
|
||||||
|
|
||||||
config(Integer.class, (tile, i) -> {
|
config(Integer.class, (UnitFactoryEntity tile, Integer i) -> {
|
||||||
((UnitFactoryEntity)tile).currentPlan = i < 0 || i >= plans.length ? -1 : i;
|
tile.currentPlan = i < 0 || i >= plans.length ? -1 : i;
|
||||||
((UnitFactoryEntity)tile).progress = 0;
|
tile.progress = 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
consumes.add(new ConsumeItemDynamic(e -> {
|
consumes.add(new ConsumeItemDynamic((UnitFactoryEntity e) -> e.currentPlan != -1 ? plans[e.currentPlan].requirements : ItemStack.empty));
|
||||||
UnitFactoryEntity entity = (UnitFactoryEntity)e;
|
|
||||||
|
|
||||||
if(entity.currentPlan != -1){
|
|
||||||
return plans[entity.currentPlan].requirements;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ItemStack.empty;
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -69,7 +61,7 @@ public class UnitFactory extends UnitBlock{
|
|||||||
@Override
|
@Override
|
||||||
public void setBars(){
|
public void setBars(){
|
||||||
super.setBars();
|
super.setBars();
|
||||||
bars.add("progress", entity -> new Bar("bar.progress", Pal.ammo, ((UnitFactoryEntity)entity)::fraction));
|
bars.add("progress", (UnitFactoryEntity entity) -> new Bar("bar.progress", Pal.ammo, entity::fraction));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package mindustry.world.consumers;
|
package mindustry.world.consumers;
|
||||||
|
|
||||||
import arc.func.*;
|
import arc.func.*;
|
||||||
|
import arc.math.*;
|
||||||
import arc.scene.ui.layout.*;
|
import arc.scene.ui.layout.*;
|
||||||
import arc.struct.*;
|
import arc.struct.*;
|
||||||
import arc.util.ArcAnnotate.*;
|
import arc.util.ArcAnnotate.*;
|
||||||
@@ -12,8 +13,8 @@ import mindustry.world.meta.*;
|
|||||||
public class ConsumeItemDynamic extends Consume{
|
public class ConsumeItemDynamic extends Consume{
|
||||||
public final @NonNull Func<Tilec, ItemStack[]> items;
|
public final @NonNull Func<Tilec, ItemStack[]> items;
|
||||||
|
|
||||||
public ConsumeItemDynamic(Func<Tilec, ItemStack[]> items){
|
public <T extends Tilec> ConsumeItemDynamic(Func<T, ItemStack[]> items){
|
||||||
this.items = items;
|
this.items = (Func<Tilec, ItemStack[]>)items;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -43,7 +44,7 @@ public class ConsumeItemDynamic extends Consume{
|
|||||||
private void rebuild(Tilec tile, Table table){
|
private void rebuild(Tilec tile, Table table){
|
||||||
for(ItemStack stack : items.get(tile)){
|
for(ItemStack stack : items.get(tile)){
|
||||||
table.add(new ReqImage(new ItemImage(stack.item.icon(Cicon.medium), stack.amount),
|
table.add(new ReqImage(new ItemImage(stack.item.icon(Cicon.medium), stack.amount),
|
||||||
() -> tile.items() != null && tile.items().has(stack.item, stack.amount))).size(8 * 4).padRight(5);
|
() -> tile.items() != null && tile.items().has(stack.item, stack.amount))).size(8 * 4).padRight(6 * Mathf.digits(stack.amount));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ public class ConsumeItemFilter extends Consume{
|
|||||||
@Override
|
@Override
|
||||||
public void build(Tilec tile, Table table){
|
public void build(Tilec tile, Table table){
|
||||||
MultiReqImage image = new MultiReqImage();
|
MultiReqImage image = new MultiReqImage();
|
||||||
content.items().each(i -> filter.get(i) && (!state.isCampaign() || data.isUnlocked(i)), item -> image.add(new ReqImage(new ItemImage(item.icon(Cicon.medium), 1),
|
content.items().each(i -> filter.get(i) && i.unlockedNow(), item -> image.add(new ReqImage(new ItemImage(item.icon(Cicon.medium), 1),
|
||||||
() -> tile.items() != null && tile.items().has(item))));
|
() -> tile.items() != null && tile.items().has(item))));
|
||||||
|
|
||||||
table.add(image).size(8 * 4);
|
table.add(image).size(8 * 4);
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ import mindustry.ui.Bar;
|
|||||||
public class BlockBars{
|
public class BlockBars{
|
||||||
private OrderedMap<String, Func<Tilec, Bar>> bars = new OrderedMap<>();
|
private OrderedMap<String, Func<Tilec, Bar>> bars = new OrderedMap<>();
|
||||||
|
|
||||||
public void add(String name, Func<Tilec, Bar> sup){
|
public <T extends Tilec> void add(String name, Func<T, Bar> sup){
|
||||||
bars.put(name, sup);
|
bars.put(name, (Func<Tilec, Bar>)sup);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void remove(String name){
|
public void remove(String name){
|
||||||
|
|||||||
Reference in New Issue
Block a user