Fractional research
This commit is contained in:
@@ -471,6 +471,8 @@ public class TechTree implements ContentList{
|
|||||||
public UnlockableContent content;
|
public UnlockableContent content;
|
||||||
/** Item requirements for this content. */
|
/** Item requirements for this content. */
|
||||||
public ItemStack[] requirements;
|
public ItemStack[] requirements;
|
||||||
|
/** Requirements that have been fulfilled. Always the same length as the requirement array. */
|
||||||
|
public final ItemStack[] finishedRequirements;
|
||||||
/** Extra objectives needed to research this. TODO implement */
|
/** Extra objectives needed to research this. TODO implement */
|
||||||
public Seq<Objective> objectives = new Seq<>();
|
public Seq<Objective> objectives = new Seq<>();
|
||||||
/** Time required to research this content, in seconds. */
|
/** Time required to research this content, in seconds. */
|
||||||
@@ -491,6 +493,12 @@ public class TechTree implements ContentList{
|
|||||||
this.depth = parent == null ? 0 : parent.depth + 1;
|
this.depth = parent == null ? 0 : parent.depth + 1;
|
||||||
this.progress = Core.settings == null ? 0 : Core.settings.getFloat("research-" + content.name, 0f);
|
this.progress = Core.settings == null ? 0 : Core.settings.getFloat("research-" + content.name, 0f);
|
||||||
this.time = Seq.with(requirements).mapFloat(i -> i.item.cost * i.amount).sum() * 10;
|
this.time = Seq.with(requirements).mapFloat(i -> i.item.cost * i.amount).sum() * 10;
|
||||||
|
this.finishedRequirements = new ItemStack[requirements.length];
|
||||||
|
|
||||||
|
//load up the requirements that have been finished if settings are available
|
||||||
|
for(int i = 0; i < requirements.length; i++){
|
||||||
|
finishedRequirements[i] = new ItemStack(requirements[i].item, Core.settings == null ? 0 : Core.settings.getInt("req-" + content.name + "-" + requirements[i].item.name));
|
||||||
|
}
|
||||||
|
|
||||||
//add dependencies as objectives.
|
//add dependencies as objectives.
|
||||||
content.getDependencies(d -> objectives.add(new Research(d)));
|
content.getDependencies(d -> objectives.add(new Research(d)));
|
||||||
@@ -509,6 +517,11 @@ public class TechTree implements ContentList{
|
|||||||
/** Flushes research progress to settings. */
|
/** Flushes research progress to settings. */
|
||||||
public void save(){
|
public void save(){
|
||||||
Core.settings.put("research-" + content.name, progress);
|
Core.settings.put("research-" + content.name, progress);
|
||||||
|
|
||||||
|
//save finished requirements by item type
|
||||||
|
for(ItemStack stack : finishedRequirements){
|
||||||
|
Core.settings.put("req-" + content.name + "-" + stack.item.name, stack.amount);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import arc.scene.ui.*;
|
|||||||
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.ArcAnnotate.*;
|
||||||
import mindustry.content.*;
|
import mindustry.content.*;
|
||||||
import mindustry.content.TechTree.*;
|
import mindustry.content.TechTree.*;
|
||||||
import mindustry.core.*;
|
import mindustry.core.*;
|
||||||
@@ -262,8 +263,8 @@ public class ResearchDialog extends BaseDialog{
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}else if(canUnlock(node.node) && locked(node.node)){
|
}else if(canSpend(node.node) && locked(node.node)){
|
||||||
unlock(node.node);
|
spend(node.node);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
button.hovered(() -> {
|
button.hovered(() -> {
|
||||||
@@ -284,7 +285,7 @@ public class ResearchDialog 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 : selectable(node.node) && !items().has(node.node.requirements) ? Tex.buttonRed : Tex.button;
|
button.getStyle().up = !locked(node.node) ? Tex.buttonOver : selectable(node.node) && !canSpend(node.node) ? Tex.buttonRed : Tex.button;
|
||||||
|
|
||||||
((TextureRegionDrawable)button.getStyle().imageUp).setRegion(node.selectable ? node.node.content.icon(Cicon.medium) : Icon.lock.getRegion());
|
((TextureRegionDrawable)button.getStyle().imageUp).setRegion(node.selectable ? node.node.content.icon(Cicon.medium) : Icon.lock.getRegion());
|
||||||
button.getImage().setColor(!locked(node.node) ? Color.white : node.selectable ? Color.gray : Pal.gray);
|
button.getImage().setColor(!locked(node.node) ? Color.white : node.selectable ? Color.gray : Pal.gray);
|
||||||
@@ -323,6 +324,40 @@ public class ResearchDialog extends BaseDialog{
|
|||||||
return items().has(node.requirements) && selectable(node);
|
return items().has(node.requirements) && selectable(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean canSpend(TechNode node){
|
||||||
|
//can spend when there's at least 1 item that can be spent
|
||||||
|
return selectable(node) && (node.requirements.length == 0 || Structs.contains(node.requirements, i -> items().has(i.item)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void spend(TechNode node){
|
||||||
|
boolean complete = true;
|
||||||
|
|
||||||
|
boolean[] shine = new boolean[node.requirements.length];
|
||||||
|
|
||||||
|
for(int i = 0; i < node.requirements.length; i++){
|
||||||
|
ItemStack req = node.requirements[i];
|
||||||
|
ItemStack completed = node.finishedRequirements[i];
|
||||||
|
|
||||||
|
//amount actually taken from inventory
|
||||||
|
int used = Math.min(req.amount - completed.amount, items().get(req.item));
|
||||||
|
completed.amount += used;
|
||||||
|
|
||||||
|
if(used > 0) shine[i] = true;
|
||||||
|
|
||||||
|
//disable completion if the completed amount has not reached requirements
|
||||||
|
if(completed.amount < req.amount){
|
||||||
|
complete = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(complete){
|
||||||
|
unlock(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
node.save();
|
||||||
|
rebuild(shine);
|
||||||
|
}
|
||||||
|
|
||||||
void unlock(TechNode node){
|
void unlock(TechNode node){
|
||||||
node.content.unlock();
|
node.content.unlock();
|
||||||
items().remove(node.requirements);
|
items().remove(node.requirements);
|
||||||
@@ -337,6 +372,11 @@ public class ResearchDialog extends BaseDialog{
|
|||||||
}
|
}
|
||||||
|
|
||||||
void rebuild(){
|
void rebuild(){
|
||||||
|
rebuild(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
//pass an array of stack indexes that should shine here
|
||||||
|
void rebuild(@Nullable boolean[] shine){
|
||||||
ImageButton button = hoverNode;
|
ImageButton button = hoverNode;
|
||||||
|
|
||||||
infoTable.remove();
|
infoTable.remove();
|
||||||
@@ -377,13 +417,35 @@ public class ResearchDialog extends BaseDialog{
|
|||||||
desc.table(t -> {
|
desc.table(t -> {
|
||||||
t.left();
|
t.left();
|
||||||
if(selectable){
|
if(selectable){
|
||||||
for(ItemStack req : node.requirements){
|
for(int i = 0; i < node.requirements.length; i++){
|
||||||
|
ItemStack req = node.requirements[i];
|
||||||
|
ItemStack completed = node.finishedRequirements[i];
|
||||||
|
|
||||||
|
//skip finished stacks
|
||||||
|
if(req.amount <= completed.amount) continue;
|
||||||
|
boolean shiny = shine != null && shine[i];
|
||||||
|
|
||||||
t.table(list -> {
|
t.table(list -> {
|
||||||
|
int reqAmount = req.amount - completed.amount;
|
||||||
|
|
||||||
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(() -> " " + (player.team().core() != null ? UI.formatAmount(Math.min(player.team().core().items.get(req.item), req.amount)) + " / " : "") + UI.formatAmount(req.amount))
|
Label label = list.label(() -> " " +
|
||||||
.update(l -> l.setColor(items().has(req.item, req.amount) ? Color.lightGray : Color.scarlet));//TODO
|
(player.team().core() != null ?
|
||||||
|
UI.formatAmount(Math.min(player.team().core().items.get(req.item), reqAmount)) + " / " :
|
||||||
|
"")
|
||||||
|
+ UI.formatAmount(reqAmount)).get();
|
||||||
|
|
||||||
|
Color targetColor = items().has(req.item) ? Color.lightGray : Color.scarlet;
|
||||||
|
|
||||||
|
if(shiny){
|
||||||
|
label.setColor(Pal.accent);
|
||||||
|
label.actions(Actions.color(targetColor, 0.75f, Interp.fade));
|
||||||
|
}else{
|
||||||
|
label.setColor(targetColor);
|
||||||
|
}
|
||||||
|
|
||||||
}).fillX().left();
|
}).fillX().left();
|
||||||
t.row();
|
t.row();
|
||||||
}
|
}
|
||||||
@@ -409,8 +471,8 @@ public class ResearchDialog extends BaseDialog{
|
|||||||
|
|
||||||
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, () -> spend(node))
|
||||||
.disabled(i -> !canUnlock(node)).growX().height(44f).colspan(3);
|
.disabled(i -> !canSpend(node)).growX().height(44f).colspan(3);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
org.gradle.daemon=true
|
org.gradle.daemon=true
|
||||||
org.gradle.jvmargs=-Xms256m -Xmx1024m
|
org.gradle.jvmargs=-Xms256m -Xmx1024m
|
||||||
archash=9758a12fe9090a08fead6186fe49b7c347180f2e
|
archash=9947972b4ee3f60df35ba3d8be42ad5c287c9a43
|
||||||
|
|||||||
Reference in New Issue
Block a user