Merge branch 'master' of https://github.com/Anuken/Mindustry into 7.0-features
This commit is contained in:
@@ -202,15 +202,20 @@ public class BlockIndexer{
|
||||
}
|
||||
|
||||
public boolean eachBlock(@Nullable Team team, float wx, float wy, float range, Boolf<Building> pred, Cons<Building> cons){
|
||||
breturnArray.clear();
|
||||
|
||||
if(team == null){
|
||||
returnBool = false;
|
||||
|
||||
allBuildings(wx, wy, range, b -> {
|
||||
if(pred.get(b)){
|
||||
breturnArray.add(b);
|
||||
returnBool = true;
|
||||
cons.get(b);
|
||||
}
|
||||
});
|
||||
return returnBool;
|
||||
}else{
|
||||
breturnArray.clear();
|
||||
|
||||
var buildings = team.data().buildings;
|
||||
if(buildings == null) return false;
|
||||
buildings.intersect(wx - range, wy - range, range*2f, range*2f, b -> {
|
||||
|
||||
@@ -2,7 +2,6 @@ package mindustry.ai.types;
|
||||
|
||||
import arc.math.*;
|
||||
import mindustry.ai.*;
|
||||
import mindustry.entities.*;
|
||||
import mindustry.entities.units.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.world.*;
|
||||
@@ -49,13 +48,6 @@ public class GroundAI extends AIController{
|
||||
unit.elevation = Mathf.approachDelta(unit.elevation, 0f, unit.type.riseSpeed);
|
||||
}
|
||||
|
||||
if(!Units.invalidateTarget(target, unit, unit.range()) && unit.type.rotateShooting){
|
||||
if(unit.type.hasWeapons()){
|
||||
unit.lookAt(Predict.intercept(unit, target, unit.type.weapons.first().bullet.speed));
|
||||
}
|
||||
}else if(unit.moving()){
|
||||
unit.lookAt(unit.vel().angle());
|
||||
}
|
||||
|
||||
faceTarget();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,10 +47,10 @@ public class HugAI extends AIController{
|
||||
})){
|
||||
if(unit.within(target, (unit.hitSize + (target instanceof Sized s ? s.hitSize() : 1f)) * 0.6f)){
|
||||
//circle target
|
||||
unit.moveAt(vec.set(target).sub(unit).rotate(90f).setLength(unit.speed()));
|
||||
unit.movePref(vec.set(target).sub(unit).rotate(90f).setLength(unit.speed()));
|
||||
}else{
|
||||
//move toward target in a straight line
|
||||
unit.moveAt(vec.set(target).sub(unit).limit(unit.speed()));
|
||||
unit.movePref(vec.set(target).sub(unit).limit(unit.speed()));
|
||||
}
|
||||
}else if(move){
|
||||
pathfind(Pathfinder.fieldCore);
|
||||
@@ -69,13 +69,6 @@ public class HugAI extends AIController{
|
||||
unit.elevation = Mathf.approachDelta(unit.elevation, 0f, unit.type.riseSpeed);
|
||||
}
|
||||
|
||||
if(!Units.invalidateTarget(target, unit, unit.range()) && unit.type.rotateShooting){
|
||||
if(unit.type.hasWeapons()){
|
||||
unit.lookAt(Predict.intercept(unit, target, unit.type.weapons.first().bullet.speed));
|
||||
}
|
||||
}else if(unit.moving()){
|
||||
unit.lookAt(unit.vel().angle());
|
||||
}
|
||||
|
||||
faceTarget();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,10 +41,6 @@ public class SuicideAI extends GroundAI{
|
||||
shoot = unit.within(target, unit.type.weapons.first().bullet.range() +
|
||||
(target instanceof Building b ? b.block.size * Vars.tilesize / 2f : ((Hitboxc)target).hitSize() / 2f));
|
||||
|
||||
if(unit.type.hasWeapons()){
|
||||
unit.aimLook(Predict.intercept(unit, target, unit.type.weapons.first().bullet.speed));
|
||||
}
|
||||
|
||||
//do not move toward walls or transport blocks
|
||||
if(!(target instanceof Building build && !(build.block instanceof CoreBlock) && (
|
||||
build.block.group == BlockGroup.walls ||
|
||||
@@ -76,7 +72,7 @@ public class SuicideAI extends GroundAI{
|
||||
if(!blocked){
|
||||
moveToTarget = true;
|
||||
//move towards target directly
|
||||
unit.moveAt(vec.set(target).sub(unit).limit(unit.speed()));
|
||||
unit.movePref(vec.set(target).sub(unit).limit(unit.speed()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -103,11 +99,11 @@ public class SuicideAI extends GroundAI{
|
||||
pathfind(Pathfinder.fieldCore);
|
||||
}
|
||||
}
|
||||
|
||||
if(unit.moving()) unit.lookAt(unit.vel().angle());
|
||||
}
|
||||
|
||||
unit.controlWeapons(rotate, shoot);
|
||||
|
||||
faceTarget();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -164,7 +164,7 @@ public class StatusEffects implements ContentList{
|
||||
}};
|
||||
|
||||
boss = new StatusEffect("boss"){{
|
||||
color = Team.sharded.color;
|
||||
color = Team.crux.color;
|
||||
permanent = true;
|
||||
damageMultiplier = 1.3f;
|
||||
healthMultiplier = 1.5f;
|
||||
|
||||
@@ -172,13 +172,19 @@ public class Control implements ApplicationListener, Loadable{
|
||||
|
||||
Events.on(BlockDestroyEvent.class, e -> {
|
||||
if(e.tile.team() == player.team()){
|
||||
state.stats.buildingsDestroyed++;
|
||||
state.stats.buildingsDestroyed ++;
|
||||
}
|
||||
});
|
||||
|
||||
Events.on(UnitDestroyEvent.class, e -> {
|
||||
if(e.unit.team() != player.team()){
|
||||
state.stats.enemyUnitsDestroyed++;
|
||||
state.stats.enemyUnitsDestroyed ++;
|
||||
}
|
||||
});
|
||||
|
||||
Events.on(UnitCreateEvent.class, e -> {
|
||||
if(e.unit.team == state.rules.defaultTeam){
|
||||
state.stats.unitsCreated++;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -149,9 +149,17 @@ public abstract class UnlockableContent extends MappableContent{
|
||||
}
|
||||
}
|
||||
|
||||
public boolean unlockedNowHost(){
|
||||
if(!state.isCampaign()) return true;
|
||||
return net != null && net.client() ?
|
||||
alwaysUnlocked || state.rules.researched.contains(name) :
|
||||
unlocked || alwaysUnlocked;
|
||||
}
|
||||
|
||||
public boolean unlocked(){
|
||||
if(net != null && net.client()) return alwaysUnlocked || state.rules.researched.contains(name);
|
||||
return unlocked || alwaysUnlocked;
|
||||
return net != null && net.client() ?
|
||||
alwaysUnlocked || unlocked || state.rules.researched.contains(name) :
|
||||
unlocked || alwaysUnlocked;
|
||||
}
|
||||
|
||||
/** Locks this content again. */
|
||||
|
||||
@@ -15,6 +15,8 @@ public class MapResizeDialog extends BaseDialog{
|
||||
|
||||
public MapResizeDialog(Intc2 cons){
|
||||
super("@editor.resizemap");
|
||||
|
||||
closeOnBack();
|
||||
shown(() -> {
|
||||
cont.clear();
|
||||
width = editor.width();
|
||||
|
||||
@@ -170,9 +170,8 @@ public class WaveInfoDialog extends BaseDialog{
|
||||
t.remove();
|
||||
updateWaves();
|
||||
}).pad(-6).size(46f).padRight(-12f);
|
||||
}, () -> showUpdate(group)).height(46f).pad(-6f).padBottom(0f);
|
||||
}, () -> showUpdate(group)).height(46f).pad(-6f).padBottom(0f).row();
|
||||
|
||||
t.row();
|
||||
t.table(spawns -> {
|
||||
spawns.field("" + (group.begin + 1), TextFieldFilter.digitsOnly, text -> {
|
||||
if(Strings.canParsePositiveInt(text)){
|
||||
@@ -190,8 +189,8 @@ public class WaveInfoDialog extends BaseDialog{
|
||||
updateWaves();
|
||||
}
|
||||
}).width(100f).get().setMessageText("∞");
|
||||
});
|
||||
t.row();
|
||||
}).row();
|
||||
|
||||
t.table(p -> {
|
||||
p.add("@waves.every").padRight(4);
|
||||
p.field(group.spacing + "", TextFieldFilter.digitsOnly, text -> {
|
||||
@@ -201,9 +200,8 @@ public class WaveInfoDialog extends BaseDialog{
|
||||
}
|
||||
}).width(100f);
|
||||
p.add("@waves.waves").padLeft(4);
|
||||
});
|
||||
}).row();
|
||||
|
||||
t.row();
|
||||
t.table(a -> {
|
||||
a.field(group.unitAmount + "", TextFieldFilter.digitsOnly, text -> {
|
||||
if(Strings.canParsePositiveInt(text)){
|
||||
@@ -220,8 +218,19 @@ public class WaveInfoDialog extends BaseDialog{
|
||||
}
|
||||
}).width(80f);
|
||||
a.add("@waves.perspawn").padLeft(4);
|
||||
});
|
||||
t.row();
|
||||
}).row();
|
||||
|
||||
t.table(a -> {
|
||||
a.field(group.max + "", TextFieldFilter.digitsOnly, text -> {
|
||||
if(Strings.canParsePositiveInt(text)){
|
||||
group.max = Strings.parseInt(text);
|
||||
updateWaves();
|
||||
}
|
||||
}).width(80f);
|
||||
|
||||
a.add("@waves.max").padLeft(5);
|
||||
}).row();
|
||||
|
||||
t.table(a -> {
|
||||
a.field((int)group.shields + "", TextFieldFilter.digitsOnly, text -> {
|
||||
if(Strings.canParsePositiveInt(text)){
|
||||
@@ -238,9 +247,8 @@ public class WaveInfoDialog extends BaseDialog{
|
||||
}
|
||||
}).width(80f);
|
||||
a.add("@waves.shields").padLeft(4);
|
||||
});
|
||||
}).row();
|
||||
|
||||
t.row();
|
||||
t.check("@waves.guardian", b -> group.effect = (b ? StatusEffects.boss : null)).padTop(4).update(b -> b.setChecked(group.effect == StatusEffects.boss)).padBottom(8f);
|
||||
}).width(340f).pad(8);
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import arc.util.*;
|
||||
import mindustry.*;
|
||||
import mindustry.content.*;
|
||||
import mindustry.entities.*;
|
||||
import mindustry.game.EventType.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.graphics.*;
|
||||
import mindustry.type.*;
|
||||
@@ -40,6 +41,7 @@ public class UnitSpawnAbility extends Ability{
|
||||
Unit u = this.unit.create(unit.team);
|
||||
u.set(x, y);
|
||||
u.rotation = unit.rotation;
|
||||
Events.fire(new UnitCreateEvent(u, null, unit));
|
||||
if(!Vars.net.client()){
|
||||
u.add();
|
||||
}
|
||||
|
||||
@@ -76,6 +76,17 @@ abstract class MechComp implements Posc, Flyingc, Hitboxc, Unitc, Mechc, Elevati
|
||||
return raw;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Replace
|
||||
public void rotateMove(Vec2 vec){
|
||||
//mechs use baseRotation to rotate, not rotation.
|
||||
moveAt(Tmp.v2.trns(baseRotation, vec.len()));
|
||||
|
||||
if(!vec.isZero()){
|
||||
baseRotation = Angles.moveToward(baseRotation, vec.angle(), type.rotateSpeed * Math.max(Time.delta, 1));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void moveAt(Vec2 vector, float acceleration){
|
||||
//mark walking state when moving in a controlled manner
|
||||
|
||||
@@ -51,6 +51,15 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I
|
||||
private transient boolean wasPlayer;
|
||||
private transient boolean wasHealed;
|
||||
|
||||
/** Move based on preferred unit movement type. */
|
||||
public void movePref(Vec2 movement){
|
||||
if(type.omniMovement){
|
||||
moveAt(movement);
|
||||
}else{
|
||||
rotateMove(movement);
|
||||
}
|
||||
}
|
||||
|
||||
public void moveAt(Vec2 vector){
|
||||
moveAt(vector, type.accel);
|
||||
}
|
||||
|
||||
@@ -76,6 +76,23 @@ public class AIController implements UnitController{
|
||||
}
|
||||
}
|
||||
|
||||
/** For ground units: Looks at the target, or the movement position. Does not apply to non-omni units. */
|
||||
public void faceTarget(){
|
||||
if(unit.type.omniMovement || unit instanceof Mechc){
|
||||
if(!Units.invalidateTarget(target, unit, unit.range()) && unit.type.rotateShooting && unit.type.hasWeapons()){
|
||||
unit.lookAt(Predict.intercept(unit, target, unit.type.weapons.first().bullet.speed));
|
||||
}else if(unit.moving()){
|
||||
unit.lookAt(unit.vel().angle());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void faceMovement(){
|
||||
if((unit.type.omniMovement || unit instanceof Mechc) && unit.moving()){
|
||||
unit.lookAt(unit.vel().angle());
|
||||
}
|
||||
}
|
||||
|
||||
public boolean invalid(Teamc target){
|
||||
return Units.invalidateTarget(target, unit.team, unit.x, unit.y);
|
||||
}
|
||||
@@ -89,7 +106,7 @@ public class AIController implements UnitController{
|
||||
|
||||
if(tile == targetTile || (costType == Pathfinder.costNaval && !targetTile.floor().isLiquid)) return;
|
||||
|
||||
unit.moveAt(vec.trns(unit.angleTo(targetTile.worldx(), targetTile.worldy()), unit.speed()));
|
||||
unit.movePref(vec.trns(unit.angleTo(targetTile.worldx(), targetTile.worldy()), unit.speed()));
|
||||
}
|
||||
|
||||
public void updateWeapons(){
|
||||
|
||||
25
core/src/mindustry/entities/units/UnitDecal.java
Normal file
25
core/src/mindustry/entities/units/UnitDecal.java
Normal file
@@ -0,0 +1,25 @@
|
||||
package mindustry.entities.units;
|
||||
|
||||
import arc.graphics.*;
|
||||
import mindustry.graphics.*;
|
||||
|
||||
/** A sprite drawn in addition to the base unit sprites. */
|
||||
public class UnitDecal{
|
||||
public String region = "error";
|
||||
public float x, y, rotation;
|
||||
public float layer = Layer.flyingUnit + 1f;
|
||||
public float xScale = 1f, yScale = 1f;
|
||||
public Color color = Color.white;
|
||||
|
||||
public UnitDecal(String region, float x, float y, float rotation, float layer, Color color){
|
||||
this.region = region;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.rotation = rotation;
|
||||
this.layer = layer;
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
public UnitDecal(){
|
||||
}
|
||||
}
|
||||
@@ -411,14 +411,20 @@ public class EventType{
|
||||
}
|
||||
}
|
||||
|
||||
/** Called when a unit is created in a reconstructor or factory. */
|
||||
/** Called when a unit is created in a reconstructor, factory or other unit. */
|
||||
public static class UnitCreateEvent{
|
||||
public final Unit unit;
|
||||
public final Building spawner;
|
||||
public final @Nullable Building spawner;
|
||||
public final @Nullable Unit spawnerUnit;
|
||||
|
||||
public UnitCreateEvent(Unit unit, Building spawner){
|
||||
public UnitCreateEvent(Unit unit, Building spawner, Unit spawnerUnit){
|
||||
this.unit = unit;
|
||||
this.spawner = spawner;
|
||||
this.spawnerUnit = spawnerUnit;
|
||||
}
|
||||
|
||||
public UnitCreateEvent(Unit unit, Building spawner){
|
||||
this(unit, spawner, null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,52 +1,16 @@
|
||||
package mindustry.game;
|
||||
|
||||
import arc.math.*;
|
||||
import arc.struct.*;
|
||||
import mindustry.type.*;
|
||||
|
||||
//TODO more stats:
|
||||
//- units constructed
|
||||
public class GameStats{
|
||||
/** Total items delivered to global resoure counter. Campaign only. */
|
||||
public ObjectIntMap<Item> itemsDelivered = new ObjectIntMap<>();
|
||||
/** Enemy (red team) units destroyed. */
|
||||
public int enemyUnitsDestroyed;
|
||||
/** Total waves lasted. */
|
||||
public int wavesLasted;
|
||||
/** Total (ms) time lasted in this save/zone. */
|
||||
public long timeLasted;
|
||||
/** Friendly buildings fully built. */
|
||||
public int buildingsBuilt;
|
||||
/** Friendly buildings fully deconstructed. */
|
||||
public int buildingsDeconstructed;
|
||||
/** Friendly buildings destroyed. */
|
||||
public int buildingsDestroyed;
|
||||
|
||||
//unused
|
||||
public RankResult calculateRank(Sector sector){
|
||||
float score = 0;
|
||||
|
||||
int rankIndex = Mathf.clamp((int)score, 0, Rank.all.length - 1);
|
||||
Rank rank = Rank.all[rankIndex];
|
||||
String sign = Math.abs((rankIndex + 0.5f) - score) < 0.2f || rank.name().contains("S") ? "" : (rankIndex + 0.5f) < score ? "-" : "+";
|
||||
|
||||
return new RankResult(rank, sign);
|
||||
}
|
||||
|
||||
public static class RankResult{
|
||||
public final Rank rank;
|
||||
/** + or - */
|
||||
public final String modifier;
|
||||
|
||||
public RankResult(Rank rank, String modifier){
|
||||
this.rank = rank;
|
||||
this.modifier = modifier;
|
||||
}
|
||||
}
|
||||
|
||||
public enum Rank{
|
||||
F, D, C, B, A, S, SS;
|
||||
|
||||
public static final Rank[] all = values();
|
||||
}
|
||||
/** Total units created by any means. */
|
||||
public int unitsCreated;
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ public class MenuRenderer implements Disposable{
|
||||
private float time = 0f;
|
||||
private float flyerRot = 45f;
|
||||
private int flyers = Mathf.chance(0.2) ? Mathf.random(35) : Mathf.random(15);
|
||||
private UnitType flyerType = content.units().select(u -> u.hitSize <= 20f && u.flying && u.onTitleScreen && u.region.found()).random();
|
||||
private UnitType flyerType = content.units().select(u -> !u.isHidden() && u.hitSize <= 20f && u.flying && u.onTitleScreen && u.region.found()).random();
|
||||
|
||||
public MenuRenderer(){
|
||||
Time.mark();
|
||||
|
||||
@@ -642,11 +642,7 @@ public class DesktopInput extends InputHandler{
|
||||
unit.lookAt(unit.prefRotation());
|
||||
}
|
||||
|
||||
if(omni){
|
||||
unit.moveAt(movement);
|
||||
}else{
|
||||
unit.rotateMove(movement);
|
||||
}
|
||||
unit.movePref(movement);
|
||||
|
||||
unit.aim(unit.type.faceTarget ? Core.input.mouseWorld() : Tmp.v1.trns(unit.rotation, Core.input.mouseWorld().dst(unit)).add(unit.x, unit.y));
|
||||
unit.controlWeapons(true, player.shooting && !boosted);
|
||||
|
||||
@@ -919,11 +919,7 @@ public class MobileInput extends InputHandler implements GestureListener{
|
||||
|
||||
player.boosting = collisions.overlapsTile(rect) || !unit.within(targetPos, 85f);
|
||||
|
||||
if(omni){
|
||||
unit.moveAt(movement);
|
||||
}else{
|
||||
unit.rotateMove(movement);
|
||||
}
|
||||
unit.movePref(movement);
|
||||
|
||||
//update shooting if not building + not mining
|
||||
if(!player.unit().activelyBuilding() && player.unit().mineTile == null){
|
||||
|
||||
@@ -447,7 +447,7 @@ public class LExecutor{
|
||||
}
|
||||
}
|
||||
case build -> {
|
||||
if(state.rules.logicUnitBuild && unit.canBuild() && exec.obj(p3) instanceof Block block){
|
||||
if(state.rules.logicUnitBuild && unit.canBuild() && exec.obj(p3) instanceof Block block && block.canBeBuilt()){
|
||||
int x = World.toTile(x1 - block.offset/tilesize), y = World.toTile(y1 - block.offset/tilesize);
|
||||
int rot = exec.numi(p4);
|
||||
|
||||
|
||||
@@ -77,6 +77,8 @@ public class UnitType extends UnlockableContent{
|
||||
public Effect fallEffect = Fx.fallSmoke;
|
||||
public Effect fallThrusterEffect = Fx.fallSmoke;
|
||||
public Effect deathExplosionEffect = Fx.dynamicExplosion;
|
||||
/** Additional sprites that are drawn with the unit. */
|
||||
public Seq<UnitDecal> decals = new Seq<>();
|
||||
public Seq<Ability> abilities = new Seq<>();
|
||||
/** Flags to target based on priority. Null indicates that the closest target should be found. The closest enemy core is used as a fallback. */
|
||||
public BlockFlag[] targetFlags = {null};
|
||||
@@ -618,6 +620,18 @@ public class UnitType extends UnlockableContent{
|
||||
unit.trns(-legOffset.x, -legOffset.y);
|
||||
}
|
||||
|
||||
if(decals.size > 0){
|
||||
float base = unit.rotation - 90;
|
||||
for(var d : decals){
|
||||
Draw.z(d.layer);
|
||||
Draw.scl(d.xScale, d.yScale);
|
||||
Draw.color(d.color);
|
||||
Draw.rect(d.region, unit.x + Angles.trnsx(base, d.x, d.y), unit.y + Angles.trnsy(base, d.x, d.y), base + d.rotation);
|
||||
}
|
||||
Draw.reset();
|
||||
Draw.z(z);
|
||||
}
|
||||
|
||||
if(unit.abilities.size > 0){
|
||||
for(Ability a : unit.abilities){
|
||||
Draw.reset();
|
||||
@@ -911,4 +925,5 @@ public class UnitType extends UnlockableContent{
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import arc.*;
|
||||
import mindustry.core.GameState.*;
|
||||
import mindustry.game.EventType.*;
|
||||
import mindustry.game.*;
|
||||
import mindustry.type.*;
|
||||
|
||||
import static mindustry.Vars.*;
|
||||
|
||||
@@ -52,6 +51,7 @@ public class GameOverDialog extends BaseDialog{
|
||||
t.margin(13f);
|
||||
t.left().defaults().left();
|
||||
t.add(Core.bundle.format("stat.wave", state.stats.wavesLasted)).row();
|
||||
t.add(Core.bundle.format("stat.unitsCreated", state.stats.unitsCreated)).row();
|
||||
t.add(Core.bundle.format("stat.enemiesDestroyed", state.stats.enemyUnitsDestroyed)).row();
|
||||
t.add(Core.bundle.format("stat.built", state.stats.buildingsBuilt)).row();
|
||||
t.add(Core.bundle.format("stat.destroyed", state.stats.buildingsDestroyed)).row();
|
||||
@@ -59,17 +59,6 @@ public class GameOverDialog extends BaseDialog{
|
||||
if(control.saves.getCurrent() != null){
|
||||
t.add(Core.bundle.format("stat.playtime", control.saves.getCurrent().getPlayTime())).row();
|
||||
}
|
||||
if(state.isCampaign() && !state.stats.itemsDelivered.isEmpty()){
|
||||
t.add("@stat.delivered").row();
|
||||
for(Item item : content.items()){
|
||||
if(state.stats.itemsDelivered.get(item, 0) > 0){
|
||||
t.table(items -> {
|
||||
items.add(" [lightgray]" + state.stats.itemsDelivered.get(item, 0));
|
||||
items.image(item.uiIcon).size(8 * 3).pad(4);
|
||||
}).left().row();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(state.isCampaign() && net.client()){
|
||||
t.add("@gameover.waiting").padTop(20f).row();
|
||||
|
||||
@@ -540,7 +540,7 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
|
||||
|
||||
//sector notifications & search
|
||||
c.top().right();
|
||||
c.defaults().width(280f);
|
||||
c.defaults().width(290f);
|
||||
|
||||
c.button(bundle.get("sectorlist") +
|
||||
(attacked == 0 ? "" : "\n[red]⚠[lightgray] " + bundle.format("sectorlist.attacked", "[red]" + attacked + "[]")),
|
||||
@@ -588,6 +588,7 @@ public class PlanetDialog extends BaseDialog implements PlanetInterfaceRenderer{
|
||||
for(Sector sec : all){
|
||||
if(sec.hasBase() && (searchText.isEmpty() || sec.name().toLowerCase().contains(searchText.toLowerCase()))){
|
||||
con.button(t -> {
|
||||
t.marginRight(10f);
|
||||
t.left();
|
||||
t.defaults().growX();
|
||||
|
||||
|
||||
@@ -301,6 +301,8 @@ public class SettingsMenuDialog extends Dialog{
|
||||
control.setInput(new DesktopInput());
|
||||
input.setUseKeyboard(true);
|
||||
}
|
||||
}else{
|
||||
Core.settings.put("keyboard", false);
|
||||
}
|
||||
}
|
||||
//the issue with touchscreen support on desktop is that:
|
||||
|
||||
@@ -303,7 +303,7 @@ public class ConstructBlock extends Block{
|
||||
int accumulated = (int)(accumulator[i]); //get amount
|
||||
|
||||
if(clampedAmount > 0 && accumulated > 0){ //if it's positive, add it to the core
|
||||
if(core != null && requirements[i].item.unlockedNow()){ //only accept items that are unlocked
|
||||
if(core != null && requirements[i].item.unlockedNowHost()){ //only accept items that are unlocked
|
||||
int accepting = Math.min(accumulated, core.storageCapacity - core.items.get(requirements[i].item));
|
||||
//transfer items directly, as this is not production.
|
||||
core.items.add(requirements[i].item, accepting);
|
||||
|
||||
@@ -109,13 +109,15 @@ public class PowerNode extends PowerBlock{
|
||||
Core.bundle.format("bar.powerbalance",
|
||||
((entity.power.graph.getPowerBalance() >= 0 ? "+" : "") + UI.formatAmount((long)(entity.power.graph.getPowerBalance() * 60)))),
|
||||
() -> Pal.powerBar,
|
||||
() -> Mathf.clamp(entity.power.graph.getLastPowerProduced() / entity.power.graph.getLastPowerNeeded())));
|
||||
() -> Mathf.clamp(entity.power.graph.getLastPowerProduced() / entity.power.graph.getLastPowerNeeded())
|
||||
));
|
||||
|
||||
bars.add("batteries", entity -> new Bar(() ->
|
||||
Core.bundle.format("bar.powerstored",
|
||||
(UI.formatAmount((long)entity.power.graph.getLastPowerStored())), UI.formatAmount((long)entity.power.graph.getLastCapacity())),
|
||||
() -> Pal.powerBar,
|
||||
() -> Mathf.clamp(entity.power.graph.getLastPowerStored() / entity.power.graph.getLastCapacity())));
|
||||
() -> Mathf.clamp(entity.power.graph.getLastPowerStored() / entity.power.graph.getLastCapacity())
|
||||
));
|
||||
|
||||
bars.add("connections", entity -> new Bar(() ->
|
||||
Core.bundle.format("bar.powerlines", entity.power.links.size, maxNodes),
|
||||
|
||||
@@ -9,6 +9,7 @@ public class PowerVoid extends PowerBlock{
|
||||
super(name);
|
||||
consumes.power(Float.MAX_VALUE);
|
||||
envEnabled = Env.any;
|
||||
enableDrawStatus = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -126,7 +126,7 @@ public class Reconstructor extends UnitBlock{
|
||||
var upgrade = upgrade(pay.unit.type);
|
||||
|
||||
if(upgrade != null){
|
||||
if(!upgrade.unlockedNow()){
|
||||
if(!upgrade.unlockedNowHost()){
|
||||
//flash "not researched"
|
||||
pay.showOverlay(Icon.tree);
|
||||
}
|
||||
@@ -137,7 +137,7 @@ public class Reconstructor extends UnitBlock{
|
||||
}
|
||||
}
|
||||
|
||||
return upgrade != null && upgrade.unlockedNow() && !upgrade.isBanned();
|
||||
return upgrade != null && upgrade.unlockedNowHost() && !upgrade.isBanned();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -232,7 +232,7 @@ public class Reconstructor extends UnitBlock{
|
||||
if(payload == null) return null;
|
||||
|
||||
UnitType t = upgrade(payload.unit.type);
|
||||
return t != null && t.unlockedNow() ? t : null;
|
||||
return t != null && t.unlockedNowHost() ? t : null;
|
||||
}
|
||||
|
||||
public boolean constructing(){
|
||||
@@ -241,7 +241,7 @@ public class Reconstructor extends UnitBlock{
|
||||
|
||||
public boolean hasUpgrade(UnitType type){
|
||||
UnitType t = upgrade(type);
|
||||
return t != null && t.unlockedNow() && !type.isBanned();
|
||||
return t != null && t.unlockedNowHost() && !type.isBanned();
|
||||
}
|
||||
|
||||
public UnitType upgrade(UnitType type){
|
||||
|
||||
@@ -43,7 +43,6 @@ public class ConsumeItemFilter extends Consume{
|
||||
|
||||
@Override
|
||||
public void update(Building entity){
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user