Merge branch 'master' of https://github.com/Anuken/Mindustry into 7.0-features

 Conflicts:
	core/src/mindustry/ui/dialogs/PlanetDialog.java
This commit is contained in:
Anuken
2021-08-13 10:08:34 -04:00
56 changed files with 415 additions and 142 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 144 B

After

Width:  |  Height:  |  Size: 262 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 833 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 148 B

After

Width:  |  Height:  |  Size: 226 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 214 B

After

Width:  |  Height:  |  Size: 363 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 889 B

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 333 B

After

Width:  |  Height:  |  Size: 795 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 278 B

After

Width:  |  Height:  |  Size: 517 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 233 B

After

Width:  |  Height:  |  Size: 329 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 608 B

After

Width:  |  Height:  |  Size: 503 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 241 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 256 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 B

View File

@@ -345,9 +345,9 @@ custom = Custom
builtin = Built-In
map.delete.confirm = Are you sure you want to delete this map? This action cannot be undone!
map.random = [accent]Random Map
map.nospawn = This map does not have any cores for the player to spawn in! Add a[accent] orange[] core to this map in the editor.
map.nospawn = This map does not have any cores for the player to spawn in! Add a [#{0}]{1}[] core to this map in the editor.
map.nospawn.pvp = This map does not have any enemy cores for player to spawn into! Add[scarlet] non-orange[] cores to this map in the editor.
map.nospawn.attack = This map does not have any enemy cores for player to attack! Add[scarlet] red[] cores to this map in the editor.
map.nospawn.attack = This map does not have any enemy cores for player to attack! Add [#{0}]{1}[] cores to this map in the editor.
map.invalid = Error loading map: corrupted or invalid map file.
workshop.update = Update Item
workshop.error = Error fetching workshop details: {0}
@@ -564,6 +564,8 @@ weather.sandstorm.name = Sandstorm
weather.sporestorm.name = Sporestorm
weather.fog.name = Fog
sectorlist = Sectors
sectorlist.attacked = {0} under attack
sectors.unexplored = [lightgray]Unexplored
sectors.resources = Resources:
sectors.production = Production:
@@ -1001,6 +1003,7 @@ rules.wavetimer = Wave Timer
rules.waves = Waves
rules.attack = Attack Mode
rules.buildai = AI Building
rules.aitier = AI Tier
rules.cleanupdeadteams = Clean Up Defeated Team Buildings (PvP)
rules.corecapture = Capture Core On Destruction
rules.polygoncoreprotection = Polygonal Core Protection
@@ -1020,12 +1023,15 @@ rules.deconstructrefundmultiplier = Deconstruct Refund Multiplier
rules.waitForWaveToEnd = Waves Wait for Enemies
rules.dropzoneradius = Drop Zone Radius:[lightgray] (tiles)
rules.unitammo = Units Require Ammo
rules.enemyteam = Enemy Team
rules.playerteam = Player Team
rules.title.waves = Waves
rules.title.resourcesbuilding = Resources & Building
rules.title.enemy = Enemies
rules.title.unit = Units
rules.title.experimental = Experimental
rules.title.environment = Environment
rules.title.teams = Teams
rules.lighting = Lighting
rules.enemyLights = Enemy Lights
rules.fire = Fire

View File

@@ -130,7 +130,12 @@ public class SoundControl{
Core.audio.soundBus.play();
setupFilters();
}else{
Core.audio.soundBus.replay();
//stopping a single audio bus stops everything else, yay!
Core.audio.soundBus.stop();
//play music bus again, as it was stopped above
Core.audio.musicBus.play();
Core.audio.soundBus.play();
}
}

View File

@@ -1975,7 +1975,7 @@ public class Blocks implements ContentList{
despawnEffect = Fx.instBomb;
trailSpacing = 20f;
damage = 1350;
buildingDamageMultiplier = 0.25f;
buildingDamageMultiplier = 0.2f;
speed = brange;
hitShake = 6f;
ammoMultiplier = 1f;
@@ -2049,7 +2049,7 @@ public class Blocks implements ContentList{
loopSound = Sounds.beam;
loopSoundVolume = 2f;
shootType = new ContinuousLaserBulletType(75){{
shootType = new ContinuousLaserBulletType(78){{
length = 200f;
hitEffect = Fx.hitMeltdown;
hitColor = Pal.meltdownHit;
@@ -2230,9 +2230,9 @@ public class Blocks implements ContentList{
payloadPropulsionTower = new PayloadMassDriver("payload-propulsion-tower"){{
requirements(Category.units, with(Items.thorium, 300, Items.silicon, 200, Items.plastanium, 200, Items.phaseFabric, 50));
size = 5;
reloadTime = 140f;
reloadTime = 130f;
chargeTime = 100f;
range = 600f;
range = 1000f;
maxPayloadSize = 3.5f;
consumes.power(6f);
}};

View File

@@ -3,6 +3,7 @@ package mindustry.content;
import arc.graphics.*;
import mindustry.ctype.*;
import mindustry.entities.bullet.*;
import mindustry.entities.effect.*;
import mindustry.graphics.*;
public class Bullets implements ContentList{
@@ -110,6 +111,7 @@ public class Bullets implements ContentList{
backColor = Pal.lightOrange;
makeFire = true;
trailEffect = Fx.incendTrail;
ammoMultiplier = 4f;
}};
artilleryExplosive = new ArtilleryBulletType(2f, 20, "shell"){{
@@ -120,7 +122,7 @@ public class Bullets implements ContentList{
collidesTiles = false;
ammoMultiplier = 4f;
splashDamageRadius = 45f * 0.75f;
splashDamage = 50f;
splashDamage = 55f;
backColor = Pal.missileYellowBack;
frontColor = Pal.missileYellow;
@@ -317,20 +319,26 @@ public class Bullets implements ContentList{
standardHoming = new BasicBulletType(3f, 12, "bullet"){{
width = 7f;
height = 9f;
homingPower = 0.08f;
homingPower = 0.1f;
reloadMultiplier = 1.5f;
ammoMultiplier = 5;
lifetime = 60f;
}};
standardIncendiary = new BasicBulletType(3.2f, 11, "bullet"){{
standardIncendiary = new BasicBulletType(3.2f, 16, "bullet"){{
width = 10f;
height = 12f;
frontColor = Pal.lightishOrange;
backColor = Pal.lightOrange;
status = StatusEffects.burning;
hitEffect = new MultiEffect(Fx.hitBulletSmall, Fx.fireHit);
ammoMultiplier = 5;
splashDamage = 10f;
splashDamageRadius = 22f;
makeFire = true;
inaccuracy = 3f;
lifetime = 60f;
}};
@@ -361,12 +369,15 @@ public class Bullets implements ContentList{
frontColor = Pal.lightishOrange;
backColor = Pal.lightOrange;
status = StatusEffects.burning;
hitEffect = new MultiEffect(Fx.hitBulletSmall, Fx.fireHit);
shootEffect = Fx.shootBig;
makeFire = true;
pierceCap = 2;
pierceBuilding = true;
knockback = 0.7f;
knockback = 0.6f;
ammoMultiplier = 3;
splashDamage = 15f;
splashDamageRadius = 24f;
}};
fireball = new FireBulletType(1f, 4);
@@ -386,7 +397,7 @@ public class Bullets implements ContentList{
hittable = false;
}};
pyraFlame = new BulletType(4f, 50f){{
pyraFlame = new BulletType(4f, 60f){{
ammoMultiplier = 6f;
hitSize = 7f;
lifetime = 18f;

View File

@@ -880,6 +880,16 @@ public class Fx{
Drawf.light(Team.derelict, e.x, e.y, 20f * e.fslope(), Pal.lightFlame, 0.5f);
}),
fireHit = new Effect(35f, e -> {
color(Pal.lightFlame, Pal.darkFlame, e.fin());
randLenVectors(e.id, 3, 2f + e.fin() * 10f, (x, y) -> {
Fill.circle(e.x + x, e.y + y, 0.2f + e.fout() * 1.6f);
});
color();
}),
fireSmoke = new Effect(35f, e -> {
color(Color.gray);

View File

@@ -21,7 +21,7 @@ public class StatusEffects implements ContentList{
burning = new StatusEffect("burning"){{
color = Color.valueOf("ffc455");
damage = 0.12f; //over 8 seconds, this would be ~60 damage
damage = 0.167f;
effect = Fx.burning;
transitionDamage = 8f;

View File

@@ -1137,7 +1137,7 @@ public class UnitTypes implements ContentList{
hitSize = 58f;
destructibleWreck = false;
armor = 13f;
targetFlags = new BlockFlag[]{BlockFlag.reactor, BlockFlag.core, null};
targetFlags = new BlockFlag[]{BlockFlag.reactor, BlockFlag.battery, BlockFlag.core, null};
ammoType = new ItemAmmoType(Items.thorium);
BulletType fragBullet = new FlakBulletType(4f, 5){{

View File

@@ -507,6 +507,11 @@ public class NetClient implements ApplicationListener{
}
}
/** Resets the world data timeout counter. */
public void resetTimeout(){
timeoutTime = 0f;
}
public boolean isConnecting(){
return connecting;
}

View File

@@ -130,7 +130,7 @@ public class UI implements ApplicationListener, Loadable{
@Override
public Seq<AssetDescriptor> getDependencies(){
return Seq.with(new AssetDescriptor<>(Control.class), new AssetDescriptor<>("outline", Font.class), new AssetDescriptor<>("default", Font.class), new AssetDescriptor<>("chat", Font.class));
return Seq.with(new AssetDescriptor<>(Control.class), new AssetDescriptor<>("outline", Font.class), new AssetDescriptor<>("default", Font.class));
}
@Override

View File

@@ -328,8 +328,8 @@ public class World{
invalidMap = false;
if(!headless){
if(state.teams.playerCores().size == 0 && !checkRules.pvp){
ui.showErrorMessage("@map.nospawn");
if(state.teams.cores(checkRules.defaultTeam).size == 0 && !checkRules.pvp){
ui.showErrorMessage(Core.bundle.format("map.nospawn", checkRules.defaultTeam.color, checkRules.defaultTeam.localized()));
invalidMap = true;
}else if(checkRules.pvp){ //pvp maps need two cores to be valid
if(state.teams.getActive().count(TeamData::hasCore) < 2){
@@ -339,7 +339,7 @@ public class World{
}else if(checkRules.attackMode){ //attack maps need two cores to be valid
invalidMap = state.rules.waveTeam.data().noCores();
if(invalidMap){
ui.showErrorMessage("@map.nospawn.attack");
ui.showErrorMessage(Core.bundle.format("map.nospawn.attack", checkRules.waveTeam.color, checkRules.waveTeam.localized()));
}
}
}else{

View File

@@ -42,7 +42,7 @@ public class MapEditorDialog extends Dialog implements Disposable{
private BaseDialog menu;
private Table blockSelection;
private Rules lastSavedRules;
private boolean saved = false;
private boolean saved = false; //currently never read
private boolean shownWithMap = false;
private Seq<Block> blocksOut = new Seq<>();

View File

@@ -196,7 +196,7 @@ public class MapView extends Element implements GestureListener{
if(Core.scene.getScrollFocus() != this) return;
zoom += Core.input.axis(KeyCode.scroll) / 10f * zoom;
zoom += Core.input.axis(Binding.zoom) / 10f * zoom;
clampZoom();
}

View File

@@ -32,7 +32,7 @@ public class UnitSpawnAbility extends Ability{
@Override
public void update(Unit unit){
timer += Time.delta * state.rules.unitBuildSpeedMultiplier;
timer += Time.delta * state.rules.unitBuildSpeed(unit.team);
if(timer >= spawnTime && Units.canCreate(unit.team, this.unit)){
float x = unit.x + Angles.trnsx(unit.rotation, spawnY, spawnX), y = unit.y + Angles.trnsy(unit.rotation, spawnY, spawnX);

View File

@@ -124,11 +124,13 @@ abstract class BuilderComp implements Posc, Statusc, Teamc, Rotc{
return;
}
float bs = 1f / entity.buildCost * Time.delta * type.buildSpeed * buildSpeedMultiplier * state.rules.buildSpeed(team);
//otherwise, update it.
if(current.breaking){
entity.deconstruct(self(), core, 1f / entity.buildCost * Time.delta * type.buildSpeed * buildSpeedMultiplier * state.rules.buildSpeedMultiplier);
entity.deconstruct(self(), core, bs);
}else{
entity.construct(self(), core, 1f / entity.buildCost * Time.delta * type.buildSpeed * buildSpeedMultiplier * state.rules.buildSpeedMultiplier, current.config);
entity.construct(self(), core, bs, current.config);
}
current.stuck = Mathf.equal(current.progress, entity.progress);

View File

@@ -1378,10 +1378,12 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
public void damage(float damage){
if(dead()) return;
if(Mathf.zero(state.rules.blockHealthMultiplier)){
float dm = state.rules.blockHealth(team);
if(Mathf.zero(dm)){
damage = health + 1;
}else{
damage /= state.rules.blockHealthMultiplier;
damage /= dm;
}
Call.tileDamage(self(), health - handleDamage(damage));

View File

@@ -68,8 +68,8 @@ abstract class BulletComp implements Timedc, Damagec, Hitboxc, Teamc, Posc, Draw
@Override
public float damageMultiplier(){
if(owner instanceof Unit u) return u.damageMultiplier() * state.rules.unitDamageMultiplier;
if(owner instanceof Building) return state.rules.blockDamageMultiplier;
if(owner instanceof Unit u) return u.damageMultiplier() * state.rules.unitDamage(team);
if(owner instanceof Building) return state.rules.blockDamage(team);
return 1f;
}

View File

@@ -140,6 +140,26 @@ public class Rules{
}
}
public float unitBuildSpeed(Team team){
return unitBuildSpeedMultiplier * teams.get(team).unitBuildSpeedMultiplier;
}
public float unitDamage(Team team){
return unitDamageMultiplier * teams.get(team).unitDamageMultiplier;
}
public float blockHealth(Team team){
return blockHealthMultiplier * teams.get(team).blockHealthMultiplier;
}
public float blockDamage(Team team){
return blockDamageMultiplier * teams.get(team).blockDamageMultiplier;
}
public float buildSpeed(Team team){
return buildSpeedMultiplier * teams.get(team).buildSpeedMultiplier;
}
/** A team-specific ruleset. */
public static class TeamRule{
/** Whether to use building AI. */
@@ -154,6 +174,19 @@ public class Rules{
public boolean infiniteResources;
/** If true, this team has infinite unit ammo. */
public boolean infiniteAmmo;
/** How fast unit factories build units. */
public float unitBuildSpeedMultiplier = 1f;
/** How much damage any other units deal. */
public float unitDamageMultiplier = 1f;
/** How much health blocks start with. */
public float blockHealthMultiplier = 1f;
/** How much damage blocks (turrets) deal. */
public float blockDamageMultiplier = 1f;
/** Multiplier for building speed. */
public float buildSpeedMultiplier = 1f;
//build cost disabled due to technical complexity
}
/** A simple map for storing TeamRules in an efficient way without hashing. */

View File

@@ -30,8 +30,11 @@ public class Pixelator implements Disposable{
py = Core.camera.position.y;
Core.camera.position.set((int)px + ((int)(camera.width) % 2 == 0 ? 0 : 0.5f), (int)py + ((int)(camera.height) % 2 == 0 ? 0 : 0.5f));
int w = (int)(Core.camera.width * renderer.landScale());
int h = (int)(Core.camera.height * renderer.landScale());
int w = (int)Core.camera.width, h = (int)Core.camera.height;
if(renderer.isCutscene()){
w = (int)(Core.camera.width * renderer.landScale() / renderer.getScale());
h = (int)(Core.camera.height * renderer.landScale() / renderer.getScale());
}
buffer.resize(w, h);

View File

@@ -646,13 +646,6 @@ public class DesktopInput extends InputHandler{
unit.moveAt(movement);
}else{
unit.rotateMove(movement);
unit.moveAt(Tmp.v2.trns(unit.rotation, movement.len()));
//problem: actual unit rotation is controlled by velocity, but velocity is 1) unpredictable and 2) can be set to 0
if(!movement.isZero()){
unit.rotation = Angles.moveToward(unit.rotation, movement.angle(), unit.type.rotateSpeed * Math.max(Time.delta, 1));
}
}
unit.aim(unit.type.faceTarget ? Core.input.mouseWorld() : Tmp.v1.trns(unit.rotation, Core.input.mouseWorld().dst(unit)).add(unit.x, unit.y));

View File

@@ -454,6 +454,10 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
public void update(){
player.typing = ui.chatfrag.shown();
if(player.dead()){
droppingItem = false;
}
if(player.isBuilder()){
player.unit().updateBuilding(isBuilding);
}

View File

@@ -272,6 +272,10 @@ public class Net{
throw new RuntimeException("Received stream chunk without a StreamBegin beforehand!");
}
builder.add(c.data);
ui.loadfrag.setProgress(builder.progress());
netClient.resetTimeout();
if(builder.isDone()){
streams.remove(builder.id);
handleClientReceived(builder.build());

View File

@@ -135,7 +135,7 @@ public class Sector{
@Nullable
public String iconChar(){
if(info.contentIcon != null) return info.contentIcon.emoji();
if(info.icon != null) return Iconc.codes.get(info.icon) + "";
if(info.icon != null) return (char)Iconc.codes.get(info.icon) + "";
return null;
}

View File

@@ -331,7 +331,7 @@ public class UnitType extends UnlockableContent{
singleTarget = weapons.size <= 1 && !forceMultiTarget;
if(itemCapacity < 0){
itemCapacity = Math.max(Mathf.round((int)(hitSize * 4.3), 10), 10);
itemCapacity = Math.max(Mathf.round((int)(hitSize * 4f), 10), 10);
}
//assume slight range margin

View File

@@ -37,7 +37,6 @@ public class Fonts{
public static Font def;
public static Font outline;
public static Font chat;
public static Font icon;
public static Font iconLarge;
public static Font tech;
@@ -76,7 +75,6 @@ public class Fonts{
FreeTypeFontParameter param = fontParameter();
Core.assets.load("default", Font.class, new FreeTypeFontLoaderParameter(mainFont, param)).loaded = f -> Fonts.def = (Font)f;
Core.assets.load("chat", Font.class, new FreeTypeFontLoaderParameter(mainFont, param)).loaded = f -> Fonts.chat = (Font)f;
Core.assets.load("icon", Font.class, new FreeTypeFontLoaderParameter("fonts/icon.ttf", new FreeTypeFontParameter(){{
size = 30;
incremental = true;
@@ -104,7 +102,7 @@ public class Fonts{
}
public static void loadContentIcons(){
Seq<Font> fonts = Seq.with(Fonts.chat, Fonts.def, Fonts.outline);
Seq<Font> fonts = Seq.with(Fonts.def, Fonts.outline);
Texture uitex = Core.atlas.find("logo").texture;
int size = (int)(Fonts.def.getData().lineHeight/Fonts.def.getData().scaleY);

View File

@@ -26,8 +26,8 @@ import static mindustry.gen.Tex.*;
public class Styles{
//TODO all these names are inconsistent and not descriptive
public static Drawable black, black9, black8, black6, black3, black5, none, flatDown, flatOver, accentDrawable;
public static ButtonStyle defaultb, waveb, modsb;
public static TextButtonStyle defaultt, squaret, nodet, cleart, discordt, nonet, infot, clearPartialt, clearTogglet, logicTogglet, clearToggleMenut, togglet, transt, fullTogglet, logict;
public static ButtonStyle defaultb, waveb, modsb, underlineb;
public static TextButtonStyle defaultt, squaret, nodet, cleart, discordt, nonet, infot, clearPartialt, clearTogglet, logicTogglet, clearToggleMenut, togglet, transt, fullTogglet, squareTogglet, logict;
public static ImageButtonStyle defaulti, nodei, righti, emptyi, emptytogglei, selecti, logici, geni, colori, accenti, cleari, clearFulli, clearPartiali, clearPartial2i, clearTogglei, clearTransi, clearToggleTransi, clearTogglePartiali;
public static ScrollPaneStyle defaultPane, horizontalPane, smallPane, nonePane;
public static KeybindDialog.KeybindDialogStyle defaultKeybindDialog;
@@ -62,7 +62,14 @@ public class Styles{
modsb = new ButtonStyle(){{
down = flatOver;
up = underline;
over = underlineWhite;
over = underline2;
}};
underlineb = new ButtonStyle(){{
down = flatOver;
up = sideline;
over = sidelineOver;
checked = flatOver;
}};
waveb = new ButtonStyle(){{
@@ -196,6 +203,16 @@ public class Styles{
disabled = black;
disabledFontColor = Color.gray;
}};
squareTogglet = new TextButtonStyle(){{
font = Fonts.def;
fontColor = Color.white;
checked = flatOver;
down = flatOver;
up = pane;
over = flatOver;
disabled = black;
disabledFontColor = Color.gray;
}};
defaulti = new ImageButtonStyle(){{
down = buttonDown;
up = button;
@@ -340,7 +357,7 @@ public class Styles{
}};
defaultField = new TextFieldStyle(){{
font = Fonts.chat;
font = Fonts.def;
fontColor = Color.white;
disabledFontColor = Color.gray;
disabledBackground = underlineDisabled;
@@ -353,7 +370,7 @@ public class Styles{
}};
nodeField = new TextFieldStyle(){{
font = Fonts.chat;
font = Fonts.def;
fontColor = Color.white;
disabledFontColor = Color.gray;
disabledBackground = underlineDisabled;
@@ -366,7 +383,7 @@ public class Styles{
}};
areaField = new TextFieldStyle(){{
font = Fonts.chat;
font = Fonts.def;
fontColor = Color.white;
disabledFontColor = Color.gray;
selection = Tex.selection;
@@ -377,7 +394,7 @@ public class Styles{
}};
nodeArea = new TextFieldStyle(){{
font = Fonts.chat;
font = Fonts.def;
fontColor = Color.white;
disabledFontColor = Color.gray;
selection = Tex.selection;

View File

@@ -13,6 +13,7 @@ import arc.util.*;
import mindustry.content.*;
import mindustry.ctype.*;
import mindustry.game.*;
import mindustry.game.Rules.*;
import mindustry.gen.*;
import mindustry.graphics.*;
import mindustry.type.*;
@@ -200,6 +201,53 @@ public class CustomRulesDialog extends BaseDialog{
}, () -> ui.picker.show(rules.ambientLight, rules.ambientLight::set)).left().width(250f).row();
main.button("@rules.weather", this::weatherDialog).width(250f).left().row();
title("@rules.title.teams");
team("@rules.playerteam", t -> rules.defaultTeam = t, () -> rules.defaultTeam);
team("@rules.enemyteam", t -> rules.waveTeam = t, () -> rules.waveTeam);
for(Team team : Team.baseTeams){
boolean[] shown = {false};
Table wasMain = main;
main.button("[#" + team.color + "]" + team.localized() + (team.emoji.isEmpty() ? "" : "[] " + team.emoji), Icon.downOpen, Styles.togglet, () -> {
shown[0] = !shown[0];
}).marginLeft(14f).width(260f).height(55f).checked(a -> shown[0]).row();
main.collapser(t -> {
t.left().defaults().fillX().left().pad(5);
main = t;
TeamRule teams = rules.teams.get(team);
number("@rules.blockhealthmultiplier", f -> teams.blockHealthMultiplier = f, () -> teams.blockHealthMultiplier);
number("@rules.blockdamagemultiplier", f -> teams.blockDamageMultiplier = f, () -> teams.blockDamageMultiplier);
check("@rules.buildai", b -> teams.ai = b, () -> teams.ai, () -> team != rules.defaultTeam);
number("@rules.aitier", false, f -> teams.aiTier = f, () -> teams.aiTier, () -> teams.ai, 0, 1);
check("@rules.infiniteresources", b -> teams.infiniteResources = b, () -> teams.infiniteResources);
number("@rules.buildspeedmultiplier", f -> teams.buildSpeedMultiplier = f, () -> teams.buildSpeedMultiplier, 0.001f, 50f);
number("@rules.unitdamagemultiplier", f -> teams.unitDamageMultiplier = f, () -> teams.unitDamageMultiplier);
number("@rules.unitbuildspeedmultiplier", f -> teams.unitBuildSpeedMultiplier = f, () -> teams.unitBuildSpeedMultiplier, 0.001f, 50f);
main = wasMain;
}, () -> shown[0]).growX().row();
}
}
void team(String text, Cons<Team> cons, Prov<Team> prov){
main.table(t -> {
t.left();
t.add(text).left().padRight(5);
for(Team team : Team.baseTeams){
t.button(Tex.whiteui, Styles.clearTogglei, 38f, () -> {
cons.get(team);
}).pad(1f).checked(b -> prov.get() == team).size(60f).tooltip(team.localized()).with(i -> i.getStyle().imageUpColor = team.color);
}
}).padTop(0).row();
}
void number(String text, Floatc cons, Floatp prov){
@@ -218,15 +266,15 @@ public class CustomRulesDialog extends BaseDialog{
number(text, false, cons, prov, condition, 0, Float.MAX_VALUE);
}
//TODO integer param unused
void number(String text, boolean integer, Intc cons, Intp prov, int min, int max){
main.table(t -> {
t.left();
t.add(text).left().padRight(5);
t.field((integer ? prov.get() : prov.get()) + "", s -> cons.get(Strings.parseInt(s)))
t.field((prov.get()) + "", s -> cons.get(Strings.parseInt(s)))
.padRight(100f)
.valid(f -> Strings.parseInt(f) >= min && Strings.parseInt(f) <= max).width(120f).left().addInputDialog();
}).padTop(0);
main.row();
}).padTop(0).row();
}
void number(String text, boolean integer, Floatc cons, Floatp prov, Boolp condition, float min, float max){

View File

@@ -20,6 +20,8 @@ import mindustry.world.*;
import static mindustry.Vars.*;
public class DatabaseDialog extends BaseDialog{
private TextField search;
private Table all = new Table();
public DatabaseDialog(){
super("@database");
@@ -28,28 +30,38 @@ public class DatabaseDialog extends BaseDialog{
addCloseButton();
shown(this::rebuild);
onResize(this::rebuild);
all.margin(20).marginTop(0f);
cont.table(s -> {
s.image(Icon.zoom).padRight(8);
search = s.field(null, text -> rebuild()).growX().get();
search.setMessageText(Core.bundle.get("players.search"));
}).fillX().padBottom(4).row();
cont.pane(all);
}
void rebuild(){
cont.clear();
Table table = new Table();
table.margin(20);
ScrollPane pane = new ScrollPane(table);
all.clear();
var text = search.getText();
Seq<Content>[] allContent = Vars.content.getContentMap();
for(int j = 0; j < allContent.length; j++){
ContentType type = ContentType.all[j];
Seq<Content> array = allContent[j].select(c -> c instanceof UnlockableContent u && (!u.isHidden() || u.node() != null));
Seq<Content> array = allContent[j]
.select(c -> c instanceof UnlockableContent u &&
(!u.isHidden() || u.node() != null) &&
(text.isEmpty() || u.localizedName.toLowerCase().contains(text.toLowerCase())));
if(array.size == 0) continue;
table.add("@content." + type.name() + ".name").growX().left().color(Pal.accent);
table.row();
table.image().growX().pad(5).padLeft(0).padRight(0).height(3).color(Pal.accent);
table.row();
table.table(list -> {
all.add("@content." + type.name() + ".name").growX().left().color(Pal.accent);
all.row();
all.image().growX().pad(5).padLeft(0).padRight(0).height(3).color(Pal.accent);
all.row();
all.table(list -> {
list.left();
int cols = (int)Mathf.clamp((Core.graphics.getWidth() - Scl.scl(30)) / Scl.scl(32 + 10), 1, 22);
@@ -94,10 +106,12 @@ public class DatabaseDialog extends BaseDialog{
}
}
}).growX().left().padBottom(10);
table.row();
all.row();
}
cont.add(pane);
if(all.getChildren().isEmpty()){
all.add("@none.found");
}
}
boolean unlocked(UnlockableContent content){

View File

@@ -53,11 +53,11 @@ public class PausedDialog extends BaseDialog{
ui.host.show();
}
}
}).disabled(b -> !((steam && net.server()) || !net.active())).colspan(2).width(dw * 2 + 20f).update(e -> e.setText(net.server() && steam ? "@invitefriends" : "@hostserver"));
}).disabled(b -> !((steam && net.server()) || !net.active())).colspan(2).width(dw * 2 + 10f).update(e -> e.setText(net.server() && steam ? "@invitefriends" : "@hostserver"));
cont.row();
cont.button("@quit", Icon.exit, this::showQuitConfirm).colspan(2).width(dw + 20f).update(s -> s.setText(control.saves.getCurrent() != null && control.saves.getCurrent().isAutosave() ? "@save.quit" : "@quit"));
cont.button("@quit", Icon.exit, this::showQuitConfirm).colspan(2).width(dw + 10f).update(s -> s.setText(control.saves.getCurrent() != null && control.saves.getCurrent().isAutosave() ? "@save.quit" : "@quit"));
}else{
cont.defaults().size(130f).pad(5);

View File

@@ -62,9 +62,10 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
public Seq<Sector> newPresets = new Seq<>();
public float presetShow = 0f;
public boolean showed = false;
public boolean showed = false, sectorsShown;
public String searchText = "";
public Table sectorTop = new Table();
public Table sectorTop = new Table(), notifs;
public Label hoverLabel = new Label("");
public PlanetDialog(){
@@ -74,17 +75,22 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
planets.planet = content.getByName(ContentType.planet, Core.settings.getString("lastplanet", "serpulo"));
if(planets.planet == null) planets.planet = Planets.serpulo;
keyDown(key -> {
if(key == KeyCode.escape || key == KeyCode.back || key == Core.keybinds.get(Binding.planet_map).key){
if(showing() && newPresets.size > 1){
//clear all except first, which is the last sector.
newPresets.truncate(1);
}else if(selected != null){
selected = null;
updateSelected();
}else{
Core.app.post(this::hide);
addListener(new InputListener(){
@Override
public boolean keyDown(InputEvent event, KeyCode key){
if(event.targetActor == PlanetDialog.this && (key == KeyCode.escape || key == KeyCode.back || key == Core.keybinds.get(Binding.planet_map).key)){
if(showing() && newPresets.size > 1){
//clear all except first, which is the last sector.
newPresets.truncate(1);
}else if(selected != null){
selected = null;
updateSelected();
}else{
Core.app.post(() -> hide());
}
return true;
}
return false;
}
});
@@ -121,8 +127,14 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
pos.rotate(Tmp.v31.set(planets.cam.up).rotate(planets.cam.direction, 90), amount);
});
scrolled(value -> {
zoom = Mathf.clamp(zoom + value / 10f, planets.planet.minZoom, 2f);
addListener(new InputListener(){
@Override
public boolean scrolled(InputEvent event, float x, float y, float amountX, float amountY){
if(event.targetActor == PlanetDialog.this){
zoom = Mathf.clamp(zoom + y / 10f, planets.planet.minZoom, 2f);
}
return true;
}
});
addCaptureListener(new ElementGestureListener(){
@@ -452,6 +464,7 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
}
void setup(){
searchText = "";
zoom = planets.zoom = 1f;
selectAlpha = 1f;
ui.minimapfrag.hide();
@@ -484,13 +497,19 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
});
}
@Override
public void act(float delta){
if(scene.getDialog() == PlanetDialog.this && !scene.hit(input.mouseX(), input.mouseY(), true).isDescendantOf(e -> e instanceof ScrollPane)){
scene.setScrollFocus(PlanetDialog.this);
}
super.act(delta);
}
@Override
public void draw(){
planets.orbitAlpha = selectAlpha;
planets.render(PlanetDialog.this);
if(Core.scene.getDialog() == PlanetDialog.this){
Core.scene.setScrollFocus(PlanetDialog.this);
}
}
},
//info text
@@ -516,7 +535,7 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
selected = null;
launchSector = null;
renderer.planets.planet = planet;
Core.settings.put("lastplanet", planet.name);
settings.put("lastplanet", planet.name);
}).width(200).height(40).growX().update(bb -> bb.setChecked(renderer.planets.planet == planet));
pt.row();
}
@@ -525,11 +544,95 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
}
}),
new Table(t -> {
t.top();
//t.add(sectorTop);
})).grow();
new Table(c -> {
if(!(graphics.isPortrait() && mobile) && planets.planet.sectors.contains(Sector::hasBase)){
int attacked = planets.planet.sectors.count(Sector::isAttacked);
//sector notifications & search
c.top().right();
c.defaults().width(280f);
c.button(bundle.get("sectorlist") +
(attacked == 0 ? "" : "\n[red]⚠[lightgray] " + bundle.format("sectorlist.attacked", "[red]" + attacked + "[]")),
Icon.downOpen, Styles.squareTogglet, () -> sectorsShown = !sectorsShown)
.height(60f).checked(b -> {
Image image = (Image)b.getCells().first().get();
image.setDrawable(sectorsShown ? Icon.upOpen : Icon.downOpen);
return sectorsShown;
}).with(t -> t.left().margin(7f)).with(t -> t.getLabelCell().grow().left()).row();
c.collapser(t -> {
t.background(Styles.black8);
notifs = t;
rebuildList();
}, false, () -> sectorsShown).padBottom(64f).row();
}
})).grow();
}
//TODO
void rebuildList(){
notifs.clear();
var all = planets.planet.sectors.select(Sector::hasBase);
all.sort(Structs.comps(Structs.comparingBool(s -> !s.isAttacked()), Structs.comparingInt(s -> s.save == null ? 0 : -(int)s.save.meta.timePlayed)));
notifs.pane(p -> {
Runnable[] readd = {null};
p.table(s -> {
s.image(Icon.zoom).padRight(4);
s.field(searchText, t -> {
searchText = t;
readd[0].run();
}).growX().height(50f).addInputDialog();
}).growX().row();
Table con = p.table().growX().get();
con.touchable = Touchable.enabled;
readd[0] = () -> {
con.clearChildren();
for(Sector sec : all){
if(sec.hasBase() && (searchText.isEmpty() || sec.name().toLowerCase().contains(searchText.toLowerCase()))){
con.button(t -> {
t.left();
t.defaults().growX();
t.table(head -> {
head.left().defaults();
if(sec.isAttacked()){
head.image(Icon.warningSmall).update(i -> {
i.color.set(Pal.accent).lerp(Pal.remove, Mathf.absin(Time.globalTime, 9f, 1f));
}).padRight(4f);
}
String ic = sec.iconChar() == null ? "" : sec.iconChar() + " ";
head.add(ic + sec.name()).growX().wrap();
}).growX().row();
if(sec.isAttacked()){
addSurvivedInfo(sec, t, true);
}
}, Styles.underlineb, () -> {
lookAt(sec);
selected = sec;
updateSelected();
}).margin(8f).marginLeft(13f).marginBottom(6f).marginTop(6f).padBottom(3f).padTop(3f).growX().checked(b -> selected == sec).row();
//for resources: .tooltip(sec.info.resources.toString("", u -> u.emoji()))
}
}
if(con.getChildren().isEmpty()){
con.add("@none.found").pad(10f);
}
};
readd[0].run();
}).grow().get().setScrollingDisabled(true, false);
}
@Override
@@ -738,6 +841,19 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
dialog.show();
}
void addSurvivedInfo(Sector sector, Table table, boolean wrap){
if(!wrap){
table.add(Core.bundle.format("sectors.underattack", (int)(sector.info.damage * 100))).wrapLabel(wrap).row();
}
if(sector.info.wavesSurvived >= 0 && sector.info.wavesSurvived - sector.info.wavesPassed >= 0 && !sector.isBeingPlayed()){
int toCapture = sector.info.attack || sector.info.winWave <= 1 ? -1 : sector.info.winWave - (sector.info.wave + sector.info.wavesPassed);
boolean plus = (sector.info.wavesSurvived - sector.info.wavesPassed) >= SectorDamage.maxRetWave - 1;
table.add(Core.bundle.format("sectors.survives", Math.min(sector.info.wavesSurvived - sector.info.wavesPassed, toCapture <= 0 ? 200 : toCapture) +
(plus ? "+" : "") + (toCapture < 0 ? "" : "/" + toCapture))).wrapLabel(wrap).row();
}
}
void updateSelected(){
Sector sector = selected;
Table stable = sectorTop;
@@ -762,6 +878,7 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
ui.showTextInput("@sectors.rename", "@name", 20, sector.name(), v -> {
sector.setName(v);
updateSelected();
rebuildList();
});
}).size(40f).padLeft(4);
}
@@ -774,6 +891,14 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
new Dialog(""){{
closeOnBack();
setFillParent(true);
Runnable refresh = () -> {
sector.saveInfo();
hide();
updateSelected();
rebuildList();
};
cont.pane(t -> {
resized(true, () -> {
t.clearChildren();
@@ -783,9 +908,7 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
t.button(Icon.none, Styles.clearTogglei, () -> {
sector.info.icon = null;
sector.info.contentIcon = null;
sector.saveInfo();
hide();
updateSelected();
refresh.run();
}).checked(sector.info.icon == null && sector.info.contentIcon == null);
int cols = (int)Math.min(20, Core.graphics.getWidth() / Scl.scl(52f));
@@ -797,9 +920,7 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
t.button(value, Styles.clearTogglei, () -> {
sector.info.icon = key;
sector.info.contentIcon = null;
sector.saveInfo();
hide();
updateSelected();
refresh.run();
}).checked(key.equals(sector.info.icon));
if(++i % cols == 0) t.row();
@@ -816,9 +937,7 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
t.button(new TextureRegionDrawable(u.uiIcon), Styles.clearTogglei, iconMed, () -> {
sector.info.icon = null;
sector.info.contentIcon = u;
sector.saveInfo();
hide();
updateSelected();
refresh.run();
}).checked(sector.info.contentIcon == u);
if(++i % cols == 0) t.row();
@@ -853,16 +972,7 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
}
if(sector.isAttacked()){
stable.add(Core.bundle.format("sectors.underattack", (int)(sector.info.damage * 100)));
stable.row();
if(sector.info.wavesSurvived >= 0 && sector.info.wavesSurvived - sector.info.wavesPassed >= 0 && !sector.isBeingPlayed()){
int toCapture = sector.info.attack || sector.info.winWave <= 1 ? -1 : sector.info.winWave - (sector.info.wave + sector.info.wavesPassed);
boolean plus = (sector.info.wavesSurvived - sector.info.wavesPassed) >= SectorDamage.maxRetWave - 1;
stable.add(Core.bundle.format("sectors.survives", Math.min(sector.info.wavesSurvived - sector.info.wavesPassed, toCapture <= 0 ? 200 : toCapture) +
(plus ? "+" : "") + (toCapture < 0 ? "" : "/" + toCapture)));
stable.row();
}
addSurvivedInfo(sector, stable, false);
}else if(sector.hasBase() && sector.near().contains(Sector::hasEnemyBase)){
stable.add("@sectors.vulnerable");
stable.row();
@@ -899,6 +1009,8 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
stable.pack();
stable.setPosition(x, y, Align.center);
//do not fade out for now, TODO remove?
/*
stable.update(() -> {
if(selected != null){
if(launching){
@@ -918,7 +1030,7 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
}
}
}
});
});*/
stable.act(0f);
}

View File

@@ -69,7 +69,7 @@ public class SchematicsDialog extends BaseDialog{
searchField = s.field(search, res -> {
search = res;
rebuildPane.run();
}).growX().get();
}).growX().addInputDialog().get();
}).fillX().padBottom(4);
cont.row();

View File

@@ -9,6 +9,7 @@ import arc.math.*;
import arc.scene.*;
import arc.scene.ui.*;
import arc.scene.ui.Label.*;
import arc.scene.ui.TextField.*;
import arc.scene.ui.layout.*;
import arc.struct.*;
import arc.util.*;
@@ -18,7 +19,6 @@ import mindustry.input.*;
import mindustry.ui.*;
import static arc.Core.*;
import static mindustry.Vars.net;
import static mindustry.Vars.*;
public class ChatFragment extends Table{
@@ -104,10 +104,9 @@ public class ChatFragment extends Table{
fieldlabel.getStyle().font = font;
fieldlabel.setStyle(fieldlabel.getStyle());
chatfield = new TextField("", new TextField.TextFieldStyle(scene.getStyle(TextField.TextFieldStyle.class)));
chatfield = new TextField("", new TextFieldStyle(scene.getStyle(TextFieldStyle.class)));
chatfield.setMaxLength(Vars.maxTextLength);
chatfield.getStyle().background = null;
chatfield.getStyle().font = Fonts.chat;
chatfield.getStyle().fontColor = Color.white;
chatfield.setStyle(chatfield.getStyle());

View File

@@ -48,7 +48,7 @@ public class HintsFragment extends Fragment{
}else if(!current.show()){ //current became hidden
hide();
}
}else if(hints.size > 0){
}else if(hints.size > 0 && !renderer.isCutscene()){
//check one hint each frame to see if it should be shown.
Hint hint = hints.find(Hint::show);
if(hint != null && hint.complete()){
@@ -163,7 +163,7 @@ public class HintsFragment extends Fragment{
schematicSelect(visibleDesktop, () -> ui.hints.placedBlocks.contains(Blocks.router), () -> Core.input.keyRelease(Binding.schematic_select) || Core.input.keyTap(Binding.pick)),
conveyorPathfind(() -> control.input.block == Blocks.titaniumConveyor, () -> Core.input.keyRelease(Binding.diagonal_placement) || (mobile && Core.settings.getBool("swapdiagonal"))),
boost(visibleDesktop, () -> !player.dead() && player.unit().type.canBoost, () -> Core.input.keyDown(Binding.boost)),
blockInfo(() -> true, () -> ui.content.isShown()),
blockInfo(() -> !(state.isCampaign() && state.rules.sector == SectorPresets.groundZero.sector && state.wave < 3), () -> ui.content.isShown()),
derelict(() -> ui.hints.events.contains("derelictmouse"), () -> false),
command(() -> state.rules.defaultTeam.data().units.size > 3 && !net.active(), () -> player.unit().isCommanding()),
payloadPickup(() -> !player.unit().dead && player.unit() instanceof Payloadc p && p.payloads().isEmpty(), () -> player.unit() instanceof Payloadc p && p.payloads().any()),

View File

@@ -17,6 +17,7 @@ public class LoadingFragment extends Fragment{
private TextButton button;
private Bar bar;
private Label nameLabel;
private float progValue;
@Override
public void build(Group parent){
@@ -55,6 +56,13 @@ public class LoadingFragment extends Fragment{
bar.set(() -> ((int)(progress.get() * 100) + "%"), progress, Pal.accent);
}
public void setProgress(float progress){
progValue = progress;
if(!bar.visible){
setProgress(() -> progValue);
}
}
public void setButton(Runnable listener){
button.visible = true;
button.getListeners().remove(button.getListeners().size - 1);

View File

@@ -20,7 +20,7 @@ public class PlayerListFragment extends Fragment{
public Table content = new Table().marginRight(13f).marginLeft(13f);
private boolean visible = false;
private Interval timer = new Interval();
private TextField sField;
private TextField search;
private Seq<Player> players = new Seq<>();
@Override
@@ -47,12 +47,9 @@ public class PlayerListFragment extends Fragment{
cont.table(Tex.buttonTrans, pane -> {
pane.label(() -> Core.bundle.format(Groups.player.size() == 1 ? "players.single" : "players", Groups.player.size()));
pane.row();
sField = pane.field(null, text -> {
rebuild();
}).grow().pad(8).get();
sField.name = "search";
sField.setMaxLength(maxNameLength);
sField.setMessageText(Core.bundle.format("players.search"));
search = pane.field(null, text -> rebuild()).grow().pad(8).name("search").maxTextLength(maxNameLength).get();
search.setMessageText(Core.bundle.get("players.search"));
pane.row();
pane.pane(content).grow().get().setScrollingDisabled(true, false);
@@ -83,8 +80,8 @@ public class PlayerListFragment extends Fragment{
Groups.player.copy(players);
players.sort(Structs.comps(Structs.comparing(Player::team), Structs.comparingBool(p -> !p.admin)));
if(sField.getText().length() > 0){
players.filter(p -> Strings.stripColors(p.name().toLowerCase()).contains(sField.getText().toLowerCase()));
if(search.getText().length() > 0){
players.filter(p -> Strings.stripColors(p.name().toLowerCase()).contains(search.getText().toLowerCase()));
}
for(var user : players){
@@ -181,7 +178,7 @@ public class PlayerListFragment extends Fragment{
rebuild();
}else{
Core.scene.setKeyboardFocus(null);
sField.clearText();
search.clearText();
}
}

View File

@@ -8,6 +8,7 @@ import arc.math.*;
import arc.scene.*;
import arc.scene.ui.*;
import arc.scene.ui.Label.*;
import arc.scene.ui.TextField.*;
import arc.scene.ui.layout.*;
import arc.struct.*;
import arc.util.*;
@@ -93,9 +94,8 @@ public class ScriptConsoleFragment extends Table{
fieldlabel.getStyle().font = font;
fieldlabel.setStyle(fieldlabel.getStyle());
chatfield = new TextField("", new TextField.TextFieldStyle(scene.getStyle(TextField.TextFieldStyle.class)));
chatfield = new TextField("", new TextFieldStyle(scene.getStyle(TextFieldStyle.class)));
chatfield.getStyle().background = null;
chatfield.getStyle().font = Fonts.chat;
chatfield.getStyle().fontColor = Color.white;
chatfield.setStyle(chatfield.getStyle());

View File

@@ -141,7 +141,7 @@ public class LaunchPad extends Block{
public void display(Table table){
super.display(table);
if(!state.isCampaign() || net.client()) return;
if(!state.isCampaign() || net.client() || team != player.team()) return;
table.row();
table.label(() -> {

View File

@@ -93,7 +93,9 @@ public class MessageBlock extends Block{
text = message.toString();
multiline = true;
maxLength = maxTextLength;
accepted = str -> configure(str);
accepted = str -> {
if(!str.equals(text)) configure(str);
};
}});
}else{
BaseDialog dialog = new BaseDialog("@editmessage");
@@ -113,7 +115,7 @@ public class MessageBlock extends Block{
});
a.setMaxLength(maxTextLength);
dialog.buttons.button("@ok", () -> {
configure(a.getText());
if(!a.getText().equals(message.toString())) configure(a.getText());
dialog.hide();
}).size(130f, 60f);
dialog.update(() -> {

View File

@@ -197,7 +197,7 @@ public class Reconstructor extends UnitBlock{
if(moveInPayload()){
if(consValid()){
valid = true;
progress += edelta() * state.rules.unitBuildSpeedMultiplier;
progress += edelta() * state.rules.unitBuildSpeed(team);
}
//upgrade the unit
@@ -214,7 +214,7 @@ public class Reconstructor extends UnitBlock{
}
speedScl = Mathf.lerpDelta(speedScl, Mathf.num(valid), 0.05f);
time += edelta() * speedScl * state.rules.unitBuildSpeedMultiplier;
time += edelta() * speedScl * state.rules.unitBuildSpeed(team);
}
@Override

View File

@@ -213,8 +213,8 @@ public class UnitFactory extends UnitBlock{
}
if(consValid() && currentPlan != -1){
time += edelta() * speedScl * Vars.state.rules.unitBuildSpeedMultiplier;
progress += edelta() * Vars.state.rules.unitBuildSpeedMultiplier;
time += edelta() * speedScl * Vars.state.rules.unitBuildSpeed(team);
progress += edelta() * Vars.state.rules.unitBuildSpeed(team);
speedScl = Mathf.lerpDelta(speedScl, 1f, 0.05f);
}else{
speedScl = Mathf.lerpDelta(speedScl, 0f, 0.05f);

View File

@@ -49,11 +49,7 @@ public class StatValues{
public static StatValue liquids(Boolf<Liquid> filter, float amount, boolean perSecond){
return table -> {
Seq<Liquid> list = new Seq<>();
for(Liquid item : content.liquids()){
if(!item.isHidden() && filter.get(item)) list.add(item);
}
Seq<Liquid> list = content.liquids().select(i -> filter.get(i) && i.unlockedNow());
for(int i = 0; i < list.size; i++){
table.add(new LiquidDisplay(list.get(i), amount, perSecond)).padRight(5);
@@ -91,7 +87,7 @@ public class StatValues{
public static StatValue items(float timePeriod, Boolf<Item> filter){
return table -> {
Seq<Item> list = content.items().select(filter);
Seq<Item> list = content.items().select(i -> filter.get(i) && i.unlockedNow());
for(int i = 0; i < list.size; i++){
Item item = list.get(i);