Merge
This commit is contained in:
@@ -48,7 +48,7 @@ public class Blocks implements ContentList{
|
||||
melter, separator, sporePress, pulverizer, incinerator, coalCentrifuge,
|
||||
|
||||
//sandbox
|
||||
powerVoid, powerSource, itemSource, liquidSource, itemVoid, message,
|
||||
powerSource, powerVoid, itemSource, itemVoid, liquidSource, message,
|
||||
|
||||
//defense
|
||||
scrapWall, scrapWallLarge, scrapWallHuge, scrapWallGigantic, thruster, //ok, these names are getting ridiculous, but at least I don't have humongous walls yet
|
||||
@@ -63,7 +63,7 @@ public class Blocks implements ContentList{
|
||||
|
||||
//power
|
||||
combustionGenerator, thermalGenerator, turbineGenerator, differentialGenerator, rtgGenerator, solarPanel, largeSolarPanel, thoriumReactor,
|
||||
impactReactor, battery, batteryLarge, powerNode, powerNodeLarge, surgeTower,
|
||||
impactReactor, battery, batteryLarge, powerNode, powerNodeLarge, surgeTower, diode,
|
||||
|
||||
//production
|
||||
mechanicalDrill, pneumaticDrill, laserDrill, blastDrill, waterExtractor, oilExtractor, cultivator,
|
||||
@@ -548,7 +548,7 @@ public class Blocks implements ContentList{
|
||||
hasPower = true;
|
||||
|
||||
consumes.power(4f);
|
||||
consumes.items(new ItemStack(Items.titanium, 2), new ItemStack(Items.lead, 4), new ItemStack(Items.silicon, 3), new ItemStack(Items.copper, 3));
|
||||
consumes.items(new ItemStack(Items.copper, 3), new ItemStack(Items.lead, 4), new ItemStack(Items.titanium, 2), new ItemStack(Items.silicon, 3));
|
||||
}};
|
||||
|
||||
cryofluidMixer = new LiquidConverter("cryofluidmixer"){{
|
||||
@@ -724,11 +724,11 @@ public class Blocks implements ContentList{
|
||||
//endregion
|
||||
//region sandbox
|
||||
|
||||
powerVoid = new PowerVoid("power-void"){{
|
||||
powerSource = new PowerSource("power-source"){{
|
||||
requirements(Category.power, BuildVisibility.sandboxOnly, ItemStack.with());
|
||||
alwaysUnlocked = true;
|
||||
}};
|
||||
powerSource = new PowerSource("power-source"){{
|
||||
powerVoid = new PowerVoid("power-void"){{
|
||||
requirements(Category.power, BuildVisibility.sandboxOnly, ItemStack.with());
|
||||
alwaysUnlocked = true;
|
||||
}};
|
||||
@@ -1021,6 +1021,7 @@ public class Blocks implements ContentList{
|
||||
pulseConduit = new Conduit("pulse-conduit"){{
|
||||
requirements(Category.liquid, ItemStack.with(Items.titanium, 2, Items.metaglass, 1));
|
||||
liquidCapacity = 16f;
|
||||
liquidPressure = 1.025f;
|
||||
health = 90;
|
||||
}};
|
||||
|
||||
@@ -1076,6 +1077,10 @@ public class Blocks implements ContentList{
|
||||
laserRange = 30f;
|
||||
}};
|
||||
|
||||
diode = new PowerDiode("diode"){{
|
||||
requirements(Category.power, ItemStack.with(Items.silicon, 10, Items.plastanium, 5, Items.metaglass, 10));
|
||||
}};
|
||||
|
||||
battery = new Battery("battery"){{
|
||||
requirements(Category.power, ItemStack.with(Items.copper, 4, Items.lead, 20));
|
||||
consumes.powerBuffered(4000f);
|
||||
|
||||
@@ -215,8 +215,10 @@ public class TechTree implements ContentList{
|
||||
node(combustionGenerator, () -> {
|
||||
node(powerNode, () -> {
|
||||
node(powerNodeLarge, () -> {
|
||||
node(surgeTower, () -> {
|
||||
node(diode, () -> {
|
||||
node(surgeTower, () -> {
|
||||
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
package io.anuke.mindustry.content;
|
||||
|
||||
import io.anuke.mindustry.ctype.ContentList;
|
||||
import io.anuke.mindustry.game.*;
|
||||
import io.anuke.mindustry.ctype.*;
|
||||
import io.anuke.mindustry.game.Objectives.*;
|
||||
import io.anuke.mindustry.game.*;
|
||||
import io.anuke.mindustry.maps.generators.*;
|
||||
import io.anuke.mindustry.maps.generators.MapGenerator.*;
|
||||
import io.anuke.mindustry.maps.zonegen.*;
|
||||
import io.anuke.mindustry.type.*;
|
||||
|
||||
@@ -190,7 +189,6 @@ public class Zones implements ContentList{
|
||||
startingItems = list(copper, 250, lead, 100);
|
||||
conditionWave = 15;
|
||||
launchPeriod = 10;
|
||||
requirements = with(new ZoneWave(ruinousShores, 20));
|
||||
resources = with(copper, scrap, lead, coal, titanium, thorium, sand);
|
||||
requirements = with(
|
||||
new ZoneWave(ruinousShores, 20),
|
||||
|
||||
@@ -13,7 +13,6 @@ import io.anuke.mindustry.world.modules.*;
|
||||
import static io.anuke.mindustry.Vars.state;
|
||||
import static io.anuke.mindustry.Vars.ui;
|
||||
|
||||
//TODO somehow remove or replace this class with a more flexible solution
|
||||
public class EditorTile extends Tile{
|
||||
|
||||
public EditorTile(int x, int y, int floor, int overlay, int wall){
|
||||
@@ -103,6 +102,7 @@ public class EditorTile extends Tile{
|
||||
return;
|
||||
}
|
||||
|
||||
if(floor.isLiquid) return;
|
||||
if(overlayID() == overlay) return;
|
||||
op(OpType.overlay, this.overlay.id);
|
||||
super.setOverlayID(overlay);
|
||||
|
||||
@@ -186,7 +186,7 @@ public class WaveInfoDialog extends FloatingDialog{
|
||||
}).width(80f);
|
||||
|
||||
a.add(" + ");
|
||||
a.addField(Strings.fixed(Math.max((Mathf.isZero(group.unitScaling) ? 0 : 1f / group.unitScaling), 0), 2), TextFieldFilter.floatsOnly, text -> {
|
||||
a.addField(Strings.fixed(Math.max((Mathf.zero(group.unitScaling) ? 0 : 1f / group.unitScaling), 0), 2), TextFieldFilter.floatsOnly, text -> {
|
||||
if(Strings.canParsePositiveFloat(text)){
|
||||
group.unitScaling = 1f / Strings.parseFloat(text);
|
||||
updateWaves();
|
||||
@@ -217,21 +217,23 @@ public class WaveInfoDialog extends FloatingDialog{
|
||||
|
||||
void showUpdate(SpawnGroup group){
|
||||
FloatingDialog dialog = new FloatingDialog("");
|
||||
dialog.setFillParent(false);
|
||||
int i = 0;
|
||||
for(UnitType type : content.units()){
|
||||
dialog.cont.addButton(t -> {
|
||||
t.left();
|
||||
t.addImage(type.icon(io.anuke.mindustry.ui.Cicon.medium)).size(40f).padRight(2f);
|
||||
t.add(type.localizedName);
|
||||
}, () -> {
|
||||
lastType = type;
|
||||
group.type = type;
|
||||
dialog.hide();
|
||||
buildGroups();
|
||||
}).pad(2).margin(12f).fillX();
|
||||
if(++i % 3 == 0) dialog.cont.row();
|
||||
}
|
||||
dialog.setFillParent(true);
|
||||
dialog.cont.pane(p -> {
|
||||
int i = 0;
|
||||
for(UnitType type : content.units()){
|
||||
p.addButton(t -> {
|
||||
t.left();
|
||||
t.addImage(type.icon(io.anuke.mindustry.ui.Cicon.medium)).size(40f).padRight(2f);
|
||||
t.add(type.localizedName);
|
||||
}, () -> {
|
||||
lastType = type;
|
||||
group.type = type;
|
||||
dialog.hide();
|
||||
buildGroups();
|
||||
}).pad(2).margin(12f).fillX();
|
||||
if(++i % 3 == 0) p.row();
|
||||
}
|
||||
});
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
|
||||
@@ -34,39 +34,36 @@ public interface BuilderTrait extends Entity, TeamTrait{
|
||||
default void updateBuilding(){
|
||||
float finalPlaceDst = state.rules.infiniteResources ? Float.MAX_VALUE : placeDistance;
|
||||
Unit unit = (Unit)this;
|
||||
|
||||
//remove already completed build requests
|
||||
removal.clear();
|
||||
for(BuildRequest req : buildQueue()){
|
||||
removal.add(req);
|
||||
}
|
||||
removal.addAll(buildQueue());
|
||||
|
||||
buildQueue().clear();
|
||||
Structs.filter(buildQueue(), req -> {
|
||||
Tile tile = world.tile(req.x, req.y);
|
||||
return tile == null || (req.breaking && tile.block() == Blocks.air) || (!req.breaking && (tile.rotation() == req.rotation || !req.block.rotate) && tile.block() == req.block);
|
||||
});
|
||||
|
||||
for(BuildRequest request : removal){
|
||||
Tile tile = world.tile(request.x, request.y);
|
||||
TileEntity core = unit.getClosestCore();
|
||||
|
||||
if(!(tile == null || (request.breaking && tile.block() == Blocks.air) ||
|
||||
(!request.breaking && (tile.rotation() == request.rotation || !request.block.rotate) && tile.block() == request.block))){
|
||||
buildQueue().addLast(request);
|
||||
//nothing to build.
|
||||
if(buildRequest() == null) return;
|
||||
|
||||
//find the next build request
|
||||
if(buildQueue().size > 1){
|
||||
int total = 0;
|
||||
BuildRequest req;
|
||||
while((dst((req = buildRequest()).tile()) > finalPlaceDst || shouldSkip(req, core)) && total < buildQueue().size){
|
||||
buildQueue().removeFirst();
|
||||
buildQueue().addLast(req);
|
||||
total++;
|
||||
}
|
||||
}
|
||||
|
||||
BuildRequest current = buildRequest();
|
||||
|
||||
if(current == null){
|
||||
return;
|
||||
}
|
||||
|
||||
Tile tile = world.tile(current.x, current.y);
|
||||
|
||||
if(dst(tile) > finalPlaceDst){
|
||||
if(buildQueue().size > 1){
|
||||
buildQueue().removeFirst();
|
||||
buildQueue().addLast(current);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if(!(tile.block() instanceof BuildBlock)){
|
||||
if(!current.initialized && canCreateBlocks() && !current.breaking && Build.validPlace(getTeam(), current.x, current.y, current.block, current.rotation)){
|
||||
Call.beginPlace(getTeam(), current.x, current.y, current.block, current.rotation);
|
||||
@@ -78,8 +75,6 @@ public interface BuilderTrait extends Entity, TeamTrait{
|
||||
}
|
||||
}
|
||||
|
||||
TileEntity core = unit.getClosestCore();
|
||||
|
||||
if(tile.entity instanceof BuildEntity && !current.initialized){
|
||||
Core.app.post(() -> Events.fire(new BuildSelectEvent(tile, unit.getTeam(), this, current.breaking)));
|
||||
current.initialized = true;
|
||||
@@ -111,9 +106,17 @@ public interface BuilderTrait extends Entity, TeamTrait{
|
||||
}
|
||||
}
|
||||
|
||||
current.stuck = Mathf.equal(current.progress, entity.progress);
|
||||
current.progress = entity.progress;
|
||||
}
|
||||
|
||||
/** @return whether this request should be skipped, in favor of the next one. */
|
||||
default boolean shouldSkip(BuildRequest request, @Nullable TileEntity core){
|
||||
//requests that you have at least *started* are considered
|
||||
if(state.rules.infiniteResources || request.breaking || !request.initialized) return false;
|
||||
return request.stuck && !core.items.has(request.block.requirements);
|
||||
}
|
||||
|
||||
/** Returns the queue for storing build requests. */
|
||||
Queue<BuildRequest> buildQueue();
|
||||
|
||||
@@ -287,8 +290,8 @@ public interface BuilderTrait extends Entity, TeamTrait{
|
||||
|
||||
/** Last progress.*/
|
||||
public float progress;
|
||||
/** Whether construction has started for this request.*/
|
||||
public boolean initialized, worldContext = true;
|
||||
/** Whether construction has started for this request, and other special variables.*/
|
||||
public boolean initialized, worldContext = true, stuck;
|
||||
|
||||
/** Visual scale. Used only for rendering.*/
|
||||
public float animScale = 0f;
|
||||
|
||||
@@ -593,6 +593,11 @@ public class Player extends Unit implements BuilderMinerTrait, ShooterTrait{
|
||||
movement.x += xa * speed;
|
||||
}
|
||||
|
||||
if(Core.input.keyDown(Binding.mouse_move)){
|
||||
movement.x += Mathf.clamp((Core.input.mouseX() - Core.graphics.getWidth() / 2) * 0.005f, -1, 1) * speed;
|
||||
movement.y += Mathf.clamp((Core.input.mouseY() - Core.graphics.getHeight() / 2) * 0.005f, -1, 1) * speed;
|
||||
}
|
||||
|
||||
Vector2 vec = Core.input.mouseWorld(control.input.getMouseX(), control.input.getMouseY());
|
||||
pointerX = vec.x;
|
||||
pointerY = vec.y;
|
||||
|
||||
@@ -87,6 +87,11 @@ public class TileEntity extends BaseEntity implements TargetTrait, HealthTrait{
|
||||
return Time.delta() * timeScale;
|
||||
}
|
||||
|
||||
/** Base efficiency. If this entity has non-buffered power, returns the power %, otherwise returns 1. */
|
||||
public float efficiency(){
|
||||
return power != null && !block.consumes.getPower().buffered ? power.status : 1f;
|
||||
}
|
||||
|
||||
/** Call when nothing is happening to the entity. This increments the internal sleep timer. */
|
||||
public void sleep(){
|
||||
sleepTime += Time.delta();
|
||||
|
||||
@@ -27,7 +27,8 @@ public class EventType{
|
||||
drown,
|
||||
exclusionDeath,
|
||||
suicideBomb,
|
||||
openWiki
|
||||
openWiki,
|
||||
teamCoreDamage
|
||||
}
|
||||
|
||||
public static class WinEvent{}
|
||||
@@ -135,10 +136,14 @@ public class EventType{
|
||||
public static class DepositEvent{
|
||||
public final Tile tile;
|
||||
public final Player player;
|
||||
public final Item item;
|
||||
public final int amount;
|
||||
|
||||
public DepositEvent(Tile tile, Player player){
|
||||
public DepositEvent(Tile tile, Player player, Item item, int amount){
|
||||
this.tile = tile;
|
||||
this.player = player;
|
||||
this.item = item;
|
||||
this.amount = amount;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ public class LoopControl{
|
||||
data.curVolume = Mathf.lerpDelta(data.curVolume, data.volume * avol, 0.2f);
|
||||
|
||||
boolean play = data.curVolume > 0.01f;
|
||||
float pan = Mathf.isZero(data.total, 0.0001f) ? 0f : sound.calcPan(data.sum.x / data.total, data.sum.y / data.total);
|
||||
float pan = Mathf.zero(data.total, 0.0001f) ? 0f : sound.calcPan(data.sum.x / data.total, data.sum.y / data.total);
|
||||
if(data.soundID <= 0){
|
||||
if(play){
|
||||
data.soundID = sound.loop(data.curVolume, 1f, pan);
|
||||
|
||||
@@ -67,7 +67,7 @@ public class OverlayRenderer{
|
||||
if(!rect.setSize(Core.camera.width * 0.9f, Core.camera.height * 0.9f)
|
||||
.setCenter(Core.camera.position.x, Core.camera.position.y).contains(mechpad.x, mechpad.y)){
|
||||
|
||||
Tmp.v1.set(mechpad.worldx(), mechpad.worldy()).sub(Core.camera.position.x, Core.camera.position.y).setLength(indicatorLength);
|
||||
Tmp.v1.set(mechpad.drawx(), mechpad.drawy()).sub(Core.camera.position.x, Core.camera.position.y).setLength(indicatorLength);
|
||||
|
||||
Lines.stroke(2f, ((MechPad) mechpad.block()).mech.engineColor);
|
||||
Lines.lineAngle(Core.camera.position.x + Tmp.v1.x, Core.camera.position.y + Tmp.v1.y, Tmp.v1.angle(), 0.5f);
|
||||
|
||||
@@ -9,6 +9,8 @@ import io.anuke.arc.input.KeyCode;
|
||||
public enum Binding implements KeyBind{
|
||||
move_x(new Axis(KeyCode.A, KeyCode.D), "general"),
|
||||
move_y(new Axis(KeyCode.S, KeyCode.W)),
|
||||
mouse_move(KeyCode.MOUSE_BACK),
|
||||
dash(KeyCode.SHIFT_LEFT),
|
||||
select(KeyCode.MOUSE_LEFT),
|
||||
deselect(KeyCode.MOUSE_RIGHT),
|
||||
break_block(KeyCode.MOUSE_RIGHT),
|
||||
@@ -22,7 +24,6 @@ public enum Binding implements KeyBind{
|
||||
schematic_flip_x(KeyCode.Z),
|
||||
schematic_flip_y(KeyCode.X),
|
||||
schematic_menu(KeyCode.T),
|
||||
dash(KeyCode.SHIFT_LEFT),
|
||||
zoom_hold(KeyCode.CONTROL_LEFT, "view"),
|
||||
zoom(new Axis(KeyCode.SCROLL)),
|
||||
menu(Core.app.getType() == ApplicationType.Android ? KeyCode.BACK : KeyCode.ESCAPE),
|
||||
|
||||
@@ -50,9 +50,9 @@ public class DesktopInput extends InputHandler{
|
||||
b.defaults().left();
|
||||
b.label(() -> Core.bundle.format(!player.isBuilding ? "resumebuilding" : "pausebuilding", Core.keybinds.get(Binding.pause_building).key.toString())).style(Styles.outlineLabel);
|
||||
b.row();
|
||||
b.add(Core.bundle.format("cancelbuilding", Core.keybinds.get(Binding.clear_building).key.toString())).style(Styles.outlineLabel);
|
||||
b.label(() -> Core.bundle.format("cancelbuilding", Core.keybinds.get(Binding.clear_building).key.toString())).style(Styles.outlineLabel);
|
||||
b.row();
|
||||
b.add(Core.bundle.format("selectschematic", Core.keybinds.get(Binding.schematic_select).key.toString())).style(Styles.outlineLabel);
|
||||
b.label(() -> Core.bundle.format("selectschematic", Core.keybinds.get(Binding.schematic_select).key.toString())).style(Styles.outlineLabel);
|
||||
}).margin(10f);
|
||||
});
|
||||
|
||||
@@ -61,7 +61,7 @@ public class DesktopInput extends InputHandler{
|
||||
t.bottom();
|
||||
t.table(Styles.black6, b -> {
|
||||
b.defaults().left();
|
||||
b.add(Core.bundle.format("schematic.flip",
|
||||
b.label( () -> Core.bundle.format("schematic.flip",
|
||||
Core.keybinds.get(Binding.schematic_flip_x).key.toString(),
|
||||
Core.keybinds.get(Binding.schematic_flip_y).key.toString())).style(Styles.outlineLabel);
|
||||
b.row();
|
||||
|
||||
@@ -111,7 +111,7 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
|
||||
int[] remaining = {accepted, accepted};
|
||||
Block block = tile.block();
|
||||
|
||||
Core.app.post(() -> Events.fire(new DepositEvent(tile, player)));
|
||||
Core.app.post(() -> Events.fire(new DepositEvent(tile, player, item, accepted)));
|
||||
|
||||
for(int i = 0; i < sent; i++){
|
||||
boolean end = i == sent - 1;
|
||||
|
||||
@@ -14,6 +14,7 @@ import io.anuke.arc.util.reflect.Field;
|
||||
import io.anuke.arc.util.reflect.*;
|
||||
import io.anuke.arc.util.serialization.*;
|
||||
import io.anuke.arc.util.serialization.Json.*;
|
||||
import io.anuke.arc.util.serialization.Jval.*;
|
||||
import io.anuke.mindustry.*;
|
||||
import io.anuke.mindustry.content.*;
|
||||
import io.anuke.mindustry.content.TechTree.*;
|
||||
@@ -182,7 +183,7 @@ public class ContentParser{
|
||||
}else if(child.name.equals("liquid")){
|
||||
block.consumes.add((Consume)parser.readValue(ConsumeLiquid.class, child));
|
||||
}else if(child.name.equals("power")){
|
||||
if(child.isDouble()){
|
||||
if(child.isNumber()){
|
||||
block.consumes.power(child.asFloat());
|
||||
}else{
|
||||
block.consumes.add((Consume)parser.readValue(ConsumePower.class, child));
|
||||
@@ -342,10 +343,7 @@ public class ContentParser{
|
||||
init();
|
||||
}
|
||||
|
||||
//add comments starting with //, but ignore links
|
||||
json = json.replace("http://", "http:~~").replace("https://", "https:~~").replaceAll("//.*?\n","\n").replace("http:~~", "http://").replace("https:~~", "https://");
|
||||
|
||||
JsonValue value = parser.fromJson(null, json);
|
||||
JsonValue value = parser.fromJson(null, Jval.read(json).toString(Jformat.plain));
|
||||
if(!parsers.containsKey(type)){
|
||||
throw new SerializationException("No parsers for content type '" + type + "'");
|
||||
}
|
||||
|
||||
@@ -354,7 +354,7 @@ public class Mods implements Loadable{
|
||||
FileHandle folder = contentRoot.child(type.name().toLowerCase() + "s");
|
||||
if(folder.exists()){
|
||||
for(FileHandle file : folder.list()){
|
||||
if(file.extension().equals("json")){
|
||||
if(file.extension().equals("json") || file.extension().equals("hjson") || file.extension().equals("js")){
|
||||
runs.add(new LoadRun(type, file, mod));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ public class Bar extends Element{
|
||||
if(fraction == null) return;
|
||||
|
||||
float computed = Mathf.clamp(fraction.get());
|
||||
if(!Mathf.isEqual(lastValue, computed)){
|
||||
if(!Mathf.equal(lastValue, computed)){
|
||||
blink = 1f;
|
||||
lastValue = computed;
|
||||
}
|
||||
|
||||
@@ -32,14 +32,14 @@ public class JoinDialog extends FloatingDialog{
|
||||
|
||||
loadServers();
|
||||
|
||||
buttons.add().width(60f);
|
||||
buttons.add().growX();
|
||||
if(!steam) buttons.add().width(60f);
|
||||
buttons.add().growX().width(-1);
|
||||
|
||||
addCloseButton();
|
||||
|
||||
buttons.add().growX();
|
||||
buttons.add().growX().width(-1);
|
||||
if(!steam){
|
||||
buttons.addButton("?", () -> ui.showInfo("$join.info")).size(60f, 64f);
|
||||
buttons.addButton("?", () -> ui.showInfo("$join.info")).size(60f, 64f).width(-1);
|
||||
}
|
||||
|
||||
add = new FloatingDialog("$joingame.title");
|
||||
@@ -271,7 +271,7 @@ public class JoinDialog extends FloatingDialog{
|
||||
|
||||
Cell cell = ((Table)pane.getParent()).getCell(button);
|
||||
|
||||
if(!Mathf.isEqual(cell.minWidth(), pw)){
|
||||
if(!Mathf.equal(cell.minWidth(), pw)){
|
||||
cell.width(pw);
|
||||
cell.padLeft(pad);
|
||||
pane.getParent().invalidateHierarchy();
|
||||
|
||||
@@ -218,7 +218,7 @@ public class SettingsMenuDialog extends SettingsDialog{
|
||||
control.setInput(new MobileInput());
|
||||
}
|
||||
}*/
|
||||
game.sliderPref("saveinterval", 60, 10, 5 * 120, i -> Core.bundle.format("setting.seconds", i));
|
||||
game.sliderPref("saveinterval", 60, 10, 5 * 120, 10, i -> Core.bundle.format("setting.seconds", i));
|
||||
|
||||
if(!mobile){
|
||||
game.checkPref("crashreport", true);
|
||||
@@ -360,7 +360,11 @@ public class SettingsMenuDialog extends SettingsDialog{
|
||||
|
||||
keyDown(key -> {
|
||||
if(key == KeyCode.ESCAPE || key == KeyCode.BACK){
|
||||
hide();
|
||||
if(prefs.getChildren().first() != menu){
|
||||
back();
|
||||
}else{
|
||||
hide();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -42,10 +42,6 @@ public class HudFragment extends Fragment{
|
||||
private boolean shown = true;
|
||||
private float dsize = 47.2f;
|
||||
|
||||
private float coreAttackTime;
|
||||
private float lastCoreHP;
|
||||
private Team lastTeam;
|
||||
private float coreAttackOpacity = 0f;
|
||||
private long lastToast;
|
||||
|
||||
public void build(Group parent){
|
||||
@@ -284,44 +280,29 @@ public class HudFragment extends Fragment{
|
||||
parent.fill(t -> {
|
||||
t.touchable(Touchable.disabled);
|
||||
float notifDuration = 240f;
|
||||
float[] coreAttackTime = {0};
|
||||
float[] coreAttackOpacity = {0};
|
||||
|
||||
Events.on(StateChangeEvent.class, event -> {
|
||||
if(event.to == State.menu || event.from == State.menu){
|
||||
coreAttackTime = 0f;
|
||||
lastCoreHP = Float.NaN;
|
||||
}
|
||||
Events.on(Trigger.teamCoreDamage, () -> {
|
||||
coreAttackTime[0] = notifDuration;
|
||||
});
|
||||
|
||||
t.top().visible(() -> {
|
||||
if(state.is(State.menu) || state.teams.get(player.getTeam()).cores.size == 0 || state.teams.get(player.getTeam()).cores.first().entity == null){
|
||||
coreAttackTime = 0f;
|
||||
coreAttackTime[0] = 0f;
|
||||
return false;
|
||||
}
|
||||
|
||||
float curr = state.teams.get(player.getTeam()).cores.first().entity.health;
|
||||
|
||||
if(lastTeam != player.getTeam()){
|
||||
lastCoreHP = curr;
|
||||
lastTeam = player.getTeam();
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!Float.isNaN(lastCoreHP) && curr < lastCoreHP){
|
||||
coreAttackTime = notifDuration;
|
||||
}
|
||||
lastCoreHP = curr;
|
||||
|
||||
t.getColor().a = coreAttackOpacity;
|
||||
if(coreAttackTime > 0){
|
||||
coreAttackOpacity = Mathf.lerpDelta(coreAttackOpacity, 1f, 0.1f);
|
||||
t.getColor().a = coreAttackOpacity[0];
|
||||
if(coreAttackTime[0] > 0){
|
||||
coreAttackOpacity[0] = Mathf.lerpDelta(coreAttackOpacity[0], 1f, 0.1f);
|
||||
}else{
|
||||
coreAttackOpacity = Mathf.lerpDelta(coreAttackOpacity, 0f, 0.1f);
|
||||
coreAttackOpacity[0] = Mathf.lerpDelta(coreAttackOpacity[0], 0f, 0.1f);
|
||||
}
|
||||
|
||||
coreAttackTime -= Time.delta();
|
||||
lastTeam = player.getTeam();
|
||||
coreAttackTime[0] -= Time.delta();
|
||||
|
||||
return coreAttackOpacity > 0;
|
||||
return coreAttackOpacity[0] > 0;
|
||||
});
|
||||
t.table(Tex.button, top -> top.add("$coreattack").pad(2)
|
||||
.update(label -> label.getColor().set(Color.orange).lerp(Color.scarlet, Mathf.absin(Time.time(), 2f, 1f)))).touchable(Touchable.disabled);
|
||||
|
||||
@@ -207,7 +207,8 @@ public class Block extends BlockStorage{
|
||||
if(tile == null || tile.entity == null || tile.entity.power == null) return out;
|
||||
|
||||
for(Tile other : tile.entity.proximity()){
|
||||
if(other != null && other.entity != null && other.entity.power != null && !(consumesPower && other.block().consumesPower && !outputsPower && !other.block().outputsPower)
|
||||
if(other != null && other.entity != null && other.entity.power != null
|
||||
&& !(consumesPower && other.block().consumesPower && !outputsPower && !other.block().outputsPower)
|
||||
&& !tile.entity.power.links.contains(other.pos())){
|
||||
out.add(other);
|
||||
}
|
||||
@@ -221,11 +222,7 @@ public class Block extends BlockStorage{
|
||||
}
|
||||
|
||||
protected float getProgressIncrease(TileEntity entity, float baseTime){
|
||||
float progressIncrease = 1f / baseTime * entity.delta();
|
||||
if(hasPower){
|
||||
progressIncrease *= entity.power.satisfaction; // Reduced increase in case of low power
|
||||
}
|
||||
return progressIncrease;
|
||||
return 1f / baseTime * entity.delta() * entity.efficiency();
|
||||
}
|
||||
|
||||
/** @return whether this block should play its active sound.*/
|
||||
@@ -532,8 +529,8 @@ public class Block extends BlockStorage{
|
||||
boolean buffered = cons.buffered;
|
||||
float capacity = cons.capacity;
|
||||
|
||||
bars.add("power", entity -> new Bar(() -> buffered ? Core.bundle.format("bar.poweramount", Float.isNaN(entity.power.satisfaction * capacity) ? "<ERROR>" : (int)(entity.power.satisfaction * capacity)) :
|
||||
Core.bundle.get("bar.power"), () -> Pal.powerBar, () -> Mathf.isZero(cons.requestedPower(entity)) && entity.power.graph.getPowerProduced() + entity.power.graph.getBatteryStored() > 0f ? 1f : entity.power.satisfaction));
|
||||
bars.add("power", entity -> new Bar(() -> buffered ? Core.bundle.format("bar.poweramount", Float.isNaN(entity.power.status * capacity) ? "<ERROR>" : (int)(entity.power.status * capacity)) :
|
||||
Core.bundle.get("bar.power"), () -> Pal.powerBar, () -> Mathf.zero(cons.requestedPower(entity)) && entity.power.graph.getPowerProduced() + entity.power.graph.getBatteryStored() > 0f ? 1f : entity.power.status));
|
||||
}
|
||||
|
||||
if(hasItems && configurable){
|
||||
@@ -594,7 +591,7 @@ public class Block extends BlockStorage{
|
||||
}
|
||||
|
||||
if(consumes.hasPower() && consumes.getPower().buffered){
|
||||
power += tile.entity.power.satisfaction * consumes.getPower().capacity;
|
||||
power += tile.entity.power.status * consumes.getPower().capacity;
|
||||
}
|
||||
|
||||
if(hasLiquids){
|
||||
|
||||
@@ -28,6 +28,7 @@ public abstract class BlockStorage extends UnlockableContent{
|
||||
|
||||
public int itemCapacity = 10;
|
||||
public float liquidCapacity = 10f;
|
||||
public float liquidPressure = 1f;
|
||||
|
||||
public final BlockStats stats = new BlockStats();
|
||||
public final BlockBars bars = new BlockBars();
|
||||
@@ -150,7 +151,7 @@ public abstract class BlockStorage extends UnlockableContent{
|
||||
|
||||
if(next.block().acceptLiquid(next, tile, liquid, 0f)){
|
||||
float ofract = next.entity.liquids.get(liquid) / next.block().liquidCapacity;
|
||||
float fract = tile.entity.liquids.get(liquid) / liquidCapacity;
|
||||
float fract = tile.entity.liquids.get(liquid) / liquidCapacity * liquidPressure;
|
||||
float flow = Math.min(Mathf.clamp((fract - ofract) * (1f)) * (liquidCapacity), tile.entity.liquids.get(liquid));
|
||||
flow = Math.min(flow, next.block().liquidCapacity - next.entity.liquids.get(liquid) - 0.001f);
|
||||
|
||||
|
||||
@@ -318,6 +318,31 @@ public class Tile implements Position, TargetTrait{
|
||||
return null;
|
||||
}
|
||||
|
||||
public Tile getNearbyLink(int rotation){
|
||||
if(rotation == 0) return world.ltile(x + 1, y);
|
||||
if(rotation == 1) return world.ltile(x, y + 1);
|
||||
if(rotation == 2) return world.ltile(x - 1, y);
|
||||
if(rotation == 3) return world.ltile(x, y - 1);
|
||||
return null;
|
||||
}
|
||||
|
||||
// ▲ ▲ ▼ ▼ ◀ ▶ ◀ ▶ B A
|
||||
public Tile front(){
|
||||
return getNearbyLink((rotation + 4) % 4);
|
||||
}
|
||||
|
||||
public Tile right(){
|
||||
return getNearbyLink((rotation + 3) % 4);
|
||||
}
|
||||
|
||||
public Tile back(){
|
||||
return getNearbyLink((rotation + 2) % 4);
|
||||
}
|
||||
|
||||
public Tile left(){
|
||||
return getNearbyLink((rotation + 1) % 4);
|
||||
}
|
||||
|
||||
public boolean interactable(Team team){
|
||||
return getTeam() == Team.derelict || team == getTeam();
|
||||
}
|
||||
|
||||
@@ -108,12 +108,12 @@ public class ForceProjector extends Block{
|
||||
Effects.effect(Fx.reactorsmoke, tile.drawx() + Mathf.range(tilesize / 2f), tile.drawy() + Mathf.range(tilesize / 2f));
|
||||
}
|
||||
|
||||
entity.warmup = Mathf.lerpDelta(entity.warmup, entity.power.satisfaction, 0.1f);
|
||||
entity.warmup = Mathf.lerpDelta(entity.warmup, entity.efficiency(), 0.1f);
|
||||
|
||||
/*
|
||||
if(entity.power.satisfaction < relativePowerDraw){
|
||||
if(entity.power.status < relativePowerDraw){
|
||||
entity.warmup = Mathf.lerpDelta(entity.warmup, 0f, 0.15f);
|
||||
entity.power.satisfaction = 0f;
|
||||
entity.power.status = 0f;
|
||||
if(entity.warmup <= 0.09f){
|
||||
entity.broken = true;
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ public class MendProjector extends Block{
|
||||
|
||||
entity.phaseHeat = Mathf.lerpDelta(entity.phaseHeat, Mathf.num(entity.cons.optionalValid()), 0.1f);
|
||||
|
||||
if(entity.cons.optionalValid() && entity.timer.get(timerUse, useTime) && entity.power.satisfaction > 0){
|
||||
if(entity.cons.optionalValid() && entity.timer.get(timerUse, useTime) && entity.efficiency() > 0){
|
||||
entity.cons.trigger();
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ public class MendProjector extends Block{
|
||||
if(other == null) continue;
|
||||
|
||||
if(other.getTeamID() == tile.getTeamID() && !healed.contains(other.pos()) && other.entity != null && other.entity.health < other.entity.maxHealth()){
|
||||
other.entity.healBy(other.entity.maxHealth() * (healPercent + entity.phaseHeat * phaseBoost) / 100f * entity.power.satisfaction);
|
||||
other.entity.healBy(other.entity.maxHealth() * (healPercent + entity.phaseHeat * phaseBoost) / 100f * entity.efficiency());
|
||||
Effects.effect(Fx.healBlockFull, Tmp.c1.set(color).lerp(phase, entity.phaseHeat), other.drawx(), other.drawy(), other.block().size);
|
||||
healed.add(other.pos());
|
||||
}
|
||||
|
||||
@@ -74,13 +74,13 @@ public class OverdriveProjector extends Block{
|
||||
|
||||
entity.phaseHeat = Mathf.lerpDelta(entity.phaseHeat, Mathf.num(entity.cons.optionalValid()), 0.1f);
|
||||
|
||||
if(entity.timer.get(timerUse, useTime) && entity.power.satisfaction > 0){
|
||||
if(entity.timer.get(timerUse, useTime) && entity.efficiency() > 0){
|
||||
entity.cons.trigger();
|
||||
}
|
||||
|
||||
if(entity.charge >= reload){
|
||||
float realRange = range + entity.phaseHeat * phaseRangeBoost;
|
||||
float realBoost = (speedBoost + entity.phaseHeat * speedBoostPhase) * entity.power.satisfaction;
|
||||
float realBoost = (speedBoost + entity.phaseHeat * speedBoostPhase) * entity.efficiency();
|
||||
|
||||
entity.charge = 0f;
|
||||
|
||||
|
||||
@@ -47,6 +47,6 @@ public class PowerTurret extends CooledTurret{
|
||||
|
||||
@Override
|
||||
protected float baseReloadSpeed(Tile tile){
|
||||
return tile.isEnemyCheat() ? 1f : tile.entity.power.satisfaction;
|
||||
return tile.isEnemyCheat() ? 1f : tile.entity.power.status;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -200,7 +200,7 @@ public class Conveyor extends Block implements Autotiler{
|
||||
|
||||
if(maxmove > minmove){
|
||||
pos.y += maxmove;
|
||||
if(Mathf.isEqual(pos.x, 0, 0.1f)){
|
||||
if(Mathf.equal(pos.x, 0, 0.1f)){
|
||||
pos.x = 0f;
|
||||
}
|
||||
pos.x = Mathf.lerpDelta(pos.x, 0, 0.1f);
|
||||
|
||||
@@ -45,18 +45,7 @@ public class ItemBridge extends Block{
|
||||
|
||||
@Override
|
||||
public void configured(Tile tile, Player player, int value){
|
||||
ItemBridgeEntity entity = tile.entity();
|
||||
|
||||
if(world.tile(entity.link) != null && world.tile(entity.link).entity instanceof ItemBridgeEntity){
|
||||
ItemBridgeEntity oe = world.tile(entity.link).entity();
|
||||
oe.incoming.remove(tile.pos());
|
||||
}
|
||||
|
||||
entity.link = value;
|
||||
|
||||
if(world.tile(value) != null && world.tile(value).entity instanceof ItemBridgeEntity){
|
||||
((ItemBridgeEntity)world.tile(value).entity).incoming.add(tile.pos());
|
||||
}
|
||||
tile.<ItemBridgeEntity>entity().link = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -195,8 +184,9 @@ public class ItemBridge extends Block{
|
||||
tryDump(tile);
|
||||
entity.uptime = 0f;
|
||||
}else{
|
||||
((ItemBridgeEntity)world.tile(entity.link).entity).incoming.add(tile.pos());
|
||||
|
||||
if(entity.cons.valid() && (!hasPower || Mathf.isZero(1f - entity.power.satisfaction))){
|
||||
if(entity.cons.valid() && Mathf.zero(1f - entity.efficiency())){
|
||||
entity.uptime = Mathf.lerpDelta(entity.uptime, 1f, 0.04f);
|
||||
}else{
|
||||
entity.uptime = Mathf.lerpDelta(entity.uptime, 0f, 0.02f);
|
||||
|
||||
@@ -32,7 +32,7 @@ public class LiquidBridge extends ItemBridge{
|
||||
if(entity.cons.valid()){
|
||||
float alpha = 0.04f;
|
||||
if(hasPower){
|
||||
alpha *= entity.power.satisfaction; // Exceed boot time unless power is at max.
|
||||
alpha *= entity.efficiency(); // Exceed boot time unless power is at max.
|
||||
}
|
||||
entity.uptime = Mathf.lerpDelta(entity.uptime, 1f, alpha);
|
||||
}else{
|
||||
|
||||
@@ -77,7 +77,7 @@ public class MassDriver extends Block{
|
||||
|
||||
//reload regardless of state
|
||||
if(entity.reload > 0f){
|
||||
entity.reload = Mathf.clamp(entity.reload - entity.delta() / reloadTime * entity.power.satisfaction);
|
||||
entity.reload = Mathf.clamp(entity.reload - entity.delta() / reloadTime * entity.efficiency());
|
||||
}
|
||||
|
||||
//cleanup waiting shooters that are not valid
|
||||
@@ -113,7 +113,7 @@ public class MassDriver extends Block{
|
||||
}
|
||||
|
||||
//align to shooter rotation
|
||||
entity.rotation = Mathf.slerpDelta(entity.rotation, tile.angleTo(entity.currentShooter()), rotateSpeed * entity.power.satisfaction);
|
||||
entity.rotation = Mathf.slerpDelta(entity.rotation, tile.angleTo(entity.currentShooter()), rotateSpeed * entity.efficiency());
|
||||
}else if(entity.state == DriverState.shooting){
|
||||
//if there's nothing to shoot at OR someone wants to shoot at this thing, bail
|
||||
if(!hasLink || (!entity.waitingShooters.isEmpty() && (itemCapacity - entity.items.total() >= minDistribute))){
|
||||
@@ -133,7 +133,7 @@ public class MassDriver extends Block{
|
||||
if(entity.reload <= 0.0001f){
|
||||
|
||||
//align to target location
|
||||
entity.rotation = Mathf.slerpDelta(entity.rotation, targetRotation, rotateSpeed * entity.power.satisfaction);
|
||||
entity.rotation = Mathf.slerpDelta(entity.rotation, targetRotation, rotateSpeed * entity.efficiency());
|
||||
|
||||
//fire when it's the first in the queue and angles are ready.
|
||||
if(other.currentShooter() == tile &&
|
||||
|
||||
@@ -71,11 +71,11 @@ public class ImpactReactor extends PowerGenerator{
|
||||
public void update(Tile tile){
|
||||
FusionReactorEntity entity = tile.entity();
|
||||
|
||||
if(entity.cons.valid() && entity.power.satisfaction >= 0.99f){
|
||||
if(entity.cons.valid() && entity.power.status >= 0.99f){
|
||||
boolean prevOut = getPowerProduction(tile) <= consumes.getPower().requestedPower(entity);
|
||||
|
||||
entity.warmup = Mathf.lerpDelta(entity.warmup, 1f, warmupSpeed);
|
||||
if(Mathf.isEqual(entity.warmup, 1f, 0.001f)){
|
||||
if(Mathf.equal(entity.warmup, 1f, 0.001f)){
|
||||
entity.warmup = 1f;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
package io.anuke.mindustry.world.blocks.power;
|
||||
|
||||
import io.anuke.arc.Core;
|
||||
import io.anuke.arc.math.Mathf;
|
||||
import io.anuke.mindustry.ui.Bar;
|
||||
import io.anuke.arc.util.Eachable;
|
||||
import io.anuke.mindustry.ui.Cicon;
|
||||
import io.anuke.mindustry.world.Tile;
|
||||
import io.anuke.mindustry.world.Block;
|
||||
import io.anuke.arc.graphics.g2d.Draw;
|
||||
import io.anuke.mindustry.graphics.Pal;
|
||||
import io.anuke.arc.graphics.g2d.TextureRegion;
|
||||
import io.anuke.mindustry.entities.traits.BuilderTrait;
|
||||
|
||||
public class PowerDiode extends Block{
|
||||
protected TextureRegion arrow;
|
||||
|
||||
public PowerDiode(String name){
|
||||
super(name);
|
||||
rotate = true;
|
||||
update = true;
|
||||
solid = true;
|
||||
insulated = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(Tile tile){
|
||||
super.update(tile);
|
||||
|
||||
if(!tile.back().block().hasPower || !tile.front().block().hasPower) return;
|
||||
|
||||
PowerGraph backGraph = tile.back().entity.power.graph;
|
||||
PowerGraph frontGraph = tile.front().entity.power.graph;
|
||||
if(backGraph == frontGraph) return;
|
||||
|
||||
// 0f - 1f of battery capacity in use
|
||||
float backStored = backGraph.getBatteryStored() / backGraph.getTotalBatteryCapacity();
|
||||
float frontStored = frontGraph.getBatteryStored() / frontGraph.getTotalBatteryCapacity();
|
||||
|
||||
// try to send if the back side has more % capacity stored than the front side
|
||||
if(backStored > frontStored) {
|
||||
// send half of the difference
|
||||
float amount = backGraph.getBatteryStored() * (backStored - frontStored) / 2;
|
||||
// prevent sending more than the front can handle
|
||||
amount = Mathf.clamp(amount, 0, frontGraph.getTotalBatteryCapacity() * (1 - frontStored));
|
||||
|
||||
backGraph.useBatteries(amount);
|
||||
frontGraph.chargeBatteries(amount);
|
||||
}
|
||||
}
|
||||
|
||||
// battery % of the graph on either side, defaults to zero
|
||||
protected float bar(Tile tile){
|
||||
return tile.block().hasPower ? tile.entity.power.graph.getBatteryStored() / tile.entity.power.graph.getTotalBatteryCapacity() : 0f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBars(){
|
||||
super.setBars();
|
||||
|
||||
bars.add("back", entity -> new Bar("bar.input", Pal.lighterOrange, () -> bar(entity.tile.back())) );
|
||||
bars.add("front", entity -> new Bar("bar.output", Pal.lighterOrange, () -> bar(entity.tile.front())) );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(){
|
||||
super.load();
|
||||
arrow = Core.atlas.find(name + "-arrow");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Tile tile){
|
||||
Draw.rect(region, tile.drawx(), tile.drawy(), 0);
|
||||
Draw.rect(arrow, tile.drawx(), tile.drawy(), rotate ? tile.rotation() * 90 : 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawRequestRegion(BuilderTrait.BuildRequest req, Eachable<BuilderTrait.BuildRequest> list) {
|
||||
TextureRegion reg = icon(Cicon.full);
|
||||
Draw.rect(icon(Cicon.full), req.drawx(), req.drawy(),
|
||||
reg.getWidth() * req.animScale * Draw.scl,
|
||||
reg.getHeight() * req.animScale * Draw.scl,
|
||||
0);
|
||||
Draw.rect(arrow, req.drawx(), req.drawy(),
|
||||
arrow.getWidth() * req.animScale * Draw.scl,
|
||||
arrow.getHeight() * req.animScale * Draw.scl,
|
||||
!rotate ? 0 : req.rotation * 90);
|
||||
}
|
||||
}
|
||||
@@ -47,9 +47,9 @@ public class PowerGraph{
|
||||
}
|
||||
|
||||
public float getSatisfaction(){
|
||||
if(Mathf.isZero(lastPowerProduced)){
|
||||
if(Mathf.zero(lastPowerProduced)){
|
||||
return 0f;
|
||||
}else if(Mathf.isZero(lastPowerNeeded)){
|
||||
}else if(Mathf.zero(lastPowerNeeded)){
|
||||
return 1f;
|
||||
}
|
||||
return Mathf.clamp(lastPowerProduced / lastPowerNeeded);
|
||||
@@ -83,7 +83,7 @@ public class PowerGraph{
|
||||
for(Tile battery : batteries){
|
||||
Consumers consumes = battery.block().consumes;
|
||||
if(consumes.hasPower()){
|
||||
totalAccumulator += battery.entity.power.satisfaction * consumes.getPower().capacity;
|
||||
totalAccumulator += battery.entity.power.status * consumes.getPower().capacity;
|
||||
}
|
||||
}
|
||||
return totalAccumulator;
|
||||
@@ -94,7 +94,7 @@ public class PowerGraph{
|
||||
for(Tile battery : batteries){
|
||||
if(battery.block().consumes.hasPower()){
|
||||
ConsumePower power = battery.block().consumes.getPower();
|
||||
totalCapacity += (1f - battery.entity.power.satisfaction) * power.capacity;
|
||||
totalCapacity += (1f - battery.entity.power.status) * power.capacity;
|
||||
}
|
||||
}
|
||||
return totalCapacity;
|
||||
@@ -112,14 +112,14 @@ public class PowerGraph{
|
||||
|
||||
public float useBatteries(float needed){
|
||||
float stored = getBatteryStored();
|
||||
if(Mathf.isEqual(stored, 0f)) return 0f;
|
||||
if(Mathf.equal(stored, 0f)) return 0f;
|
||||
|
||||
float used = Math.min(stored, needed);
|
||||
float consumedPowerPercentage = Math.min(1.0f, needed / stored);
|
||||
for(Tile battery : batteries){
|
||||
Consumers consumes = battery.block().consumes;
|
||||
if(consumes.hasPower()){
|
||||
battery.entity.power.satisfaction *= (1f-consumedPowerPercentage);
|
||||
battery.entity.power.status *= (1f-consumedPowerPercentage);
|
||||
}
|
||||
}
|
||||
return used;
|
||||
@@ -129,14 +129,14 @@ public class PowerGraph{
|
||||
float capacity = getBatteryCapacity();
|
||||
//how much of the missing in each battery % is charged
|
||||
float chargedPercent = Math.min(excess/capacity, 1f);
|
||||
if(Mathf.isEqual(capacity, 0f)) return 0f;
|
||||
if(Mathf.equal(capacity, 0f)) return 0f;
|
||||
|
||||
for(Tile battery : batteries){
|
||||
Consumers consumes = battery.block().consumes;
|
||||
if(consumes.hasPower()){
|
||||
ConsumePower consumePower = consumes.getPower();
|
||||
if(consumePower.capacity > 0f){
|
||||
battery.entity.power.satisfaction += (1f-battery.entity.power.satisfaction) * chargedPercent;
|
||||
battery.entity.power.status += (1f-battery.entity.power.status) * chargedPercent;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -145,26 +145,26 @@ public class PowerGraph{
|
||||
|
||||
public void distributePower(float needed, float produced){
|
||||
//distribute even if not needed. this is because some might be requiring power but not using it; it updates consumers
|
||||
float coverage = Mathf.isZero(needed) && Mathf.isZero(produced) ? 0f : Mathf.isZero(needed) ? 1f : Math.min(1, produced / needed);
|
||||
float coverage = Mathf.zero(needed) && Mathf.zero(produced) ? 0f : Mathf.zero(needed) ? 1f : Math.min(1, produced / needed);
|
||||
for(Tile consumer : consumers){
|
||||
Consumers consumes = consumer.block().consumes;
|
||||
if(consumes.hasPower()){
|
||||
ConsumePower consumePower = consumes.getPower();
|
||||
if(consumePower.buffered){
|
||||
if(!Mathf.isZero(consumePower.capacity)){
|
||||
if(!Mathf.zero(consumePower.capacity)){
|
||||
// Add an equal percentage of power to all buffers, based on the global power coverage in this graph
|
||||
float maximumRate = consumePower.requestedPower(consumer.entity) * coverage * consumer.entity.delta();
|
||||
consumer.entity.power.satisfaction = Mathf.clamp(consumer.entity.power.satisfaction + maximumRate / consumePower.capacity);
|
||||
consumer.entity.power.status = Mathf.clamp(consumer.entity.power.status + maximumRate / consumePower.capacity);
|
||||
}
|
||||
}else{
|
||||
//valid consumers get power as usual
|
||||
if(otherConsumersAreValid(consumer, consumePower)){
|
||||
consumer.entity.power.satisfaction = coverage;
|
||||
consumer.entity.power.status = coverage;
|
||||
}else{ //invalid consumers get an estimate, if they were to activate
|
||||
consumer.entity.power.satisfaction = Math.min(1, produced / (needed + consumePower.usage * consumer.entity.delta()));
|
||||
consumer.entity.power.status = Math.min(1, produced / (needed + consumePower.usage * consumer.entity.delta()));
|
||||
//just in case
|
||||
if(Float.isNaN(consumer.entity.power.satisfaction)){
|
||||
consumer.entity.power.satisfaction = 0f;
|
||||
if(Float.isNaN(consumer.entity.power.status)){
|
||||
consumer.entity.power.status = 0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -176,9 +176,9 @@ public class PowerGraph{
|
||||
if(Core.graphics.getFrameId() == lastFrameUpdated){
|
||||
return;
|
||||
}else if(!consumers.isEmpty() && consumers.first().isEnemyCheat()){
|
||||
//when cheating, just set satisfaction to 1
|
||||
//when cheating, just set status to 1
|
||||
for(Tile tile : consumers){
|
||||
tile.entity.power.satisfaction = 1f;
|
||||
tile.entity.power.status = 1f;
|
||||
}
|
||||
|
||||
return;
|
||||
@@ -198,7 +198,7 @@ public class PowerGraph{
|
||||
return;
|
||||
}
|
||||
|
||||
if(!Mathf.isEqual(powerNeeded, powerProduced)){
|
||||
if(!Mathf.equal(powerNeeded, powerProduced)){
|
||||
if(powerNeeded > powerProduced){
|
||||
powerProduced += useBatteries(powerNeeded - powerProduced);
|
||||
}else if(powerProduced > powerNeeded){
|
||||
|
||||
@@ -19,6 +19,8 @@ import io.anuke.mindustry.world.meta.*;
|
||||
import static io.anuke.mindustry.Vars.*;
|
||||
|
||||
public class PowerNode extends PowerBlock{
|
||||
protected static boolean returnValue = false;
|
||||
|
||||
protected ObjectSet<PowerGraph> graphs = new ObjectSet<>();
|
||||
protected Vector2 t1 = new Vector2(), t2 = new Vector2();
|
||||
protected TextureRegion laser, laserEnd;
|
||||
@@ -305,7 +307,7 @@ public class PowerNode extends PowerBlock{
|
||||
|
||||
public boolean overlaps(@Nullable Tile src, @Nullable Tile other){
|
||||
if(src == null || other == null) return true;
|
||||
return overlaps(src.drawx(), src.drawy(), other, laserRange * tilesize);
|
||||
return Intersector.overlaps(Tmp.cr1.set(src.worldx() + offset(), src.worldy() + offset(), laserRange * tilesize), Tmp.r1.setSize(size * tilesize).setCenter(other.worldx() + offset(), other.worldy() + offset()));
|
||||
}
|
||||
|
||||
protected void drawLaser(Tile tile, Tile target){
|
||||
@@ -339,11 +341,9 @@ public class PowerNode extends PowerBlock{
|
||||
}
|
||||
|
||||
public static boolean insulated(int x, int y, int x2, int y2){
|
||||
final Boolean[] bool = {false};
|
||||
insulators(x, y, x2, y2, cause -> {
|
||||
bool[0] = true;
|
||||
});
|
||||
return bool[0];
|
||||
returnValue = false;
|
||||
insulators(x, y, x2, y2, cause -> returnValue = true);
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
public static void insulators(int x, int y, int x2, int y2, Cons<Tile> iterator){
|
||||
|
||||
@@ -257,9 +257,7 @@ public class Drill extends Block{
|
||||
speed = liquidBoostIntensity;
|
||||
}
|
||||
|
||||
if(hasPower){
|
||||
speed *= entity.power.satisfaction; // Drill slower when not at full power
|
||||
}
|
||||
speed *= entity.efficiency(); // Drill slower when not at full power
|
||||
|
||||
entity.lastDrillSpeed = (speed * entity.dominantItems * entity.warmup) / (drillTime + hardnessDrillMultiplier * entity.dominantItem.hardness);
|
||||
entity.warmup = Mathf.lerpDelta(entity.warmup, speed, warmupSpeed);
|
||||
|
||||
@@ -79,7 +79,7 @@ public class Fracker extends SolidPump{
|
||||
}
|
||||
|
||||
super.update(tile);
|
||||
entity.accumulator += entity.delta() * entity.power.satisfaction;
|
||||
entity.accumulator += entity.delta() * entity.efficiency();
|
||||
}else{
|
||||
tryDumpLiquid(tile, result);
|
||||
}
|
||||
|
||||
@@ -38,10 +38,8 @@ public class LiquidConverter extends GenericCrafter{
|
||||
ConsumeLiquidBase cl = consumes.get(ConsumeType.liquid);
|
||||
|
||||
if(tile.entity.cons.valid()){
|
||||
float use = Math.min(cl.amount * entity.delta(), liquidCapacity - entity.liquids.get(outputLiquid.liquid));
|
||||
if(hasPower){
|
||||
use *= entity.power.satisfaction; // Produce less liquid if power is not maxed
|
||||
}
|
||||
float use = Math.min(cl.amount * entity.delta(), liquidCapacity - entity.liquids.get(outputLiquid.liquid)) * entity.efficiency();
|
||||
|
||||
useContent(tile, outputLiquid.liquid);
|
||||
entity.progress += use / cl.amount / craftTime;
|
||||
entity.liquids.add(outputLiquid.liquid, use);
|
||||
|
||||
@@ -119,10 +119,7 @@ public class Pump extends LiquidBlock{
|
||||
}
|
||||
|
||||
if(tile.entity.cons.valid() && liquidDrop != null){
|
||||
float maxPump = Math.min(liquidCapacity - tile.entity.liquids.total(), tiles * pumpAmount * tile.entity.delta() / size / size);
|
||||
if(hasPower){
|
||||
maxPump *= tile.entity.power.satisfaction; // Produce slower if not at full power
|
||||
}
|
||||
float maxPump = Math.min(liquidCapacity - tile.entity.liquids.total(), tiles * pumpAmount * tile.entity.delta() / size / size) * tile.entity.efficiency();
|
||||
tile.entity.liquids.add(liquidDrop, maxPump);
|
||||
}
|
||||
|
||||
|
||||
@@ -101,7 +101,7 @@ public class SolidPump extends Pump{
|
||||
fraction += entity.boost;
|
||||
|
||||
if(tile.entity.cons.valid() && typeLiquid(tile) < liquidCapacity - 0.001f){
|
||||
float maxPump = Math.min(liquidCapacity - typeLiquid(tile), pumpAmount * entity.delta() * fraction * entity.power.satisfaction);
|
||||
float maxPump = Math.min(liquidCapacity - typeLiquid(tile), pumpAmount * entity.delta() * fraction * entity.efficiency());
|
||||
tile.entity.liquids.add(result, maxPump);
|
||||
entity.warmup = Mathf.lerpDelta(entity.warmup, 1f, 0.02f);
|
||||
if(Mathf.chance(entity.delta() * updateEffectChance))
|
||||
|
||||
@@ -130,6 +130,14 @@ public class CoreBlock extends StorageBlock{
|
||||
return tile.entity instanceof StorageBlockEntity;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float handleDamage(Tile tile, float amount){
|
||||
if(player != null && tile.getTeam() == player.getTeam()){
|
||||
Events.fire(Trigger.teamCoreDamage);
|
||||
}
|
||||
return amount;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBreak(Tile tile){
|
||||
return false;
|
||||
|
||||
@@ -100,7 +100,7 @@ public class RepairPoint extends Block{
|
||||
if(entity.target != null && (entity.target.isDead() || entity.target.dst(tile) > repairRadius || entity.target.health >= entity.target.maxHealth())){
|
||||
entity.target = null;
|
||||
}else if(entity.target != null && entity.cons.valid()){
|
||||
entity.target.health += repairSpeed * Time.delta() * entity.strength * entity.power.satisfaction;
|
||||
entity.target.health += repairSpeed * Time.delta() * entity.strength * entity.efficiency();
|
||||
entity.target.clampHealth();
|
||||
entity.rotation = Mathf.slerpDelta(entity.rotation, entity.angleTo(entity.target), 0.5f);
|
||||
targetIsBeingRepaired = true;
|
||||
|
||||
@@ -159,8 +159,8 @@ public class UnitFactory extends Block{
|
||||
}
|
||||
|
||||
if(entity.cons.valid() || tile.isEnemyCheat()){
|
||||
entity.time += entity.delta() * entity.speedScl * Vars.state.rules.unitBuildSpeedMultiplier * entity.power.satisfaction;
|
||||
entity.buildTime += entity.delta() * entity.power.satisfaction * Vars.state.rules.unitBuildSpeedMultiplier;
|
||||
entity.time += entity.delta() * entity.speedScl * Vars.state.rules.unitBuildSpeedMultiplier * entity.efficiency();
|
||||
entity.buildTime += entity.delta() * entity.efficiency() * Vars.state.rules.unitBuildSpeedMultiplier;
|
||||
entity.speedScl = Mathf.lerpDelta(entity.speedScl, 1f, 0.05f);
|
||||
}else{
|
||||
entity.speedScl = Mathf.lerpDelta(entity.speedScl, 0f, 0.05f);
|
||||
|
||||
@@ -42,7 +42,7 @@ public class ConsumePower extends Consume{
|
||||
|
||||
@Override
|
||||
public void update(TileEntity entity){
|
||||
// Nothing to do since PowerGraph directly updates entity.power.satisfaction
|
||||
// Nothing to do since PowerGraph directly updates entity.power.status
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -50,7 +50,7 @@ public class ConsumePower extends Consume{
|
||||
if(buffered){
|
||||
return true;
|
||||
}else{
|
||||
return entity.power.satisfaction > 0f;
|
||||
return entity.power.status > 0f;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ public class ConsumePower extends Consume{
|
||||
public float requestedPower(TileEntity entity){
|
||||
if(entity.tile.entity == null) return 0f;
|
||||
if(buffered){
|
||||
return (1f-entity.power.satisfaction)*capacity;
|
||||
return (1f-entity.power.status)*capacity;
|
||||
}else{
|
||||
try{
|
||||
return usage * Mathf.num(entity.block.shouldConsume(entity.tile));
|
||||
|
||||
@@ -41,9 +41,9 @@ public class AmmoListValue<T extends UnlockableContent> implements StatValue{
|
||||
sep(bt, Core.bundle.format("bullet.splashdamage", (int)type.splashDamage, Strings.fixed(type.splashDamageRadius / tilesize, 1)));
|
||||
}
|
||||
|
||||
if(!Mathf.isEqual(type.ammoMultiplier, 1f))
|
||||
if(!Mathf.equal(type.ammoMultiplier, 1f))
|
||||
sep(bt, Core.bundle.format("bullet.multiplier", (int)type.ammoMultiplier));
|
||||
if(!Mathf.isEqual(type.reloadMultiplier, 1f))
|
||||
if(!Mathf.equal(type.reloadMultiplier, 1f))
|
||||
sep(bt, Core.bundle.format("bullet.reload", Strings.fixed(type.reloadMultiplier, 1)));
|
||||
|
||||
if(type.knockback > 0){
|
||||
|
||||
@@ -13,7 +13,7 @@ public class PowerModule extends BlockModule{
|
||||
* Blocks will work at a reduced efficiency if this is not equal to 1.0f.
|
||||
* In case of buffered consumers, this is the percentage of power stored in relation to the maximum capacity.
|
||||
*/
|
||||
public float satisfaction = 0.0f;
|
||||
public float status = 0.0f;
|
||||
public PowerGraph graph = new PowerGraph();
|
||||
public IntArray links = new IntArray();
|
||||
|
||||
@@ -23,7 +23,7 @@ public class PowerModule extends BlockModule{
|
||||
for(int i = 0; i < links.size; i++){
|
||||
stream.writeInt(links.get(i));
|
||||
}
|
||||
stream.writeFloat(satisfaction);
|
||||
stream.writeFloat(status);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -32,7 +32,7 @@ public class PowerModule extends BlockModule{
|
||||
for(int i = 0; i < amount; i++){
|
||||
links.add(stream.readInt());
|
||||
}
|
||||
satisfaction = stream.readFloat();
|
||||
if(Float.isNaN(satisfaction) || Float.isInfinite(satisfaction)) satisfaction = 0f;
|
||||
status = stream.readFloat();
|
||||
if(Float.isNaN(status) || Float.isInfinite(status)) status = 0f;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user