Merge branch 'master' of https://github.com/Anuken/Mindustry into 7.0-features
Conflicts: core/src/mindustry/world/blocks/environment/Floor.java core/src/mindustry/world/blocks/payloads/Payload.java gradle.properties
This commit is contained in:
@@ -24,10 +24,8 @@ import mindustry.logic.*;
|
||||
import mindustry.maps.Map;
|
||||
import mindustry.maps.*;
|
||||
import mindustry.mod.*;
|
||||
import mindustry.net.Net;
|
||||
import mindustry.net.*;
|
||||
import mindustry.service.*;
|
||||
import mindustry.world.*;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.charset.*;
|
||||
@@ -113,8 +111,6 @@ public class Vars implements Loadable{
|
||||
public static final float tilePayload = tilesize * tilesize;
|
||||
/** icon sizes for UI */
|
||||
public static final float iconXLarge = 8*6f, iconLarge = 8*5f, iconMed = 8*4f, iconSmall = 8*3f;
|
||||
/** tile used in certain situations, instead of null */
|
||||
public static Tile emptyTile;
|
||||
/** for map generator dialog */
|
||||
public static boolean updateEditorOnChange = false;
|
||||
/** all choosable player colors in join/host dialog */
|
||||
@@ -278,7 +274,6 @@ public class Vars implements Loadable{
|
||||
schematicDirectory = dataDirectory.child("schematics/");
|
||||
bebuildDirectory = dataDirectory.child("be_builds/");
|
||||
emptyMap = new Map(new StringMap());
|
||||
emptyTile = null;
|
||||
|
||||
if(tree == null) tree = new FileTree();
|
||||
if(mods == null) mods = new Mods();
|
||||
|
||||
@@ -106,7 +106,7 @@ public class BlockIndexer{
|
||||
|
||||
public void removeIndex(Tile tile){
|
||||
var team = tile.team();
|
||||
if(team != Team.derelict && tile.isCenter()){
|
||||
if(tile.build != null && tile.isCenter()){
|
||||
var flags = tile.block().flags;
|
||||
var data = team.data();
|
||||
|
||||
|
||||
@@ -245,7 +245,6 @@ public class Blocks implements ContentList{
|
||||
magmarock = new Floor("magmarock"){{
|
||||
attributes.set(Attribute.heat, 0.75f);
|
||||
attributes.set(Attribute.water, -0.75f);
|
||||
updateEffect = Fx.magmasmoke;
|
||||
blendGroup = basalt;
|
||||
|
||||
emitLight = true;
|
||||
@@ -452,6 +451,7 @@ public class Blocks implements ContentList{
|
||||
|
||||
sporeCluster = new Prop("spore-cluster"){{
|
||||
variants = 3;
|
||||
breakSound = Sounds.plantBreak;
|
||||
}};
|
||||
|
||||
redweed = new Seaweed("redweed"){{
|
||||
|
||||
@@ -47,7 +47,6 @@ public class StatusEffects implements ContentList{
|
||||
|
||||
affinity(blasted, ((unit, result, time) -> {
|
||||
unit.damagePierce(transitionDamage);
|
||||
result.set(freezing, time);
|
||||
}));
|
||||
});
|
||||
}};
|
||||
@@ -75,7 +74,6 @@ public class StatusEffects implements ContentList{
|
||||
if(unit.team == state.rules.waveTeam){
|
||||
Events.fire(Trigger.shock);
|
||||
}
|
||||
result.set(wet, time);
|
||||
}));
|
||||
opposite(burning, melting);
|
||||
});
|
||||
|
||||
@@ -1780,6 +1780,7 @@ public class UnitTypes implements ContentList{
|
||||
shots = 3;
|
||||
shotDelay = 7f;
|
||||
x = y = shootX = shootY = 0f;
|
||||
shootSound = Sounds.mineDeploy;
|
||||
|
||||
bullet = new BasicBulletType(){{
|
||||
sprite = "mine-bullet";
|
||||
@@ -2047,7 +2048,6 @@ public class UnitTypes implements ContentList{
|
||||
buildSpeed = 3f;
|
||||
|
||||
abilities.add(new EnergyFieldAbility(35f, 65f, 180f){{
|
||||
repair = 35f;
|
||||
statusDuration = 60f * 6f;
|
||||
maxTargets = 25;
|
||||
}});
|
||||
@@ -2151,6 +2151,8 @@ public class UnitTypes implements ContentList{
|
||||
shootY = 7f;
|
||||
recoil = 4f;
|
||||
cooldownTime = reload - 10f;
|
||||
//TODO better sound
|
||||
shootSound = Sounds.laser;
|
||||
|
||||
bullet = new EmpBulletType(){{
|
||||
float rad = 100f;
|
||||
@@ -2183,6 +2185,7 @@ public class UnitTypes implements ContentList{
|
||||
hitShake = 4f;
|
||||
trailRotation = true;
|
||||
status = StatusEffects.electrified;
|
||||
hitSound = Sounds.plasmaboom;
|
||||
|
||||
trailEffect = new Effect(16f, e -> {
|
||||
color(Pal.heal);
|
||||
|
||||
@@ -344,8 +344,7 @@ public class NetServer implements ApplicationListener{
|
||||
boolean checkPass(){
|
||||
if(votes >= votesRequired()){
|
||||
Call.sendMessage(Strings.format("[orange]Vote passed.[scarlet] @[orange] will be banned from the server for @ minutes.", target.name, (kickDuration / 60)));
|
||||
target.getInfo().lastKicked = Time.millis() + kickDuration * 1000;
|
||||
Groups.player.each(p -> p.uuid().equals(target.uuid()), p -> p.kick(KickReason.vote));
|
||||
Groups.player.each(p -> p.uuid().equals(target.uuid()), p -> p.kick(KickReason.vote, kickDuration * 1000));
|
||||
map[0] = null;
|
||||
task.cancel();
|
||||
return true;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package mindustry.entities.abilities;
|
||||
|
||||
import arc.*;
|
||||
import arc.audio.*;
|
||||
import arc.graphics.*;
|
||||
import arc.graphics.g2d.*;
|
||||
import arc.math.*;
|
||||
@@ -16,14 +17,15 @@ import mindustry.type.*;
|
||||
public class EnergyFieldAbility extends Ability{
|
||||
private static final Seq<Healthc> all = new Seq<>();
|
||||
|
||||
public float damage = 1, repair = 20f, reload = 100, range = 60;
|
||||
public float damage = 1, reload = 100, range = 60;
|
||||
public Effect healEffect = Fx.heal, hitEffect = Fx.hitLaserBlast, damageEffect = Fx.chainLightning;
|
||||
public StatusEffect status = StatusEffects.electrified;
|
||||
public Sound shootSound = Sounds.spark;
|
||||
public float statusDuration = 60f * 6f;
|
||||
public float x, y;
|
||||
public boolean hitBuildings = true;
|
||||
public int maxTargets = 25;
|
||||
public float healPercent = 3f;
|
||||
public float healPercent = 2.5f;
|
||||
|
||||
public float layer = Layer.bullet - 0.001f, blinkScl = 20f;
|
||||
public float effectRadius = 5f, sectorRad = 0.14f, rotateSpeed = 0.5f;
|
||||
@@ -139,6 +141,10 @@ public class EnergyFieldAbility extends Ability{
|
||||
}
|
||||
}
|
||||
|
||||
if(anyNearby){
|
||||
shootSound.at(unit);
|
||||
}
|
||||
|
||||
timer = 0f;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -232,8 +232,8 @@ public class BulletType extends Content implements Cloneable{
|
||||
}
|
||||
|
||||
if(entity instanceof Unit unit){
|
||||
Tmp.v3.set(unit).sub(b.x, b.y).nor().scl(knockback * 80f);
|
||||
if(impact) Tmp.v3.setAngle(b.rotation());
|
||||
Tmp.v3.set(unit).sub(b).nor().scl(knockback * 80f);
|
||||
if(impact) Tmp.v3.setAngle(b.rotation() + (knockback < 0 ? 180f : 0f));
|
||||
unit.impulse(Tmp.v3);
|
||||
unit.apply(status, statusDuration);
|
||||
}
|
||||
|
||||
@@ -106,7 +106,6 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
||||
|
||||
/** Sets up all the necessary variables, but does not add this entity anywhere. */
|
||||
public Building create(Block block, Team team){
|
||||
this.tile = emptyTile;
|
||||
this.block = block;
|
||||
this.team = team;
|
||||
|
||||
@@ -1443,7 +1442,7 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
||||
@Override
|
||||
public void killed(){
|
||||
Events.fire(new BlockDestroyEvent(tile));
|
||||
block.breakSound.at(tile);
|
||||
block.destroySound.at(tile);
|
||||
onDestroyed();
|
||||
tile.remove();
|
||||
remove();
|
||||
|
||||
@@ -2,6 +2,7 @@ package mindustry.entities.comp;
|
||||
|
||||
import arc.math.*;
|
||||
import arc.math.geom.*;
|
||||
import arc.util.*;
|
||||
import mindustry.annotations.Annotations.*;
|
||||
import mindustry.async.PhysicsProcess.*;
|
||||
import mindustry.gen.*;
|
||||
|
||||
@@ -238,6 +238,10 @@ abstract class PlayerComp implements UnitController, Entityc, Syncc, Timerc, Dra
|
||||
con.kick(reason);
|
||||
}
|
||||
|
||||
void kick(KickReason reason, long duration){
|
||||
con.kick(reason, duration);
|
||||
}
|
||||
|
||||
void kick(String reason){
|
||||
con.kick(reason);
|
||||
}
|
||||
|
||||
@@ -363,6 +363,9 @@ public class LExecutor{
|
||||
float x1 = World.unconv(exec.numf(p1)), y1 = World.unconv(exec.numf(p2)), d1 = World.unconv(exec.numf(p3));
|
||||
|
||||
switch(type){
|
||||
case idle -> {
|
||||
ai.control = type;
|
||||
}
|
||||
case move, stop, approach -> {
|
||||
ai.control = type;
|
||||
ai.moveX = x1;
|
||||
|
||||
@@ -3,12 +3,15 @@ package mindustry.maps.filters;
|
||||
|
||||
import arc.*;
|
||||
import arc.func.*;
|
||||
import arc.scene.event.*;
|
||||
import arc.scene.style.*;
|
||||
import arc.scene.ui.*;
|
||||
import arc.scene.ui.layout.*;
|
||||
import arc.util.*;
|
||||
import mindustry.*;
|
||||
import mindustry.content.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.ui.*;
|
||||
import mindustry.ui.dialogs.*;
|
||||
import mindustry.world.*;
|
||||
import mindustry.world.blocks.environment.*;
|
||||
@@ -35,7 +38,7 @@ public abstract class FilterOption{
|
||||
final Floatc setter;
|
||||
final float min, max, step;
|
||||
|
||||
boolean display;
|
||||
boolean display = true;
|
||||
|
||||
SliderOption(String name, Floatp getter, Floatc setter, float min, float max){
|
||||
this(name, getter, setter, min, max, (max - min) / 200);
|
||||
@@ -57,19 +60,27 @@ public abstract class FilterOption{
|
||||
|
||||
@Override
|
||||
public void build(Table table){
|
||||
Label label;
|
||||
if(!display){
|
||||
table.add("@filter.option." + name);
|
||||
label = new Label("@filter.option." + name);
|
||||
}else{
|
||||
table.label(() -> Core.bundle.get("filter.option." + name) + ": " + (int)getter.get());
|
||||
label = new Label(() -> Core.bundle.get("filter.option." + name) + ": " + Strings.autoFixed(getter.get(), 2));
|
||||
}
|
||||
table.row();
|
||||
Slider slider = table.slider(min, max, step, setter).growX().get();
|
||||
label.setWrap(true);
|
||||
label.setAlignment(Align.center);
|
||||
label.touchable = Touchable.disabled;
|
||||
label.setStyle(Styles.outlineLabel);
|
||||
|
||||
Slider slider = new Slider(min, max, step, false);
|
||||
slider.moved(setter);
|
||||
slider.setValue(getter.get());
|
||||
if(updateEditorOnChange){
|
||||
slider.changed(changed);
|
||||
}else{
|
||||
slider.released(changed);
|
||||
}
|
||||
|
||||
table.stack(slider, label).colspan(2).pad(3).growX().row();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -86,7 +86,8 @@ public class Mods implements Loadable{
|
||||
|
||||
/** Imports an external mod file. Folders are not supported here. */
|
||||
public LoadedMod importMod(Fi file) throws IOException{
|
||||
String baseName = file.nameWithoutExtension();
|
||||
//for some reason, android likes to add colons to file names, e.g. primary:ExampleJavaMod.jar, which breaks dexing
|
||||
String baseName = file.nameWithoutExtension().replace(':', '_').replace(' ', '_');
|
||||
String finalName = baseName;
|
||||
//find a name to prevent any name conflicts
|
||||
int count = 1;
|
||||
@@ -300,12 +301,12 @@ public class Mods implements Loadable{
|
||||
}
|
||||
|
||||
private PageType getPage(Fi file){
|
||||
String parent = file.parent().name();
|
||||
String path = file.path();
|
||||
return
|
||||
parent.equals("environment") ? PageType.environment :
|
||||
parent.equals("editor") ? PageType.editor :
|
||||
parent.equals("rubble") ? PageType.editor :
|
||||
parent.equals("ui") || file.parent().parent().name().equals("ui") ? PageType.ui :
|
||||
path.contains("sprites/blocks/environment") ? PageType.environment :
|
||||
path.contains("sprites/editor") ? PageType.editor :
|
||||
path.contains("sprites/rubble") ? PageType.editor :
|
||||
path.contains("sprites/ui") ? PageType.ui :
|
||||
PageType.main;
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@ import arc.struct.*;
|
||||
import arc.util.*;
|
||||
import mindustry.entities.units.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.net.Administration.*;
|
||||
import mindustry.net.Packets.*;
|
||||
|
||||
import java.io.*;
|
||||
@@ -37,38 +36,39 @@ public abstract class NetConnection{
|
||||
|
||||
/** Kick with a special, localized reason. Use this if possible. */
|
||||
public void kick(KickReason reason){
|
||||
if(kicked) return;
|
||||
kick(reason, (reason == KickReason.kick || reason == KickReason.banned || reason == KickReason.vote) ? 30 * 1000 : 0);
|
||||
}
|
||||
|
||||
Log.info("Kicking connection @ / @; Reason: @", address, uuid, reason.name());
|
||||
|
||||
if((reason == KickReason.kick || reason == KickReason.banned || reason == KickReason.vote)){
|
||||
PlayerInfo info = netServer.admins.getInfo(uuid);
|
||||
info.timesKicked++;
|
||||
info.lastKicked = Math.max(Time.millis() + 30 * 1000, info.lastKicked);
|
||||
}
|
||||
|
||||
Call.kick(this, reason);
|
||||
|
||||
close();
|
||||
|
||||
netServer.admins.save();
|
||||
kicked = true;
|
||||
/** Kick with a special, localized reason. Use this if possible. */
|
||||
public void kick(KickReason reason, long kickDuration){
|
||||
kick(null, reason, kickDuration);
|
||||
}
|
||||
|
||||
/** Kick with an arbitrary reason. */
|
||||
public void kick(String reason){
|
||||
kick(reason, 30 * 1000);
|
||||
kick(reason, null, 30 * 1000);
|
||||
}
|
||||
|
||||
/** Kick with an arbitrary reason. */
|
||||
public void kick(String reason, long duration){
|
||||
kick(reason, null, duration);
|
||||
}
|
||||
|
||||
/** Kick with an arbitrary reason, and a kick duration in milliseconds. */
|
||||
public void kick(String reason, long kickDuration){
|
||||
private void kick(String reason, KickReason kickType, long kickDuration){
|
||||
if(kicked) return;
|
||||
|
||||
Log.info("Kicking connection @ / @; Reason: @", address, uuid, reason.replace("\n", " "));
|
||||
Log.info("Kicking connection @ / @; Reason: @", address, uuid, reason == null ? kickType.name() : reason.replace("\n", " "));
|
||||
|
||||
netServer.admins.handleKicked(uuid, address, kickDuration);
|
||||
if(kickDuration > 0){
|
||||
netServer.admins.handleKicked(uuid, address, kickDuration);
|
||||
}
|
||||
|
||||
Call.kick(this, reason);
|
||||
if(reason == null){
|
||||
Call.kick(this, kickType);
|
||||
}else{
|
||||
Call.kick(this, reason);
|
||||
}
|
||||
|
||||
close();
|
||||
|
||||
|
||||
@@ -249,7 +249,7 @@ public class Weapon implements Cloneable{
|
||||
unit.vel.add(Tmp.v1.trns(unit.rotation + 180f, mount.bullet.type.recoil));
|
||||
if(shootSound != Sounds.none && !headless){
|
||||
if(mount.sound == null) mount.sound = new SoundLoop(shootSound, 1f);
|
||||
mount.sound.update(x, y, true);
|
||||
mount.sound.update(bulletX, bulletY, true);
|
||||
}
|
||||
}
|
||||
}else{
|
||||
@@ -285,8 +285,7 @@ public class Weapon implements Cloneable{
|
||||
can && //must be able to shoot
|
||||
(!useAmmo || unit.ammo > 0 || !state.rules.unitAmmo || unit.team.rules().infiniteAmmo) && //check ammo
|
||||
(!alternate || mount.side == flipSprite) &&
|
||||
//TODO checking for velocity this way isn't entirely correct
|
||||
(unit.vel.len() >= mount.weapon.minShootVelocity || (net.active() && !unit.isLocal())) && //check velocity requirements
|
||||
unit.vel.len() >= mount.weapon.minShootVelocity && //check velocity requirements
|
||||
mount.reload <= 0.0001f && //reload has to be 0
|
||||
Angles.within(rotate ? mount.rotation : unit.rotation, mount.targetRotation, mount.weapon.shootCone) //has to be within the cone
|
||||
){
|
||||
@@ -324,6 +323,9 @@ public class Weapon implements Cloneable{
|
||||
Time.run(sequenceNum * shotDelay + firstShotDelay, () -> {
|
||||
if(!unit.isAdded()) return;
|
||||
mount.bullet = bullet(unit, shootX + unit.x - baseX, shootY + unit.y - baseY, f + Mathf.range(inaccuracy), lifeScl);
|
||||
if(!continuous){
|
||||
shootSound.at(shootX, shootY, Mathf.random(soundPitchMin, soundPitchMax));
|
||||
}
|
||||
});
|
||||
sequenceNum++;
|
||||
});
|
||||
|
||||
@@ -203,7 +203,7 @@ public class Fonts{
|
||||
|
||||
/** Merges the UI and font atlas together for better performance. */
|
||||
public static void mergeFontAtlas(TextureAtlas atlas){
|
||||
//grab all textures from the ui page, remove all the regions assigned to it, then copy them over to Fonts.packer and replace the texture in this atlas.
|
||||
//grab all textures from the ui page, remove all the regions assigned to it, then copy them over to UI.packer and replace the texture in this atlas.
|
||||
|
||||
//grab old UI texture and regions...
|
||||
Texture texture = atlas.find("logo").texture;
|
||||
@@ -236,8 +236,12 @@ public class Fonts{
|
||||
}
|
||||
|
||||
public static TextureRegionDrawable getGlyph(Font font, char glyph){
|
||||
Glyph g = font.getData().getGlyph(glyph);
|
||||
if(g == null) throw new IllegalArgumentException("No glyph: " + glyph + " (" + (int)glyph + ")");
|
||||
Glyph found = font.getData().getGlyph(glyph);
|
||||
if(found == null){
|
||||
Log.warn("No icon found for glyph: @ (@)", glyph, (int)glyph);
|
||||
found = font.getData().getGlyph('F');
|
||||
}
|
||||
Glyph g = found;
|
||||
|
||||
float size = Math.max(g.width, g.height);
|
||||
TextureRegionDrawable draw = new TextureRegionDrawable(new TextureRegion(font.getRegion().texture, g.u, g.v2, g.u2, g.v)){
|
||||
|
||||
@@ -31,7 +31,7 @@ public class Styles{
|
||||
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;
|
||||
public static SliderStyle defaultSlider, vSlider;
|
||||
public static SliderStyle defaultSlider;
|
||||
public static LabelStyle defaultLabel, outlineLabel, techLabel;
|
||||
public static TextFieldStyle defaultField, nodeField, areaField, nodeArea;
|
||||
public static CheckBoxStyle defaultCheck;
|
||||
@@ -320,13 +320,7 @@ public class Styles{
|
||||
}};
|
||||
|
||||
defaultSlider = new SliderStyle(){{
|
||||
background = slider;
|
||||
knob = sliderKnob;
|
||||
knobOver = sliderKnobOver;
|
||||
knobDown = sliderKnobDown;
|
||||
}};
|
||||
vSlider = new SliderStyle(){{
|
||||
background = sliderVertical;
|
||||
background = sliderBack;
|
||||
knob = sliderKnob;
|
||||
knobOver = sliderKnobOver;
|
||||
knobDown = sliderKnobDown;
|
||||
|
||||
@@ -2,6 +2,7 @@ package mindustry.ui;
|
||||
|
||||
import arc.graphics.g2d.*;
|
||||
import arc.scene.*;
|
||||
import arc.scene.ui.layout.*;
|
||||
import mindustry.graphics.*;
|
||||
|
||||
public class WarningBar extends Element{
|
||||
@@ -27,7 +28,7 @@ public class WarningBar extends Element{
|
||||
rx + barWidth, y
|
||||
);
|
||||
}
|
||||
Lines.stroke(3f);
|
||||
Lines.stroke(Scl.scl(3f));
|
||||
Lines.line(x, y, x + width, y);
|
||||
Lines.line(x, y + height, x + width, y + height);
|
||||
|
||||
|
||||
@@ -80,9 +80,7 @@ public class ModsDialog extends BaseDialog{
|
||||
}
|
||||
|
||||
shown(this::setup);
|
||||
if(mobile){
|
||||
onResize(this::setup);
|
||||
}
|
||||
onResize(this::setup);
|
||||
|
||||
Events.on(ResizeEvent.class, event -> {
|
||||
if(currentContent != null){
|
||||
@@ -144,10 +142,10 @@ public class ModsDialog extends BaseDialog{
|
||||
|
||||
void setup(){
|
||||
float h = 110f;
|
||||
float w = Math.min(Core.graphics.getWidth() / 1.1f, 520f);
|
||||
float w = Math.min(Core.graphics.getWidth() / Scl.scl(1.05f), 520f);
|
||||
|
||||
cont.clear();
|
||||
cont.defaults().width(Math.min(Core.graphics.getWidth() / 1.2f, 556f)).pad(4);
|
||||
cont.defaults().width(Math.min(Core.graphics.getWidth() / Scl.scl(1.05f), 556f)).pad(4);
|
||||
cont.add("@mod.reloadrequired").visible(mods::requiresReload).center().get().setAlignment(Align.center);
|
||||
cont.row();
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import arc.func.*;
|
||||
import arc.graphics.*;
|
||||
import arc.graphics.Texture.*;
|
||||
import arc.input.*;
|
||||
import arc.scene.event.*;
|
||||
import arc.scene.ui.*;
|
||||
import arc.scene.ui.TextButton.*;
|
||||
import arc.scene.ui.layout.*;
|
||||
@@ -286,7 +287,8 @@ public class SettingsMenuDialog extends Dialog{
|
||||
sound.sliderPref("sfxvol", bundle.get("setting.sfxvol.name", "SFX Volume"), 100, 0, 100, 1, i -> i + "%");
|
||||
sound.sliderPref("ambientvol", bundle.get("setting.ambientvol.name", "Ambient Volume"), 100, 0, 100, 1, i -> i + "%");
|
||||
|
||||
game.screenshakePref();
|
||||
game.sliderPref("saveinterval", 60, 10, 5 * 120, 10, i -> Core.bundle.format("setting.seconds", i));
|
||||
|
||||
if(mobile){
|
||||
game.checkPref("autotarget", true);
|
||||
game.checkPref("keyboard", false, val -> {
|
||||
@@ -307,7 +309,6 @@ public class SettingsMenuDialog extends Dialog{
|
||||
control.setInput(new MobileInput());
|
||||
}
|
||||
}*/
|
||||
game.sliderPref("saveinterval", 60, 10, 5 * 120, 10, i -> Core.bundle.format("setting.seconds", i));
|
||||
|
||||
if(!mobile){
|
||||
game.checkPref("crashreport", true);
|
||||
@@ -350,6 +351,8 @@ public class SettingsMenuDialog extends Dialog{
|
||||
Core.settings.put("uiscalechanged", s != lastUiScale[0]);
|
||||
return s + "%";
|
||||
});
|
||||
|
||||
graphics.sliderPref("screenshake", 4, 0, 8, i -> (i / 4f) + "x");
|
||||
graphics.sliderPref("fpscap", 240, 15, 245, 5, s -> (s > 240 ? Core.bundle.get("setting.fpscap.none") : Core.bundle.format("setting.fpscap.text", s)));
|
||||
graphics.sliderPref("chatopacity", 100, 0, 100, 5, s -> s + "%");
|
||||
graphics.sliderPref("lasersopacity", 100, 0, 100, 5, s -> {
|
||||
@@ -559,10 +562,6 @@ public class SettingsMenuDialog extends Dialog{
|
||||
rebuild();
|
||||
}
|
||||
|
||||
public void screenshakePref(){
|
||||
sliderPref("screenshake", bundle.get("setting.screenshake.name", "Screen Shake"), 4, 0, 8, i -> (i / 4f) + "x");
|
||||
}
|
||||
|
||||
public SliderSetting sliderPref(String name, String title, int def, int min, int max, StringProcessor s){
|
||||
return sliderPref(name, title, def, min, max, 1, s);
|
||||
}
|
||||
@@ -686,23 +685,21 @@ public class SettingsMenuDialog extends Dialog{
|
||||
|
||||
slider.setValue(settings.getInt(name));
|
||||
|
||||
Label label = new Label(title);
|
||||
Label value = new Label("");
|
||||
value.setStyle(Styles.outlineLabel);
|
||||
value.touchable = Touchable.disabled;
|
||||
|
||||
slider.changed(() -> {
|
||||
settings.put(name, (int)slider.getValue());
|
||||
label.setText(title + ": " + sp.get((int)slider.getValue()));
|
||||
value.setText(title + ": " + sp.get((int)slider.getValue()));
|
||||
});
|
||||
|
||||
value.setAlignment(Align.center);
|
||||
value.setWrap(true);
|
||||
|
||||
slider.change();
|
||||
|
||||
table.table(t -> {
|
||||
t.left().defaults().left();
|
||||
t.add(label).minWidth(label.getPrefWidth() / Scl.scl(1f) + 50);
|
||||
if(Core.graphics.isPortrait()){
|
||||
t.row();
|
||||
}
|
||||
t.add(slider).width(180);
|
||||
}).left().padTop(3);
|
||||
|
||||
table.stack(slider, value).width(Math.min(Core.graphics.getWidth() / 1.2f, 460f)).left().padTop(4);
|
||||
table.row();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ import arc.scene.ui.layout.Stack;
|
||||
import arc.scene.ui.layout.*;
|
||||
import arc.struct.*;
|
||||
import arc.util.*;
|
||||
import mindustry.core.*;
|
||||
import mindustry.game.EventType.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.type.*;
|
||||
@@ -200,9 +201,9 @@ public class BlockInventoryFragment extends Fragment{
|
||||
private String round(float f){
|
||||
f = (int)f;
|
||||
if(f >= 1000000){
|
||||
return (int)(f / 1000000f) + "[gray]" + Core.bundle.getOrNull("unit.millions") + "[]";
|
||||
return (int)(f / 1000000f) + "[gray]" + UI.millions;
|
||||
}else if(f >= 1000){
|
||||
return (int)(f / 1000) + Core.bundle.getOrNull("unit.thousands");
|
||||
return (int)(f / 1000) + UI.thousands;
|
||||
}else{
|
||||
return (int)f + "";
|
||||
}
|
||||
|
||||
@@ -83,13 +83,15 @@ 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()));
|
||||
}
|
||||
|
||||
for(var user : players){
|
||||
found = true;
|
||||
NetConnection connection = user.con;
|
||||
|
||||
if(connection == null && net.server() && !user.isLocal()) return;
|
||||
if(sField.getText().length() > 0 && !user.name().toLowerCase().contains(sField.getText().toLowerCase()) && !Strings.stripColors(user.name().toLowerCase()).contains(sField.getText().toLowerCase())) return;
|
||||
|
||||
Table button = new Table();
|
||||
button.left();
|
||||
|
||||
@@ -193,8 +193,10 @@ public class Block extends UnlockableContent{
|
||||
public int outlinedIcon = -1;
|
||||
/** Whether this block has a shadow under it. */
|
||||
public boolean hasShadow = true;
|
||||
/** Sounds made when this block breaks.*/
|
||||
public Sound breakSound = Sounds.boom;
|
||||
/** Sounds made when this block is destroyed.*/
|
||||
public Sound destroySound = Sounds.boom;
|
||||
/** Sound made when this block is deconstructed. */
|
||||
public Sound breakSound = Sounds.breaks;
|
||||
/** How reflective this block is. */
|
||||
public float albedo = 0f;
|
||||
/** Environmental passive light color. */
|
||||
|
||||
@@ -47,7 +47,7 @@ public class ConstructBlock extends Block{
|
||||
|
||||
/** Returns a ConstructBlock by size. */
|
||||
public static ConstructBlock get(int size){
|
||||
if(size > maxBlockSize) throw new IllegalArgumentException("No. Don't place ConstructBlock of size greater than " + maxBlockSize);
|
||||
if(size > maxBlockSize) throw new IllegalArgumentException("No. Don't place ConstructBlocks of size greater than " + maxBlockSize);
|
||||
return consBlocks[size - 1];
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ public class ConstructBlock extends Block{
|
||||
block.breakEffect.at(tile.drawx(), tile.drawy(), block.size, block.mapColor);
|
||||
Events.fire(new BlockBuildEndEvent(tile, builder, team, true, null));
|
||||
tile.remove();
|
||||
if(shouldPlay()) Sounds.breaks.at(tile, calcPitch(false));
|
||||
if(shouldPlay()) block.breakSound.at(tile, calcPitch(false));
|
||||
}
|
||||
|
||||
@Remote(called = Loc.server)
|
||||
|
||||
@@ -129,8 +129,8 @@ public class LaunchPad extends Block{
|
||||
public void updateTile(){
|
||||
if(!state.isCampaign()) return;
|
||||
|
||||
//launch when full and base conditions are met
|
||||
if(items.total() >= itemCapacity && efficiency() >= 1f && (launchCounter += edelta()) >= launchTime){
|
||||
//increment launchCounter then launch when full and base conditions are met
|
||||
if((launchCounter += edelta()) >= launchTime && items.total() >= itemCapacity){
|
||||
launchSound.at(x, y);
|
||||
LaunchPayload entity = LaunchPayload.create();
|
||||
items.each((item, amount) -> entity.stacks.add(new ItemStack(item, amount)));
|
||||
|
||||
@@ -246,7 +246,7 @@ public class Conveyor extends Block implements Autotiler{
|
||||
|
||||
if(ys[i] > nextMax) ys[i] = nextMax;
|
||||
if(ys[i] > 0.5 && i > 0) mid = i - 1;
|
||||
xs[i] = Mathf.approachDelta(xs[i], 0, speed*2);
|
||||
xs[i] = Mathf.approach(xs[i], 0, moved*2);
|
||||
|
||||
if(ys[i] >= 1f && pass(ids[i])){
|
||||
//align X position if passing forwards
|
||||
@@ -262,7 +262,7 @@ public class Conveyor extends Block implements Autotiler{
|
||||
}
|
||||
|
||||
if(minitem < itemSpace + (blendbits == 1 ? 0.3f : 0f)){
|
||||
clogHeat = Mathf.lerpDelta(clogHeat, 1f, 0.02f);
|
||||
clogHeat = Mathf.approachDelta(clogHeat, 1f, 1f / 60f);
|
||||
}else{
|
||||
clogHeat = 0f;
|
||||
}
|
||||
|
||||
@@ -51,8 +51,6 @@ public class Floor extends Block{
|
||||
public boolean playerUnmineable = false;
|
||||
/** Group of blocks that this block does not draw edges on. */
|
||||
public Block blendGroup = this;
|
||||
/** Effect displayed when randomly updated. */
|
||||
public Effect updateEffect = Fx.none;
|
||||
/** Whether this ore generates in maps by default. */
|
||||
public boolean oreDefault = false;
|
||||
/** Ore generation params. */
|
||||
|
||||
@@ -4,15 +4,18 @@ import arc.*;
|
||||
import arc.graphics.g2d.*;
|
||||
import arc.math.*;
|
||||
import mindustry.content.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.world.*;
|
||||
|
||||
public class Prop extends Block{
|
||||
|
||||
public Prop(String name){
|
||||
super(name);
|
||||
breakable = true;
|
||||
alwaysReplace = true;
|
||||
instantDeconstruct = true;
|
||||
breakEffect = Fx.breakProp;
|
||||
breakSound = Sounds.rockBreak;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -6,6 +6,7 @@ import arc.util.*;
|
||||
import arc.util.io.*;
|
||||
import mindustry.game.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.ui.*;
|
||||
import mindustry.type.*;
|
||||
import mindustry.world.*;
|
||||
|
||||
@@ -56,6 +57,12 @@ public interface Payload extends Position{
|
||||
/** @return icon describing the contents. */
|
||||
TextureRegion icon();
|
||||
|
||||
/** @deprecated use icon() instead. */
|
||||
@Deprecated
|
||||
default TextureRegion icon(Cicon icon){
|
||||
return icon();
|
||||
}
|
||||
|
||||
@Override
|
||||
default float getX(){
|
||||
return x();
|
||||
|
||||
@@ -456,6 +456,7 @@ public class PayloadMassDriver extends PayloadBlock{
|
||||
|
||||
@Override
|
||||
public Point2 config(){
|
||||
if(tile == null) return null;
|
||||
return Point2.unpack(link).sub(tile.x, tile.y);
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,10 @@ import mindustry.world.draw.*;
|
||||
import mindustry.world.meta.*;
|
||||
|
||||
public class GenericCrafter extends Block{
|
||||
/** Written to outputItems as a single-element array if outputItems is null. */
|
||||
public @Nullable ItemStack outputItem;
|
||||
/** Overwrites outputItem if not null. */
|
||||
public @Nullable ItemStack[] outputItems;
|
||||
public @Nullable LiquidStack outputLiquid;
|
||||
|
||||
public float craftTime = 80;
|
||||
@@ -45,8 +48,8 @@ public class GenericCrafter extends Block{
|
||||
super.setStats();
|
||||
stats.add(Stat.productionTime, craftTime / 60f, StatUnit.seconds);
|
||||
|
||||
if(outputItem != null){
|
||||
stats.add(Stat.output, StatValues.items(craftTime, outputItem));
|
||||
if(outputItems != null){
|
||||
stats.add(Stat.output, StatValues.items(craftTime, outputItems));
|
||||
}
|
||||
|
||||
if(outputLiquid != null){
|
||||
@@ -64,6 +67,9 @@ public class GenericCrafter extends Block{
|
||||
@Override
|
||||
public void init(){
|
||||
outputsLiquid = outputLiquid != null;
|
||||
if(outputItems == null && outputItem != null){
|
||||
outputItems = new ItemStack[]{outputItem};
|
||||
}
|
||||
super.init();
|
||||
}
|
||||
|
||||
@@ -74,7 +80,7 @@ public class GenericCrafter extends Block{
|
||||
|
||||
@Override
|
||||
public boolean outputsItems(){
|
||||
return outputItem != null;
|
||||
return outputItems != null;
|
||||
}
|
||||
|
||||
public class GenericCrafterBuild extends Building{
|
||||
@@ -95,8 +101,12 @@ public class GenericCrafter extends Block{
|
||||
|
||||
@Override
|
||||
public boolean shouldConsume(){
|
||||
if(outputItem != null && items.get(outputItem.item) + outputItem.amount > itemCapacity){
|
||||
return false;
|
||||
if(outputItems != null){
|
||||
for(ItemStack output : outputItems){
|
||||
if(items.get(output.item) + output.amount > itemCapacity){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (outputLiquid == null || !(liquids.get(outputLiquid.liquid) >= liquidCapacity - 0.001f)) && enabled;
|
||||
}
|
||||
@@ -119,9 +129,11 @@ public class GenericCrafter extends Block{
|
||||
if(progress >= 1f){
|
||||
consume();
|
||||
|
||||
if(outputItem != null){
|
||||
for(int i = 0; i < outputItem.amount; i++){
|
||||
offload(outputItem.item);
|
||||
if(outputItems != null){
|
||||
for(ItemStack output : outputItems){
|
||||
for(int i = 0; i < output.amount; i++){
|
||||
offload(output.item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,8 +145,10 @@ public class GenericCrafter extends Block{
|
||||
progress %= 1f;
|
||||
}
|
||||
|
||||
if(outputItem != null && timer(timerDump, dumpTime / timeScale)){
|
||||
dump(outputItem.item);
|
||||
if(outputItems != null && timer(timerDump, dumpTime / timeScale)){
|
||||
for(ItemStack output : outputItems){
|
||||
dump(output.item);
|
||||
}
|
||||
}
|
||||
|
||||
if(outputLiquid != null){
|
||||
@@ -174,4 +188,4 @@ public class GenericCrafter extends Block{
|
||||
if(legacyReadWarmup) read.f();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -281,7 +281,7 @@ public class CoreBlock extends StorageBlock{
|
||||
@Override
|
||||
public void afterDestroyed(){
|
||||
if(state.rules.coreCapture){
|
||||
tile.setBlock(block, lastDamage);
|
||||
tile.setNet(block, lastDamage, 0);
|
||||
//core is invincible for several seconds to prevent recapture
|
||||
((CoreBuild)tile.build).iframes = captureInvicibility;
|
||||
}
|
||||
|
||||
@@ -147,7 +147,7 @@ public class StatValues{
|
||||
}
|
||||
}
|
||||
}else{
|
||||
c.add("@none.found");
|
||||
c.add("@none.inmap");
|
||||
}
|
||||
}else{
|
||||
c.add("@stat.showinmap");
|
||||
|
||||
Reference in New Issue
Block a user