asd
This commit is contained in:
@@ -288,6 +288,7 @@ save.corrupted = Save file corrupted or invalid!
|
|||||||
empty = <empty>
|
empty = <empty>
|
||||||
on = On
|
on = On
|
||||||
off = Off
|
off = Off
|
||||||
|
save.search = Search saved games...
|
||||||
save.autosave = Autosave: {0}
|
save.autosave = Autosave: {0}
|
||||||
save.map = Map: {0}
|
save.map = Map: {0}
|
||||||
save.wave = Wave {0}
|
save.wave = Wave {0}
|
||||||
@@ -379,9 +380,13 @@ editor.ingame = Edit In-Game
|
|||||||
editor.publish.workshop = Publish On Workshop
|
editor.publish.workshop = Publish On Workshop
|
||||||
editor.newmap = New Map
|
editor.newmap = New Map
|
||||||
editor.center = Center
|
editor.center = Center
|
||||||
editor.search = Search Maps...
|
editor.search = Search maps...
|
||||||
editor.filters = Filter Maps
|
editor.filters = Filter Maps
|
||||||
editor.showAll = Show Default Maps
|
editor.filters.mode = Gamemodes:
|
||||||
|
editor.filters.type = Map Type:
|
||||||
|
editor.filters.search = Search In:
|
||||||
|
editor.filters.author = Author
|
||||||
|
editor.filters.description = Description
|
||||||
workshop = Workshop
|
workshop = Workshop
|
||||||
waves.title = Waves
|
waves.title = Waves
|
||||||
waves.remove = Remove
|
waves.remove = Remove
|
||||||
|
|||||||
@@ -128,3 +128,4 @@ SAMBUYYA
|
|||||||
genNAowl
|
genNAowl
|
||||||
TranquillyUnpleasant
|
TranquillyUnpleasant
|
||||||
Darkness6030
|
Darkness6030
|
||||||
|
hortiSquash
|
||||||
@@ -1095,7 +1095,7 @@ public class Blocks implements ContentList{
|
|||||||
}};
|
}};
|
||||||
|
|
||||||
mendProjector = new MendProjector("mend-projector"){{
|
mendProjector = new MendProjector("mend-projector"){{
|
||||||
requirements(Category.effect, with(Items.lead, 100, Items.titanium, 25, Items.silicon, 40));
|
requirements(Category.effect, with(Items.lead, 100, Items.titanium, 25, Items.silicon, 40, Items.copper, 50));
|
||||||
consumes.power(1.5f);
|
consumes.power(1.5f);
|
||||||
size = 2;
|
size = 2;
|
||||||
reload = 250f;
|
reload = 250f;
|
||||||
@@ -1541,7 +1541,7 @@ public class Blocks implements ContentList{
|
|||||||
}};
|
}};
|
||||||
|
|
||||||
waterExtractor = new SolidPump("water-extractor"){{
|
waterExtractor = new SolidPump("water-extractor"){{
|
||||||
requirements(Category.production, with(Items.metaglass, 30, Items.graphite, 30, Items.lead, 30));
|
requirements(Category.production, with(Items.metaglass, 30, Items.graphite, 30, Items.lead, 30, Items.copper, 30));
|
||||||
result = Liquids.water;
|
result = Liquids.water;
|
||||||
pumpAmount = 0.11f;
|
pumpAmount = 0.11f;
|
||||||
size = 2;
|
size = 2;
|
||||||
@@ -1858,7 +1858,7 @@ public class Blocks implements ContentList{
|
|||||||
shots = 4;
|
shots = 4;
|
||||||
burstSpacing = 5;
|
burstSpacing = 5;
|
||||||
inaccuracy = 10f;
|
inaccuracy = 10f;
|
||||||
range = 235f;
|
range = 240f;
|
||||||
xRand = 6f;
|
xRand = 6f;
|
||||||
size = 2;
|
size = 2;
|
||||||
health = 300 * size * size;
|
health = 300 * size * size;
|
||||||
@@ -2310,12 +2310,12 @@ public class Blocks implements ContentList{
|
|||||||
//region payloads
|
//region payloads
|
||||||
|
|
||||||
payloadConveyor = new PayloadConveyor("payload-conveyor"){{
|
payloadConveyor = new PayloadConveyor("payload-conveyor"){{
|
||||||
requirements(Category.units, with(Items.graphite, 10, Items.copper, 20));
|
requirements(Category.units, with(Items.graphite, 10, Items.lead, 10));
|
||||||
canOverdrive = false;
|
canOverdrive = false;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
payloadRouter = new PayloadRouter("payload-router"){{
|
payloadRouter = new PayloadRouter("payload-router"){{
|
||||||
requirements(Category.units, with(Items.graphite, 15, Items.copper, 20));
|
requirements(Category.units, with(Items.graphite, 15, Items.lead, 15));
|
||||||
canOverdrive = false;
|
canOverdrive = false;
|
||||||
}};
|
}};
|
||||||
|
|
||||||
@@ -2411,14 +2411,12 @@ public class Blocks implements ContentList{
|
|||||||
requirements(Category.units, BuildVisibility.sandboxOnly, with());
|
requirements(Category.units, BuildVisibility.sandboxOnly, with());
|
||||||
size = 5;
|
size = 5;
|
||||||
alwaysUnlocked = true;
|
alwaysUnlocked = true;
|
||||||
group = BlockGroup.units;
|
|
||||||
}};
|
}};
|
||||||
|
|
||||||
payloadVoid = new PayloadVoid("payload-void"){{
|
payloadVoid = new PayloadVoid("payload-void"){{
|
||||||
requirements(Category.units, BuildVisibility.sandboxOnly, with());
|
requirements(Category.units, BuildVisibility.sandboxOnly, with());
|
||||||
size = 5;
|
size = 5;
|
||||||
alwaysUnlocked = true;
|
alwaysUnlocked = true;
|
||||||
group = BlockGroup.units;
|
|
||||||
}};
|
}};
|
||||||
|
|
||||||
//TODO move
|
//TODO move
|
||||||
|
|||||||
@@ -275,7 +275,7 @@ public class NetServer implements ApplicationListener{
|
|||||||
int page = args.length > 0 ? Strings.parseInt(args[0]) : 1;
|
int page = args.length > 0 ? Strings.parseInt(args[0]) : 1;
|
||||||
int pages = Mathf.ceil((float)clientCommands.getCommandList().size / commandsPerPage);
|
int pages = Mathf.ceil((float)clientCommands.getCommandList().size / commandsPerPage);
|
||||||
|
|
||||||
page --;
|
page--;
|
||||||
|
|
||||||
if(page >= pages || page < 0){
|
if(page >= pages || page < 0){
|
||||||
player.sendMessage("[scarlet]'page' must be a number between[orange] 1[] and[orange] " + pages + "[scarlet].");
|
player.sendMessage("[scarlet]'page' must be a number between[orange] 1[] and[orange] " + pages + "[scarlet].");
|
||||||
@@ -724,6 +724,8 @@ public class NetServer implements ApplicationListener{
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Events.fire(new EventType.AdminRequestEvent(player, other, action));
|
||||||
|
|
||||||
if(action == AdminAction.wave){
|
if(action == AdminAction.wave){
|
||||||
//no verification is done, so admins can hypothetically spam waves
|
//no verification is done, so admins can hypothetically spam waves
|
||||||
//not a real issue, because server owners may want to do just that
|
//not a real issue, because server owners may want to do just that
|
||||||
|
|||||||
@@ -24,6 +24,38 @@ abstract class PayloadComp implements Posc, Rotc, Hitboxc, Unitc{
|
|||||||
|
|
||||||
Seq<Payload> payloads = new Seq<>();
|
Seq<Payload> payloads = new Seq<>();
|
||||||
|
|
||||||
|
//uncomment for insanity
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
private transient @Nullable PowerGraph payloadPower;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(){
|
||||||
|
if(payloadPower != null){
|
||||||
|
payloadPower.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
//update power graph first, resolve everything
|
||||||
|
for(Payload pay : payloads){
|
||||||
|
if(pay instanceof BuildPayload pb && pb.build.power != null){
|
||||||
|
if(payloadPower == null) payloadPower = new PowerGraph();
|
||||||
|
|
||||||
|
pb.build.power.graph = null;
|
||||||
|
payloadPower.add(pb.build);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(payloadPower != null){
|
||||||
|
payloadPower.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
for(Payload pay : payloads){
|
||||||
|
pay.set(x, y, rotation);
|
||||||
|
pay.update(true);
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
float payloadUsed(){
|
float payloadUsed(){
|
||||||
return payloads.sumf(p -> p.size() * p.size());
|
return payloads.sumf(p -> p.size() * p.size());
|
||||||
}
|
}
|
||||||
@@ -50,7 +82,7 @@ abstract class PayloadComp implements Posc, Rotc, Hitboxc, Unitc{
|
|||||||
|
|
||||||
void pickup(Unit unit){
|
void pickup(Unit unit){
|
||||||
unit.remove();
|
unit.remove();
|
||||||
payloads.add(new UnitPayload(unit));
|
addPayload(new UnitPayload(unit));
|
||||||
Fx.unitPickup.at(unit);
|
Fx.unitPickup.at(unit);
|
||||||
if(Vars.net.client()){
|
if(Vars.net.client()){
|
||||||
Vars.netClient.clearRemovedEntity(unit.id);
|
Vars.netClient.clearRemovedEntity(unit.id);
|
||||||
@@ -62,7 +94,7 @@ abstract class PayloadComp implements Posc, Rotc, Hitboxc, Unitc{
|
|||||||
tile.pickedUp();
|
tile.pickedUp();
|
||||||
tile.tile.remove();
|
tile.tile.remove();
|
||||||
tile.tile = Vars.emptyTile;
|
tile.tile = Vars.emptyTile;
|
||||||
payloads.add(new BuildPayload(tile));
|
addPayload(new BuildPayload(tile));
|
||||||
Fx.unitPickup.at(tile);
|
Fx.unitPickup.at(tile);
|
||||||
Events.fire(new PickupEvent(self(), tile));
|
Events.fire(new PickupEvent(self(), tile));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -544,4 +544,15 @@ public class EventType{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class AdminRequestEvent{
|
||||||
|
public final Player player;
|
||||||
|
public final @Nullable Player other;
|
||||||
|
public final AdminAction action;
|
||||||
|
|
||||||
|
public AdminRequestEvent(Player player, Player other, AdminAction action){
|
||||||
|
this.player = player;
|
||||||
|
this.other = other;
|
||||||
|
this.action = action;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -103,6 +103,8 @@ public class Rules{
|
|||||||
public ObjectSet<Block> revealedBlocks = new ObjectSet<>();
|
public ObjectSet<Block> revealedBlocks = new ObjectSet<>();
|
||||||
/** Unlocked content names. Only used in multiplayer when the campaign is enabled. */
|
/** Unlocked content names. Only used in multiplayer when the campaign is enabled. */
|
||||||
public ObjectSet<String> researched = new ObjectSet<>();
|
public ObjectSet<String> researched = new ObjectSet<>();
|
||||||
|
/** Block containing these items as requirements are hidden. */
|
||||||
|
public ObjectSet<Item> hiddenBuildItems = new ObjectSet<>();
|
||||||
/** Whether ambient lighting is enabled. */
|
/** Whether ambient lighting is enabled. */
|
||||||
public boolean lighting = false;
|
public boolean lighting = false;
|
||||||
/** Whether enemy lighting is visible.
|
/** Whether enemy lighting is visible.
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package mindustry.graphics.g3d;
|
package mindustry.graphics.g3d;
|
||||||
|
|
||||||
import arc.graphics.*;
|
import arc.graphics.*;
|
||||||
|
import arc.math.*;
|
||||||
import arc.math.geom.*;
|
import arc.math.geom.*;
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import arc.util.noise.*;
|
import arc.util.noise.*;
|
||||||
@@ -42,6 +43,9 @@ public class HexSkyMesh extends PlanetMesh{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void render(PlanetParams params, Mat3D projection, Mat3D transform){
|
public void render(PlanetParams params, Mat3D projection, Mat3D transform){
|
||||||
|
//don't waste performance rendering 0-alpha clouds
|
||||||
|
if(Mathf.zero(1f - params.uiAlpha, 0.01f)) return;
|
||||||
|
|
||||||
preRender(params);
|
preRender(params);
|
||||||
shader.bind();
|
shader.bind();
|
||||||
shader.setUniformMatrix4("u_proj", projection.val);
|
shader.setUniformMatrix4("u_proj", projection.val);
|
||||||
|
|||||||
@@ -210,7 +210,7 @@ public class PlanetGrid{
|
|||||||
|
|
||||||
static int tileCount(int size){
|
static int tileCount(int size){
|
||||||
return 10 * Mathf.pow(3, size) + 2;
|
return 10 * Mathf.pow(3, size) + 2;
|
||||||
}
|
}///
|
||||||
|
|
||||||
static int cornerCount(int size){
|
static int cornerCount(int size){
|
||||||
return 20 * Mathf.pow(3, size);
|
return 20 * Mathf.pow(3, size);
|
||||||
|
|||||||
@@ -19,8 +19,7 @@ public abstract class PlanetMesh implements GenericMesh{
|
|||||||
|
|
||||||
public PlanetMesh(){}
|
public PlanetMesh(){}
|
||||||
|
|
||||||
/** Should be overridden to set up any shader parameters such as planet position, normals, etc.
|
/** Should be overridden to set up any shader parameters such as planet position, normals, etc. */
|
||||||
* @param params*/
|
|
||||||
public void preRender(PlanetParams params){
|
public void preRender(PlanetParams params){
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -259,15 +259,6 @@ public class FileChooser extends BaseDialog{
|
|||||||
Core.settings.put("lastDirectory", directory.absolutePath());
|
Core.settings.put("lastDirectory", directory.absolutePath());
|
||||||
}
|
}
|
||||||
|
|
||||||
private String shorten(String string){
|
|
||||||
int max = 30;
|
|
||||||
if(string.length() <= max){
|
|
||||||
return string;
|
|
||||||
}else{
|
|
||||||
return string.substring(0, max - 3).concat("...");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class FileHistory{
|
public class FileHistory{
|
||||||
private Seq<Fi> history = new Seq<>();
|
private Seq<Fi> history = new Seq<>();
|
||||||
private int index;
|
private int index;
|
||||||
@@ -305,19 +296,5 @@ public class FileChooser extends BaseDialog{
|
|||||||
public boolean canBack(){
|
public boolean canBack(){
|
||||||
return !(index == 1) && index > 0;
|
return !(index == 1) && index > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void print(){
|
|
||||||
|
|
||||||
System.out.println("\n\n\n\n\n\n");
|
|
||||||
int i = 0;
|
|
||||||
for(Fi file : history){
|
|
||||||
i++;
|
|
||||||
if(index == i){
|
|
||||||
System.out.println("[[" + file.toString() + "]]");
|
|
||||||
}else{
|
|
||||||
System.out.println("--" + file.toString() + "--");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,9 @@ 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 mindustry.*;
|
||||||
import mindustry.core.GameState.*;
|
import mindustry.core.GameState.*;
|
||||||
|
import mindustry.game.*;
|
||||||
import mindustry.game.Saves.*;
|
import mindustry.game.Saves.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
import mindustry.io.*;
|
import mindustry.io.*;
|
||||||
@@ -20,8 +22,12 @@ import java.io.*;
|
|||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
public class LoadDialog extends BaseDialog{
|
public class LoadDialog extends BaseDialog{
|
||||||
ScrollPane pane;
|
|
||||||
Table slots;
|
Table slots;
|
||||||
|
String searchString;
|
||||||
|
Gamemode filteredMode;
|
||||||
|
TextField searchField;
|
||||||
|
ScrollPane pane;
|
||||||
|
BaseDialog dialog;
|
||||||
|
|
||||||
public LoadDialog(){
|
public LoadDialog(){
|
||||||
this("@loadgame");
|
this("@loadgame");
|
||||||
@@ -43,9 +49,38 @@ public class LoadDialog extends BaseDialog{
|
|||||||
|
|
||||||
slots = new Table();
|
slots = new Table();
|
||||||
pane = new ScrollPane(slots);
|
pane = new ScrollPane(slots);
|
||||||
|
|
||||||
|
rebuild();
|
||||||
|
|
||||||
|
Table search = new Table();
|
||||||
|
search.image(Icon.zoom);
|
||||||
|
searchField = search.field("", t -> {
|
||||||
|
searchString = t.length() > 0 ? t.toLowerCase() : null;
|
||||||
|
rebuild();
|
||||||
|
}).maxTextLength(50).growX().get();
|
||||||
|
searchField.setMessageText("@save.search");
|
||||||
|
for(Gamemode mode : Gamemode.all){
|
||||||
|
TextureRegionDrawable icon = Vars.ui.getIcon("mode" + Strings.capitalize(mode.name()));
|
||||||
|
boolean sandbox = mode == Gamemode.sandbox;
|
||||||
|
if(Core.atlas.isFound(icon.getRegion()) || sandbox){
|
||||||
|
search.button(sandbox ? Icon.terrain : icon, Styles.emptytogglei, () -> {
|
||||||
|
filteredMode = filteredMode == mode ? null : mode;
|
||||||
|
rebuild();
|
||||||
|
}).size(60f).checked(b -> filteredMode == mode).tooltip("@mode." + mode.name() + ".name");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pane.setFadeScrollBars(false);
|
pane.setFadeScrollBars(false);
|
||||||
pane.setScrollingDisabled(true, false);
|
pane.setScrollingDisabled(true, false);
|
||||||
|
|
||||||
|
cont.add(search).growX();
|
||||||
|
cont.row();
|
||||||
|
cont.add(pane).growY();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void rebuild(){
|
||||||
|
|
||||||
|
slots.clear();
|
||||||
slots.marginRight(24).marginLeft(20f);
|
slots.marginRight(24).marginLeft(20f);
|
||||||
|
|
||||||
Time.runTask(2f, () -> Core.scene.setScrollFocus(pane));
|
Time.runTask(2f, () -> Core.scene.setScrollFocus(pane));
|
||||||
@@ -58,7 +93,11 @@ public class LoadDialog extends BaseDialog{
|
|||||||
boolean any = false;
|
boolean any = false;
|
||||||
|
|
||||||
for(SaveSlot slot : array){
|
for(SaveSlot slot : array){
|
||||||
if(slot.isHidden()) continue;
|
if(slot.isHidden()
|
||||||
|
|| (searchString != null && !Strings.stripColors(slot.getName()).toLowerCase().contains(searchString))
|
||||||
|
|| (filteredMode != null && filteredMode != slot.mode())){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
any = true;
|
any = true;
|
||||||
|
|
||||||
@@ -82,14 +121,14 @@ public class LoadDialog extends BaseDialog{
|
|||||||
t.button(Icon.trash, Styles.emptyi, () -> {
|
t.button(Icon.trash, Styles.emptyi, () -> {
|
||||||
ui.showConfirm("@confirm", "@save.delete.confirm", () -> {
|
ui.showConfirm("@confirm", "@save.delete.confirm", () -> {
|
||||||
slot.delete();
|
slot.delete();
|
||||||
setup();
|
rebuild();
|
||||||
});
|
});
|
||||||
}).right();
|
}).right();
|
||||||
|
|
||||||
t.button(Icon.pencil, Styles.emptyi, () -> {
|
t.button(Icon.pencil, Styles.emptyi, () -> {
|
||||||
ui.showTextInput("@save.rename", "@save.rename.text", slot.getName(), text -> {
|
ui.showTextInput("@save.rename", "@save.rename.text", slot.getName(), text -> {
|
||||||
slot.setName(text);
|
slot.setName(text);
|
||||||
setup();
|
rebuild();
|
||||||
});
|
});
|
||||||
}).right();
|
}).right();
|
||||||
|
|
||||||
@@ -141,10 +180,8 @@ public class LoadDialog extends BaseDialog{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(!any){
|
if(!any){
|
||||||
slots.button("@save.none", () -> {}).disabled(true).fillX().margin(20f).minWidth(340f).height(80f).pad(4f);
|
slots.add("@save.none");
|
||||||
}
|
}
|
||||||
|
|
||||||
cont.add(pane);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addSetup(){
|
public void addSetup(){
|
||||||
@@ -154,7 +191,7 @@ public class LoadDialog extends BaseDialog{
|
|||||||
if(SaveIO.isSaveValid(file)){
|
if(SaveIO.isSaveValid(file)){
|
||||||
try{
|
try{
|
||||||
control.saves.importSave(file);
|
control.saves.importSave(file);
|
||||||
setup();
|
rebuild();
|
||||||
}catch(IOException e){
|
}catch(IOException e){
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
ui.showException("@save.import.fail", e);
|
ui.showException("@save.import.fail", e);
|
||||||
@@ -193,4 +230,15 @@ public class LoadDialog extends BaseDialog{
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dialog show(){
|
||||||
|
super.show();
|
||||||
|
|
||||||
|
if(Core.app.isDesktop() && searchField != null){
|
||||||
|
Core.scene.setKeyboardFocus(searchField);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,10 @@ public class MapsDialog extends BaseDialog{
|
|||||||
private Table mapTable = new Table();
|
private Table mapTable = new Table();
|
||||||
private TextField searchField;
|
private TextField searchField;
|
||||||
|
|
||||||
private boolean showAll = Core.settings.getBool("editorShowAllMaps", true);
|
private boolean showBuiltIn = Core.settings.getBool("editorshowbuiltinmaps", true);
|
||||||
|
private boolean showCustom = Core.settings.getBool("editorshowcustommaps", true);
|
||||||
|
private boolean searchAuthor = Core.settings.getBool("editorsearchauthor", false);
|
||||||
|
private boolean searchDescription = Core.settings.getBool("editorsearchdescription", false);
|
||||||
|
|
||||||
public MapsDialog(){
|
public MapsDialog(){
|
||||||
super("@maps");
|
super("@maps");
|
||||||
@@ -87,7 +90,7 @@ public class MapsDialog extends BaseDialog{
|
|||||||
String name = map.tags.get("name", () -> {
|
String name = map.tags.get("name", () -> {
|
||||||
String result = "unknown";
|
String result = "unknown";
|
||||||
int number = 0;
|
int number = 0;
|
||||||
while(maps.byName(result + number++) != null);
|
while(maps.byName(result + number++) != null) ;
|
||||||
return result + number;
|
return result + number;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -153,14 +156,21 @@ public class MapsDialog extends BaseDialog{
|
|||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
Seq<Map> mapList = showAll ? Vars.maps.all() : Vars.maps.customMaps();
|
Seq<Map> mapList = showCustom ?
|
||||||
|
showBuiltIn ? maps.all() : maps.customMaps() :
|
||||||
|
showBuiltIn ? maps.defaultMaps() : null;
|
||||||
|
|
||||||
|
if(mapList != null){
|
||||||
for(Map map : mapList){
|
for(Map map : mapList){
|
||||||
|
|
||||||
boolean invalid = false;
|
boolean invalid = false;
|
||||||
for(Gamemode mode : modes){
|
for(Gamemode mode : modes){
|
||||||
invalid |= !mode.valid(map);
|
invalid |= !mode.valid(map);
|
||||||
}
|
}
|
||||||
if(invalid || (searchString != null && !Strings.stripColors(map.name()).toLowerCase().contains(searchString))){
|
if(invalid || (searchString != null
|
||||||
|
&& !Strings.stripColors(map.name()).toLowerCase().contains(searchString)
|
||||||
|
&& (!searchAuthor || !Strings.stripColors(map.author()).toLowerCase().contains(searchString))
|
||||||
|
&& (!searchDescription || !Strings.stripColors(map.description()).toLowerCase().contains(searchString)))){
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,6 +193,7 @@ public class MapsDialog extends BaseDialog{
|
|||||||
|
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(noMapsShown){
|
if(noMapsShown){
|
||||||
mapTable.add("@maps.none");
|
mapTable.add("@maps.none");
|
||||||
@@ -192,30 +203,57 @@ public class MapsDialog extends BaseDialog{
|
|||||||
void showMapFilters(){
|
void showMapFilters(){
|
||||||
dialog = new BaseDialog("@editor.filters");
|
dialog = new BaseDialog("@editor.filters");
|
||||||
dialog.addCloseButton();
|
dialog.addCloseButton();
|
||||||
dialog.setFillParent(false);
|
dialog.cont.table(menu -> {
|
||||||
dialog.cont.table(Tex.button, t -> {
|
menu.add("@editor.filters.mode").width(150f).left();
|
||||||
int i = 0;
|
menu.table(t -> {
|
||||||
for(Gamemode mode : Gamemode.all){
|
for(Gamemode mode : Gamemode.all){
|
||||||
TextureRegionDrawable icon = Vars.ui.getIcon("mode" + Strings.capitalize(mode.name()));
|
TextureRegionDrawable icon = Vars.ui.getIcon("mode" + Strings.capitalize(mode.name()));
|
||||||
if(Core.atlas.isFound(icon.getRegion())){
|
if(Core.atlas.isFound(icon.getRegion())){
|
||||||
t.button(mode.name(), icon, Styles.clearTogglet, () -> {
|
t.button(icon, Styles.emptytogglei, () -> {
|
||||||
if(modes.contains(mode)){
|
if(modes.contains(mode)){
|
||||||
modes.remove(mode);
|
modes.remove(mode);
|
||||||
}else{
|
}else{
|
||||||
modes.add(mode);
|
modes.add(mode);
|
||||||
}
|
}
|
||||||
rebuildMaps();
|
rebuildMaps();
|
||||||
}).size(150f, 60f).marginLeft(6f).checked(modes.contains(mode));
|
}).size(60f).checked(modes.contains(mode)).tooltip("@mode." + mode.name() + ".name");
|
||||||
if(++i % 3 == 0) t.row();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
t.row();
|
}).padBottom(10f);
|
||||||
t.button("@editor.showAll", Styles.clearTogglet, () -> {
|
menu.row();
|
||||||
showAll = !showAll;
|
|
||||||
Core.settings.put("editorShowAllMaps", showAll);
|
menu.add("@editor.filters.type").width(150f).left();
|
||||||
|
menu.table(Tex.button, t -> {
|
||||||
|
t.button("@custom", Styles.clearTogglet, () -> {
|
||||||
|
showCustom = !showCustom;
|
||||||
|
Core.settings.put("editorshowcustommaps", showCustom);
|
||||||
Core.settings.forceSave();
|
Core.settings.forceSave();
|
||||||
rebuildMaps();
|
rebuildMaps();
|
||||||
}).checked(b -> showAll).colspan(3).growX().height(40f);
|
}).size(150f, 60f).checked(showCustom);
|
||||||
|
t.button("@builtin", Styles.clearTogglet, () -> {
|
||||||
|
showBuiltIn = !showBuiltIn;
|
||||||
|
Core.settings.put("editorshowbuiltinmaps", showBuiltIn);
|
||||||
|
Core.settings.forceSave();
|
||||||
|
rebuildMaps();
|
||||||
|
}).size(150f, 60f).checked(showBuiltIn);
|
||||||
|
}).padBottom(10f);
|
||||||
|
menu.row();
|
||||||
|
|
||||||
|
menu.add("@editor.filters.search").width(150f).left();
|
||||||
|
menu.table(Tex.button, t -> {
|
||||||
|
t.button("@editor.filters.author", Styles.clearTogglet, () -> {
|
||||||
|
searchAuthor = !searchAuthor;
|
||||||
|
Core.settings.put("editorsearchauthor", searchAuthor);
|
||||||
|
Core.settings.forceSave();
|
||||||
|
rebuildMaps();
|
||||||
|
}).size(150f, 60f).checked(searchAuthor);
|
||||||
|
t.button("@editor.filters.description", Styles.clearTogglet, () -> {
|
||||||
|
searchDescription = !searchDescription;
|
||||||
|
Core.settings.put("editorsearchdescription", searchDescription);
|
||||||
|
Core.settings.forceSave();
|
||||||
|
rebuildMaps();
|
||||||
|
}).size(150f, 60f).checked(searchDescription);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
dialog.show();
|
dialog.show();
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ public class PlacementFragment extends Fragment{
|
|||||||
boolean gridUpdate(InputHandler input){
|
boolean gridUpdate(InputHandler input){
|
||||||
scrollPositions.put(currentCategory, blockPane.getScrollY());
|
scrollPositions.put(currentCategory, blockPane.getScrollY());
|
||||||
|
|
||||||
if(Core.input.keyTap(Binding.pick) && player.isBuilder()){ //mouse eyedropper select
|
if(Core.input.keyTap(Binding.pick) && player.isBuilder() && !Core.scene.hasDialog()){ //mouse eyedropper select
|
||||||
var build = world.buildWorld(Core.input.mouseWorld().x, Core.input.mouseWorld().y);
|
var build = world.buildWorld(Core.input.mouseWorld().x, Core.input.mouseWorld().y);
|
||||||
Block tryRecipe = build == null ? null : build instanceof ConstructBuild c ? c.current : build.block;
|
Block tryRecipe = build == null ? null : build instanceof ConstructBuild c ? c.current : build.block;
|
||||||
Object tryConfig = build == null || !build.block.copyConfig ? null : build.config();
|
Object tryConfig = build == null || !build.block.copyConfig ? null : build.config();
|
||||||
@@ -445,7 +445,7 @@ public class PlacementFragment extends Fragment{
|
|||||||
}
|
}
|
||||||
|
|
||||||
boolean unlocked(Block block){
|
boolean unlocked(Block block){
|
||||||
return block.unlockedNow() && block.placeablePlayer;
|
return block.unlockedNow() && block.placeablePlayer && (state.rules.hiddenBuildItems.isEmpty() || !Structs.contains(block.requirements, i -> state.rules.hiddenBuildItems.contains(i.item)));
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean hasInfoBox(){
|
boolean hasInfoBox(){
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
package mindustry.ui.fragments;
|
package mindustry.ui.fragments;
|
||||||
|
|
||||||
import arc.*;
|
import arc.*;
|
||||||
|
import arc.graphics.*;
|
||||||
import arc.graphics.g2d.*;
|
import arc.graphics.g2d.*;
|
||||||
import arc.scene.*;
|
import arc.scene.*;
|
||||||
import arc.scene.event.*;
|
import arc.scene.event.*;
|
||||||
import arc.scene.ui.*;
|
import arc.scene.ui.*;
|
||||||
|
import arc.scene.ui.ImageButton.*;
|
||||||
import arc.scene.ui.layout.*;
|
import arc.scene.ui.layout.*;
|
||||||
import arc.struct.*;
|
import arc.struct.*;
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
@@ -115,6 +117,23 @@ public class PlayerListFragment extends Fragment{
|
|||||||
|
|
||||||
button.image(Icon.admin).visible(() -> user.admin && !(!user.isLocal() && net.server())).padRight(5).get().updateVisibility();
|
button.image(Icon.admin).visible(() -> user.admin && !(!user.isLocal() && net.server())).padRight(5).get().updateVisibility();
|
||||||
|
|
||||||
|
var style = new ImageButtonStyle(){{
|
||||||
|
down = Styles.none;
|
||||||
|
up = Styles.none;
|
||||||
|
imageCheckedColor = Pal.accent;
|
||||||
|
imageDownColor = Pal.accent;
|
||||||
|
imageUpColor = Color.white;
|
||||||
|
imageOverColor = Color.lightGray;
|
||||||
|
}};
|
||||||
|
|
||||||
|
var ustyle = new ImageButtonStyle(){{
|
||||||
|
down = Styles.none;
|
||||||
|
up = Styles.none;
|
||||||
|
imageDownColor = Pal.accent;
|
||||||
|
imageUpColor = Color.white;
|
||||||
|
imageOverColor = Color.lightGray;
|
||||||
|
}};
|
||||||
|
|
||||||
if((net.server() || player.admin) && !user.isLocal() && (!user.admin || net.server())){
|
if((net.server() || player.admin) && !user.isLocal() && (!user.admin || net.server())){
|
||||||
button.add().growY();
|
button.add().growY();
|
||||||
|
|
||||||
@@ -123,35 +142,41 @@ public class PlayerListFragment extends Fragment{
|
|||||||
button.table(t -> {
|
button.table(t -> {
|
||||||
t.defaults().size(bs);
|
t.defaults().size(bs);
|
||||||
|
|
||||||
t.button(Icon.hammer, Styles.clearPartiali,
|
t.button(Icon.hammer, ustyle,
|
||||||
() -> ui.showConfirm("@confirm", Core.bundle.format("confirmban", user.name()), () -> Call.adminRequest(user, AdminAction.ban)));
|
() -> ui.showConfirm("@confirm", Core.bundle.format("confirmban", user.name()), () -> Call.adminRequest(user, AdminAction.ban)));
|
||||||
t.button(Icon.cancel, Styles.clearPartiali,
|
t.button(Icon.cancel, ustyle,
|
||||||
() -> ui.showConfirm("@confirm", Core.bundle.format("confirmkick", user.name()), () -> Call.adminRequest(user, AdminAction.kick)));
|
() -> ui.showConfirm("@confirm", Core.bundle.format("confirmkick", user.name()), () -> Call.adminRequest(user, AdminAction.kick)));
|
||||||
|
|
||||||
t.row();
|
t.row();
|
||||||
|
|
||||||
t.button(Icon.admin, Styles.clearTogglePartiali, () -> {
|
t.button(Icon.admin, style, () -> {
|
||||||
if(net.client()) return;
|
if(net.client()) return;
|
||||||
|
|
||||||
String id = user.uuid();
|
String id = user.uuid();
|
||||||
|
|
||||||
if(netServer.admins.isAdmin(id, connection.address)){
|
if(user.admin){
|
||||||
ui.showConfirm("@confirm", Core.bundle.format("confirmunadmin", user.name()), () -> netServer.admins.unAdminPlayer(id));
|
ui.showConfirm("@confirm", Core.bundle.format("confirmunadmin", user.name()), () -> {
|
||||||
|
netServer.admins.unAdminPlayer(id);
|
||||||
|
user.admin = false;
|
||||||
|
});
|
||||||
}else{
|
}else{
|
||||||
ui.showConfirm("@confirm", Core.bundle.format("confirmadmin", user.name()), () -> netServer.admins.adminPlayer(id, user.usid()));
|
ui.showConfirm("@confirm", Core.bundle.format("confirmadmin", user.name()), () -> {
|
||||||
|
netServer.admins.adminPlayer(id, user.usid());
|
||||||
|
user.admin = true;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}).update(b -> b.setChecked(user.admin))
|
}).update(b -> b.setChecked(user.admin))
|
||||||
.disabled(b -> net.client())
|
.disabled(b -> net.client())
|
||||||
.touchable(() -> net.client() ? Touchable.disabled : Touchable.enabled)
|
.touchable(() -> net.client() ? Touchable.disabled : Touchable.enabled)
|
||||||
.checked(user.admin);
|
.checked(user.admin);
|
||||||
|
|
||||||
t.button(Icon.zoom, Styles.clearPartiali, () -> Call.adminRequest(user, AdminAction.trace));
|
t.button(Icon.zoom, ustyle, () -> Call.adminRequest(user, AdminAction.trace));
|
||||||
|
|
||||||
}).padRight(12).size(bs + 10f, bs);
|
}).padRight(12).size(bs + 10f, bs);
|
||||||
}else if(!user.isLocal() && !user.admin && net.client() && Groups.player.size() >= 3 && player.team() == user.team()){ //votekick
|
}else if(!user.isLocal() && !user.admin && net.client() && Groups.player.size() >= 3 && player.team() == user.team()){ //votekick
|
||||||
button.add().growY();
|
button.add().growY();
|
||||||
|
|
||||||
button.button(Icon.hammer, Styles.clearPartiali,
|
button.button(Icon.hammer, ustyle,
|
||||||
() -> {
|
() -> {
|
||||||
ui.showConfirm("@confirm", Core.bundle.format("confirmvotekick", user.name()), () -> {
|
ui.showConfirm("@confirm", Core.bundle.format("confirmvotekick", user.name()), () -> {
|
||||||
Call.sendChatMessage("/votekick " + user.name());
|
Call.sendChatMessage("/votekick " + user.name());
|
||||||
|
|||||||
@@ -120,6 +120,8 @@ public class Block extends UnlockableContent{
|
|||||||
public boolean autoResetEnabled = true;
|
public boolean autoResetEnabled = true;
|
||||||
/** if true, the block stops updating when disabled */
|
/** if true, the block stops updating when disabled */
|
||||||
public boolean noUpdateDisabled = false;
|
public boolean noUpdateDisabled = false;
|
||||||
|
/** if true, this block updates when a payload of a unit. Currently unused! */
|
||||||
|
public boolean updateInUnits = true;
|
||||||
/** Whether to use this block's color in the minimap. Only used for overlays. */
|
/** Whether to use this block's color in the minimap. Only used for overlays. */
|
||||||
public boolean useColor = true;
|
public boolean useColor = true;
|
||||||
/** item that drops from this block, used for drills */
|
/** item that drops from this block, used for drills */
|
||||||
@@ -152,7 +154,7 @@ public class Block extends UnlockableContent{
|
|||||||
public boolean alwaysReplace = false;
|
public boolean alwaysReplace = false;
|
||||||
/** if false, this block can never be replaced. */
|
/** if false, this block can never be replaced. */
|
||||||
public boolean replaceable = true;
|
public boolean replaceable = true;
|
||||||
/** The block group. Unless {@link #canReplace} is overriden, blocks in the same group can replace each other. */
|
/** The block group. Unless {@link #canReplace} is overridden, blocks in the same group can replace each other. */
|
||||||
public BlockGroup group = BlockGroup.none;
|
public BlockGroup group = BlockGroup.none;
|
||||||
/** List of block flags. Used for AI indexing. */
|
/** List of block flags. Used for AI indexing. */
|
||||||
public EnumSet<BlockFlag> flags = EnumSet.of();
|
public EnumSet<BlockFlag> flags = EnumSet.of();
|
||||||
@@ -264,6 +266,7 @@ public class Block extends UnlockableContent{
|
|||||||
/** Main subclass. Non-anonymous. */
|
/** Main subclass. Non-anonymous. */
|
||||||
public @Nullable Class<?> subclass;
|
public @Nullable Class<?> subclass;
|
||||||
|
|
||||||
|
public float selectScroll; //scroll position for certain blocks
|
||||||
public Prov<Building> buildType = null; //initialized later
|
public Prov<Building> buildType = null; //initialized later
|
||||||
public ObjectMap<Class<?>, Cons2> configurations = new ObjectMap<>();
|
public ObjectMap<Class<?>, Cons2> configurations = new ObjectMap<>();
|
||||||
|
|
||||||
|
|||||||
@@ -5,20 +5,29 @@ import arc.scene.style.*;
|
|||||||
import arc.scene.ui.*;
|
import arc.scene.ui.*;
|
||||||
import arc.scene.ui.layout.*;
|
import arc.scene.ui.layout.*;
|
||||||
import arc.struct.*;
|
import arc.struct.*;
|
||||||
|
import arc.util.*;
|
||||||
import mindustry.ctype.*;
|
import mindustry.ctype.*;
|
||||||
import mindustry.gen.*;
|
import mindustry.gen.*;
|
||||||
import mindustry.ui.*;
|
import mindustry.ui.*;
|
||||||
|
import mindustry.world.*;
|
||||||
|
|
||||||
import static mindustry.Vars.*;
|
import static mindustry.Vars.*;
|
||||||
|
|
||||||
public class ItemSelection{
|
public class ItemSelection{
|
||||||
private static float scrollPos = 0f;
|
|
||||||
|
|
||||||
public static <T extends UnlockableContent> void buildTable(Table table, Seq<T> items, Prov<T> holder, Cons<T> consumer){
|
public static <T extends UnlockableContent> void buildTable(Table table, Seq<T> items, Prov<T> holder, Cons<T> consumer){
|
||||||
buildTable(table, items, holder, consumer, true);
|
buildTable(table, items, holder, consumer, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static <T extends UnlockableContent> void buildTable(Block block, Table table, Seq<T> items, Prov<T> holder, Cons<T> consumer){
|
||||||
|
buildTable(block, table, items, holder, consumer, true);
|
||||||
|
}
|
||||||
|
|
||||||
public static <T extends UnlockableContent> void buildTable(Table table, Seq<T> items, Prov<T> holder, Cons<T> consumer, boolean closeSelect){
|
public static <T extends UnlockableContent> void buildTable(Table table, Seq<T> items, Prov<T> holder, Cons<T> consumer, boolean closeSelect){
|
||||||
|
buildTable(null, table, items, holder, consumer, closeSelect);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T extends UnlockableContent> void buildTable(@Nullable Block block, Table table, Seq<T> items, Prov<T> holder, Cons<T> consumer, boolean closeSelect){
|
||||||
|
|
||||||
ButtonGroup<ImageButton> group = new ButtonGroup<>();
|
ButtonGroup<ImageButton> group = new ButtonGroup<>();
|
||||||
group.setMinCheckCount(0);
|
group.setMinCheckCount(0);
|
||||||
@@ -52,10 +61,13 @@ public class ItemSelection{
|
|||||||
|
|
||||||
ScrollPane pane = new ScrollPane(cont, Styles.smallPane);
|
ScrollPane pane = new ScrollPane(cont, Styles.smallPane);
|
||||||
pane.setScrollingDisabled(true, false);
|
pane.setScrollingDisabled(true, false);
|
||||||
pane.setScrollYForce(scrollPos);
|
|
||||||
|
if(block != null){
|
||||||
|
pane.setScrollYForce(block.selectScroll);
|
||||||
pane.update(() -> {
|
pane.update(() -> {
|
||||||
scrollPos = pane.getScrollY();
|
block.selectScroll = pane.getScrollY();
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
pane.setOverscroll(false, false);
|
pane.setOverscroll(false, false);
|
||||||
table.add(pane).maxHeight(Scl.scl(40 * 5));
|
table.add(pane).maxHeight(Scl.scl(40 * 5));
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ public class OverdriveProjector extends Block{
|
|||||||
float realRange = range + phaseHeat * phaseRangeBoost;
|
float realRange = range + phaseHeat * phaseRangeBoost;
|
||||||
|
|
||||||
charge = 0f;
|
charge = 0f;
|
||||||
indexer.eachBlock(this, realRange, other -> true, other -> other.applyBoost(realBoost(), reload + 1f));
|
indexer.eachBlock(this, realRange, other -> other.block.canOverdrive, other -> other.applyBoost(realBoost(), reload + 1f));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(timer(timerUse, useTime) && efficiency() > 0 && consValid()){
|
if(timer(timerUse, useTime) && efficiency() > 0 && consValid()){
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ public class BaseTurret extends Block{
|
|||||||
priority = TargetPriority.turret;
|
priority = TargetPriority.turret;
|
||||||
group = BlockGroup.turrets;
|
group = BlockGroup.turrets;
|
||||||
flags = EnumSet.of(BlockFlag.turret);
|
flags = EnumSet.of(BlockFlag.turret);
|
||||||
|
updateInUnits = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -100,6 +100,7 @@ public class Turret extends ReloadTurret{
|
|||||||
public Turret(String name){
|
public Turret(String name){
|
||||||
super(name);
|
super(name);
|
||||||
liquidCapacity = 20f;
|
liquidCapacity = 20f;
|
||||||
|
quickRotate = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -184,8 +185,8 @@ public class Turret extends ReloadTurret{
|
|||||||
logicControlTime = logicControlCooldown;
|
logicControlTime = logicControlCooldown;
|
||||||
logicShooting = !Mathf.zero(p2);
|
logicShooting = !Mathf.zero(p2);
|
||||||
|
|
||||||
if(p1 instanceof Posc){
|
if(p1 instanceof Posc pos){
|
||||||
targetPosition((Posc)p1);
|
targetPosition(pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ public class PayloadConveyor extends Block{
|
|||||||
if(!enabled) return;
|
if(!enabled) return;
|
||||||
|
|
||||||
if(item != null){
|
if(item != null){
|
||||||
item.update();
|
item.update(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
lastInterp = curInterp;
|
lastInterp = curInterp;
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ public class Sorter extends Block{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void buildConfiguration(Table table){
|
public void buildConfiguration(Table table){
|
||||||
ItemSelection.buildTable(table, content.items(), () -> sortItem, this::configure);
|
ItemSelection.buildTable(Sorter.this, table, content.items(), () -> sortItem, this::configure);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -37,7 +37,9 @@ public class BuildPayload implements Payload{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(){
|
public void update(boolean inUnit){
|
||||||
|
if(inUnit && !build.block.updateInUnits) return;
|
||||||
|
|
||||||
if(build.tile == null) build.tile = emptyTile;
|
if(build.tile == null) build.tile = emptyTile;
|
||||||
build.update();
|
build.update();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import arc.scene.ui.layout.*;
|
|||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import arc.util.io.*;
|
import arc.util.io.*;
|
||||||
import mindustry.*;
|
import mindustry.*;
|
||||||
|
import mindustry.gen.*;
|
||||||
import mindustry.world.*;
|
import mindustry.world.*;
|
||||||
import mindustry.world.blocks.*;
|
import mindustry.world.blocks.*;
|
||||||
import mindustry.world.blocks.storage.*;
|
import mindustry.world.blocks.storage.*;
|
||||||
@@ -55,7 +56,18 @@ public class Constructor extends BlockProducer{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void buildConfiguration(Table table){
|
public void buildConfiguration(Table table){
|
||||||
ItemSelection.buildTable(table, content.blocks().select(Constructor.this::canProduce), () -> recipe, this::configure);
|
ItemSelection.buildTable(Constructor.this, table, content.blocks().select(Constructor.this::canProduce), () -> recipe, this::configure);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onConfigureTileTapped(Building other){
|
||||||
|
if(this == other){
|
||||||
|
deselect();
|
||||||
|
configure(null);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -36,8 +36,9 @@ public interface Payload extends Position{
|
|||||||
/** @return the time taken to build this payload. */
|
/** @return the time taken to build this payload. */
|
||||||
float buildTime();
|
float buildTime();
|
||||||
|
|
||||||
/** update this payload if it is a block */
|
/** update this payload if it is a block
|
||||||
default void update(){}
|
* @param inUnit whether this payload is in a unit */
|
||||||
|
default void update(boolean inUnit){}
|
||||||
|
|
||||||
/** @return whether this payload was dumped. */
|
/** @return whether this payload was dumped. */
|
||||||
default boolean dump(){
|
default boolean dump(){
|
||||||
|
|||||||
@@ -138,7 +138,7 @@ public class PayloadBlock extends Block{
|
|||||||
@Override
|
@Override
|
||||||
public void updateTile(){
|
public void updateTile(){
|
||||||
if(payload != null){
|
if(payload != null){
|
||||||
payload.update();
|
payload.update(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -85,12 +85,23 @@ public class PayloadSource extends PayloadBlock{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void buildConfiguration(Table table){
|
public void buildConfiguration(Table table){
|
||||||
ItemSelection.buildTable(table,
|
ItemSelection.buildTable(PayloadSource.this, table,
|
||||||
content.blocks().select(PayloadSource.this::canProduce).<UnlockableContent>as()
|
content.blocks().select(PayloadSource.this::canProduce).<UnlockableContent>as()
|
||||||
.and(content.units().select(PayloadSource.this::canProduce).as()),
|
.and(content.units().select(PayloadSource.this::canProduce).as()),
|
||||||
() -> (UnlockableContent)config(), this::configure);
|
() -> (UnlockableContent)config(), this::configure);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onConfigureTileTapped(Building other){
|
||||||
|
if(this == other){
|
||||||
|
deselect();
|
||||||
|
configure(null);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object config(){
|
public Object config(){
|
||||||
return unit == null ? block : unit;
|
return unit == null ? block : unit;
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ public class NuclearReactor extends PowerGenerator{
|
|||||||
|
|
||||||
public NuclearReactor(String name){
|
public NuclearReactor(String name){
|
||||||
super(name);
|
super(name);
|
||||||
|
updateInUnits = false;
|
||||||
itemCapacity = 30;
|
itemCapacity = 30;
|
||||||
liquidCapacity = 30;
|
liquidCapacity = 30;
|
||||||
hasItems = true;
|
hasItems = true;
|
||||||
@@ -138,6 +139,7 @@ public class NuclearReactor extends PowerGenerator{
|
|||||||
if((fuel < 5 && heat < 0.5f) || !state.rules.reactorExplosions) return;
|
if((fuel < 5 && heat < 0.5f) || !state.rules.reactorExplosions) return;
|
||||||
|
|
||||||
Effect.shake(6f, 16f, x, y);
|
Effect.shake(6f, 16f, x, y);
|
||||||
|
// * ((float)fuel / itemCapacity) to scale based on fullness
|
||||||
Damage.damage(x, y, explosionRadius * tilesize, explosionDamage * 4);
|
Damage.damage(x, y, explosionRadius * tilesize, explosionDamage * 4);
|
||||||
|
|
||||||
explodeEffect.at(x, y);
|
explodeEffect.at(x, y);
|
||||||
|
|||||||
@@ -280,6 +280,13 @@ public class PowerGraph{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void clear(){
|
||||||
|
all.clear();
|
||||||
|
producers.clear();
|
||||||
|
consumers.clear();
|
||||||
|
batteries.clear();
|
||||||
|
}
|
||||||
|
|
||||||
public void reflow(Building tile){
|
public void reflow(Building tile){
|
||||||
queue.clear();
|
queue.clear();
|
||||||
queue.addLast(tile);
|
queue.addLast(tile);
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ public class ItemSource extends Block{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void buildConfiguration(Table table){
|
public void buildConfiguration(Table table){
|
||||||
ItemSelection.buildTable(table, content.items(), () -> outputItem, this::configure);
|
ItemSelection.buildTable(ItemSource.this, table, content.items(), () -> outputItem, this::configure);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ public class LiquidSource extends Block{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void buildConfiguration(Table table){
|
public void buildConfiguration(Table table){
|
||||||
ItemSelection.buildTable(table, content.liquids(), () -> source, this::configure);
|
ItemSelection.buildTable(LiquidSource.this, table, content.liquids(), () -> source, this::configure);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package mindustry.world.blocks.storage;
|
|||||||
import arc.graphics.*;
|
import arc.graphics.*;
|
||||||
import arc.graphics.g2d.*;
|
import arc.graphics.g2d.*;
|
||||||
import arc.scene.ui.layout.*;
|
import arc.scene.ui.layout.*;
|
||||||
|
import arc.struct.*;
|
||||||
import arc.util.*;
|
import arc.util.*;
|
||||||
import arc.util.io.*;
|
import arc.util.io.*;
|
||||||
import mindustry.entities.units.*;
|
import mindustry.entities.units.*;
|
||||||
@@ -54,44 +55,122 @@ public class Unloader extends Block{
|
|||||||
public class UnloaderBuild extends Building{
|
public class UnloaderBuild extends Building{
|
||||||
public float unloadTimer = 0f;
|
public float unloadTimer = 0f;
|
||||||
public Item sortItem = null;
|
public Item sortItem = null;
|
||||||
public Building dumpingTo;
|
|
||||||
public int offset = 0;
|
public int offset = 0;
|
||||||
public int[] rotations;
|
public int rotations = 0;
|
||||||
|
public Seq<ContainerStat> possibleBlocks = new Seq<>();
|
||||||
|
|
||||||
|
public class ContainerStat{
|
||||||
|
Building building;
|
||||||
|
float loadFactor;
|
||||||
|
boolean canLoad;
|
||||||
|
boolean canUnload;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateTile(){
|
public void updateTile(){
|
||||||
if((unloadTimer += delta()) >= speed){
|
if(((unloadTimer += delta()) < speed) || (proximity.size < 2)) return;
|
||||||
|
Item item = null;
|
||||||
boolean any = false;
|
boolean any = false;
|
||||||
if(rotations == null || rotations.length != proximity.size){
|
int itemslength = content.items().size;
|
||||||
rotations = new int[proximity.size];
|
|
||||||
|
//initialize possibleBlocks only if the new size is bigger than the previous, to avoid unnecessary allocations
|
||||||
|
if(possibleBlocks.size != proximity.size){
|
||||||
|
int tmp = possibleBlocks.size;
|
||||||
|
possibleBlocks.setSize(proximity.size);
|
||||||
|
for(int i = tmp; i < proximity.size; i++){
|
||||||
|
possibleBlocks.set(i, new ContainerStat());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int i = 0; i < proximity.size; i++){
|
if(sortItem != null){
|
||||||
int pos = (offset + i) % proximity.size;
|
item = sortItem;
|
||||||
|
|
||||||
|
for(int pos = 0; pos < proximity.size; pos++){
|
||||||
var other = proximity.get(pos);
|
var other = proximity.get(pos);
|
||||||
|
boolean interactable = other.interactable(team);
|
||||||
|
|
||||||
if(other.interactable(team) && other.block.unloadable && other.canUnload() && other.block.hasItems
|
//set the stats of all buildings in possibleBlocks
|
||||||
&& ((sortItem == null && other.items.total() > 0) || (sortItem != null && other.items.has(sortItem)))){
|
ContainerStat pb = possibleBlocks.get(pos);
|
||||||
//make sure the item can't be dumped back into this block
|
pb.building = other;
|
||||||
dumpingTo = other;
|
pb.canUnload = interactable && other.canUnload() && other.items != null && other.items.has(sortItem);
|
||||||
|
pb.canLoad = interactable && !(other.block instanceof StorageBlock) && other.acceptItem(this, sortItem);
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
//select the next item for nulloaders
|
||||||
|
//inspired of nextIndex() but for all proximity at once, and also way more powerful
|
||||||
|
for(int i = 0; i < itemslength; i++){
|
||||||
|
int total = (rotations + i + 1) % itemslength;
|
||||||
|
boolean hasProvider = false;
|
||||||
|
boolean hasReceiver = false;
|
||||||
|
boolean isDistinct = false;
|
||||||
|
Item possibleItem = content.item(total);
|
||||||
|
|
||||||
//get item to be taken
|
for(int pos = 0; pos < proximity.size; pos++){
|
||||||
Item item = sortItem == null ? other.items.takeIndex(rotations[pos]) : sortItem;
|
var other = proximity.get(pos);
|
||||||
|
boolean interactable = other.interactable(team);
|
||||||
|
|
||||||
//remove item if it's dumped correctly
|
//set the stats of all buildings in possibleBlocks while we are at it
|
||||||
if(put(item)){
|
ContainerStat pb = possibleBlocks.get(pos);
|
||||||
other.items.remove(item, 1);
|
pb.building = other;
|
||||||
|
pb.canUnload = interactable && other.canUnload() && other.items != null && other.items.has(possibleItem);
|
||||||
|
pb.canLoad = interactable && !(other.block instanceof StorageBlock) && other.acceptItem(this, possibleItem);
|
||||||
|
|
||||||
|
//the part handling framerate issues and slow conveyor belts, to avoid skipping items
|
||||||
|
if(hasProvider && pb.canLoad) isDistinct = true;
|
||||||
|
if(hasReceiver && pb.canUnload) isDistinct = true;
|
||||||
|
hasProvider = hasProvider || pb.canUnload;
|
||||||
|
hasReceiver = hasReceiver || pb.canLoad;
|
||||||
|
}
|
||||||
|
if(isDistinct){
|
||||||
|
item = possibleItem;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(item != null){
|
||||||
|
//only compute the load factor if a transfer is possible
|
||||||
|
for(int pos = 0; pos < proximity.size; pos++){
|
||||||
|
ContainerStat pb = possibleBlocks.get(pos);
|
||||||
|
var other = pb.building;
|
||||||
|
pb.loadFactor = (other.getMaximumAccepted(item) == 0) || (other.items == null) ? 0 : other.items.get(item) / (float)other.getMaximumAccepted(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
//sort so it gives full priority to blocks that can give but not receive (mainly plast and storage), and then by load
|
||||||
|
possibleBlocks.sort((e1, e2) -> {
|
||||||
|
// TODO: instead of canLoad it should be ((instance of Storage) || (is it a plast belt i can unload from))
|
||||||
|
// otherwise a 100% full factory will get full priority over the storage/plast, barely an issue but still wasting trades and thus speed
|
||||||
|
int canLoad = Boolean.compare(e2.canLoad, e1.canLoad);
|
||||||
|
return (canLoad != 0) ? canLoad : Float.compare(e1.loadFactor, e2.loadFactor);
|
||||||
|
});
|
||||||
|
|
||||||
|
ContainerStat dumpingFrom = null;
|
||||||
|
ContainerStat dumpingTo = null;
|
||||||
|
|
||||||
|
//choose the building to accept the item
|
||||||
|
for(int i = 0; i < possibleBlocks.size; i++){
|
||||||
|
if(possibleBlocks.get(i).canLoad){
|
||||||
|
dumpingTo = possibleBlocks.get(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//choose the building to give the item
|
||||||
|
for(int i = possibleBlocks.size - 1; i >= 0; i--){
|
||||||
|
if(possibleBlocks.get(i).canUnload){
|
||||||
|
dumpingFrom = possibleBlocks.get(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//trade the items
|
||||||
|
if(dumpingFrom != null && dumpingTo != null && dumpingFrom.loadFactor != dumpingTo.loadFactor){
|
||||||
|
dumpingTo.building.handleItem(this, item);
|
||||||
|
dumpingFrom.building.removeStack(item, 1);
|
||||||
any = true;
|
any = true;
|
||||||
|
|
||||||
if(sortItem == null){
|
|
||||||
rotations[pos] = item.id + 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
other.itemTaken(item);
|
if(sortItem == null) rotations = item.id;
|
||||||
}else if(sortItem == null){
|
|
||||||
rotations[pos] = other.items.nextIndex(rotations[pos]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(any){
|
if(any){
|
||||||
@@ -101,11 +180,10 @@ public class Unloader extends Block{
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(proximity.size > 0){
|
if(proximity.size > 0){
|
||||||
offset ++;
|
offset++;
|
||||||
offset %= proximity.size;
|
offset %= proximity.size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void draw(){
|
public void draw(){
|
||||||
@@ -118,7 +196,7 @@ public class Unloader extends Block{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void buildConfiguration(Table table){
|
public void buildConfiguration(Table table){
|
||||||
ItemSelection.buildTable(table, content.items(), () -> sortItem, this::configure);
|
ItemSelection.buildTable(Unloader.this, table, content.items(), () -> sortItem, this::configure);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -132,11 +210,6 @@ public class Unloader extends Block{
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canDump(Building to, Item item){
|
|
||||||
return !(to.block instanceof StorageBlock) && to != dumpingTo;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Item config(){
|
public Item config(){
|
||||||
return sortItem;
|
return sortItem;
|
||||||
|
|||||||
@@ -231,7 +231,7 @@ public class Reconstructor extends UnitBlock{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean shouldConsume(){
|
public boolean shouldConsume(){
|
||||||
return constructing();
|
return constructing() && enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
public UnitType unit(){
|
public UnitType unit(){
|
||||||
|
|||||||
@@ -160,12 +160,23 @@ public class UnitFactory extends UnitBlock{
|
|||||||
Seq<UnitType> units = Seq.with(plans).map(u -> u.unit).filter(u -> u.unlockedNow() && !u.isBanned());
|
Seq<UnitType> units = Seq.with(plans).map(u -> u.unit).filter(u -> u.unlockedNow() && !u.isBanned());
|
||||||
|
|
||||||
if(units.any()){
|
if(units.any()){
|
||||||
ItemSelection.buildTable(table, units, () -> currentPlan == -1 ? null : plans.get(currentPlan).unit, unit -> configure(plans.indexOf(u -> u.unit == unit)));
|
ItemSelection.buildTable(UnitFactory.this, table, units, () -> currentPlan == -1 ? null : plans.get(currentPlan).unit, unit -> configure(plans.indexOf(u -> u.unit == unit)));
|
||||||
}else{
|
}else{
|
||||||
table.table(Styles.black3, t -> t.add("@none").color(Color.lightGray));
|
table.table(Styles.black3, t -> t.add("@none").color(Color.lightGray));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onConfigureTileTapped(Building other){
|
||||||
|
if(this == other){
|
||||||
|
deselect();
|
||||||
|
configure(null);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean acceptPayload(Building source, Payload payload){
|
public boolean acceptPayload(Building source, Payload payload){
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -68,7 +68,8 @@ public class ConsumePower extends Consume{
|
|||||||
* @return The amount of power which is requested per tick.
|
* @return The amount of power which is requested per tick.
|
||||||
*/
|
*/
|
||||||
public float requestedPower(Building entity){
|
public float requestedPower(Building entity){
|
||||||
if(entity.tile == null || entity.tile.build == null) return 0f;
|
if(entity == null) return 0f;
|
||||||
|
|
||||||
if(buffered){
|
if(buffered){
|
||||||
return (1f-entity.power.status)*capacity;
|
return (1f-entity.power.status)*capacity;
|
||||||
}else{
|
}else{
|
||||||
|
|||||||
@@ -117,7 +117,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "MindustryBR",
|
"name": "MindustryBR",
|
||||||
"address": ["mindustryptbr.ddns.net", "mindustryptbr.myddns.me", "mindustry.me:4447"]
|
"address": ["mindustryptbr.ddns.net", "mindustryptbr.myddns.me", "n2.mindustry.me:4002", "n2.mindustry.me:4007"]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Conservatory",
|
"name": "Conservatory",
|
||||||
|
|||||||
@@ -65,6 +65,10 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "MindustryBR",
|
"name": "MindustryBR",
|
||||||
"address": ["mindustry.me:4451", "n2.mindustry.me:4446"]
|
"address": ["n2.mindustry.me:4003", "n2.mindustry.me:4005", "n2.mindustry.me:4008", "n2.mindustry.me:4009", "n2.mindustry.me:4010"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "LostDustry",
|
||||||
|
"address": ["lostdustry.northeurope.cloudapp.azure.com:6568", "lostdustry.northeurope.cloudapp.azure.com:6569", "lostdustry.northeurope.cloudapp.azure.com:6570"]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
Reference in New Issue
Block a user