Resolve conflicts

# Conflicts:
#	core/assets/sprites/block_colors.png
#	core/assets/sprites/sprites.atlas
#	core/assets/sprites/sprites.png
#	core/assets/sprites/sprites3.png
#	core/assets/sprites/sprites5.png
This commit is contained in:
Patrick 'Quezler' Mounier
2019-11-12 08:44:26 +01:00
84 changed files with 3281 additions and 2412 deletions

View File

@@ -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,
@@ -1071,6 +1071,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);

View File

@@ -26,6 +26,7 @@ public class Liquids implements ContentList{
flammability = 1.2f;
explosiveness = 1.2f;
heatCapacity = 0.7f;
barColor = Color.valueOf("6b675f");
effect = StatusEffects.tarred;
}};

View File

@@ -194,7 +194,7 @@ public class Mechs implements ContentList{
@Override
public void updateAlt(Player player){
float scl = 1f - player.shootHeat / 2f;
float scl = 1f - player.shootHeat / 2f*Time.delta();
player.velocity().scl(scl);
}

View File

@@ -215,8 +215,10 @@ public class TechTree implements ContentList{
node(combustionGenerator, () -> {
node(powerNode, () -> {
node(powerNodeLarge, () -> {
node(surgeTower, () -> {
node(diode, () -> {
node(surgeTower, () -> {
});
});
});

View File

@@ -36,7 +36,7 @@ public class MissileBulletType extends BasicBulletType{
}
if(weaveMag > 0){
b.velocity().rotate(Mathf.sin(Time.time() + b.id * 4422, weaveScale, weaveMag));
b.velocity().rotate(Mathf.sin(Time.time() + b.id * 4422, weaveScale, weaveMag) * Time.delta());
}
}
}

View File

@@ -52,6 +52,7 @@ public class Player extends Unit implements BuilderMinerTrait, ShooterTrait{
public @Nullable
String uuid, usid;
public boolean isAdmin, isTransferring, isShooting, isBoosting, isMobile, isTyping, isBuilding = true;
public boolean buildWasAutoPaused = false;
public float boostHeat, shootHeat, destructTime;
public boolean achievedFlight;
public Color color = new Color();
@@ -592,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;

View File

@@ -135,10 +135,38 @@ 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;
}
}
/** Called when the player taps a block. */
public static class TapEvent{
public final Tile tile;
public final Player player;
public TapEvent(Tile tile, Player player){
this.tile = tile;
this.player = player;
}
}
/** Called when the player sets a specific block. */
public static class TapConfigEvent{
public final Tile tile;
public final Player player;
public final int value;
public TapConfigEvent(Tile tile, Player player, int value){
this.tile = tile;
this.player = player;
this.value = value;
}
}

View File

@@ -10,13 +10,11 @@ import io.anuke.arc.math.geom.*;
import io.anuke.arc.scene.ui.layout.*;
import io.anuke.arc.util.*;
import io.anuke.arc.util.pooling.*;
import io.anuke.mindustry.content.TypeIDs;
import io.anuke.mindustry.entities.*;
import io.anuke.mindustry.entities.type.*;
import io.anuke.mindustry.game.EventType.*;
import io.anuke.mindustry.io.*;
import io.anuke.mindustry.ui.*;
import io.anuke.mindustry.ui.dialogs.*;
import io.anuke.mindustry.world.*;
import static io.anuke.mindustry.Vars.*;
@@ -151,6 +149,10 @@ public class MinimapRenderer implements Disposable{
private int colorFor(Tile tile){
if(tile == null) return 0;
tile = tile.link();
int bc = tile.block().minimapColor(tile);
if(bc != 0){
return bc;
}
return Tmp.c1.set(MapIO.colorFor(tile.floor(), tile.block(), tile.overlay(), tile.getTeam())).mul(tile.block().cacheLayer == CacheLayer.walls ? 1f - tile.rotation() / 4f : 1f).rgba();
}

View File

@@ -9,6 +9,7 @@ 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),
select(KeyCode.MOUSE_LEFT),
deselect(KeyCode.MOUSE_RIGHT),
break_block(KeyCode.MOUSE_RIGHT),
@@ -31,12 +32,12 @@ public enum Binding implements KeyBind{
minimap(KeyCode.M),
toggle_menus(KeyCode.C),
screenshot(KeyCode.P),
toggle_power_lines(KeyCode.F7),
player_list(KeyCode.TAB, "multiplayer"),
chat(KeyCode.ENTER),
chat_history_prev(KeyCode.UP),
chat_history_next(KeyCode.DOWN),
chat_scroll(new Axis(KeyCode.SCROLL)),
;
private final KeybindValue defaultValue;

View File

@@ -48,11 +48,11 @@ public class DesktopInput extends InputHandler{
t.touchable(() -> t.getColor().a < 0.1f ? Touchable.disabled : Touchable.childrenOnly);
t.table(Styles.black6, b -> {
b.defaults().left();
b.label(() -> Core.bundle.format(!player.isBuilding ? "resumebuilding" : "pausebuilding", Core.keybinds.get(Binding.pause_building).key.name())).style(Styles.outlineLabel);
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.name())).style(Styles.outlineLabel);
b.add(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.name())).style(Styles.outlineLabel);
b.add(Core.bundle.format("selectschematic", Core.keybinds.get(Binding.schematic_select).key.toString())).style(Styles.outlineLabel);
}).margin(10f);
});
@@ -62,8 +62,8 @@ public class DesktopInput extends InputHandler{
t.table(Styles.black6, b -> {
b.defaults().left();
b.add(Core.bundle.format("schematic.flip",
Core.keybinds.get(Binding.schematic_flip_x).key.name(),
Core.keybinds.get(Binding.schematic_flip_y).key.name())).style(Styles.outlineLabel);
Core.keybinds.get(Binding.schematic_flip_x).key.toString(),
Core.keybinds.get(Binding.schematic_flip_y).key.toString())).style(Styles.outlineLabel);
b.row();
b.table(a -> {
a.addImageTextButton("$schematic.add", Icon.saveSmall, this::showSchematicSave).colspan(2).size(250f, 50f).disabled(f -> lastSchematic == null || lastSchematic.file != null);
@@ -267,6 +267,12 @@ public class DesktopInput extends InputHandler{
int cursorY = tileY(Core.input.mouseY());
int rawCursorX = world.toTile(Core.input.mouseWorld().x), rawCursorY = world.toTile(Core.input.mouseWorld().y);
// automatically pause building if the current build queue is empty
if(Core.settings.getBool("buildautopause") && player.isBuilding && !player.isBuilding()){
player.isBuilding = false;
player.buildWasAutoPaused = true;
}
if(!selectRequests.isEmpty()){
int shiftX = rawCursorX - schematicX, shiftY = rawCursorY - schematicY;
@@ -337,6 +343,7 @@ public class DesktopInput extends InputHandler{
if(Core.input.keyTap(Binding.pause_building)){
player.isBuilding = !player.isBuilding;
player.buildWasAutoPaused = false;
}
if((cursorX != lastLineX || cursorY != lastLineY) && isPlacing() && mode == placing){
@@ -422,6 +429,15 @@ public class DesktopInput extends InputHandler{
mode = none;
}
if(Core.input.keyTap(Binding.toggle_power_lines)){
if(Core.settings.getInt("lasersopacity") == 0){
Core.settings.put("lasersopacity", Core.settings.getInt("preferredlaseropacity", 100));
}else{
Core.settings.put("preferredlaseropacity", Core.settings.getInt("lasersopacity"));
Core.settings.put("lasersopacity", 0);
}
}
}
@Override

View File

@@ -32,6 +32,7 @@ import io.anuke.mindustry.ui.fragments.*;
import io.anuke.mindustry.world.*;
import io.anuke.mindustry.world.blocks.*;
import io.anuke.mindustry.world.blocks.BuildBlock.*;
import io.anuke.mindustry.world.blocks.power.PowerNode;
import java.util.*;
@@ -110,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;
@@ -144,12 +145,14 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
if(tile == null || player == null) return;
if(!Units.canInteract(player, tile)) return;
tile.block().tapped(tile, player);
Core.app.post(() -> Events.fire(new TapEvent(tile, player)));
}
@Remote(targets = Loc.both, called = Loc.both, forward = true)
public static void onTileConfig(Player player, Tile tile, int value){
if(tile == null || !Units.canInteract(player, tile)) return;
tile.block().configured(tile, player, value);
Core.app.post(() -> Events.fire(new TapConfigEvent(tile, player, value)));
}
public Eachable<BuildRequest> allRequests(){
@@ -806,16 +809,44 @@ public abstract class InputHandler implements InputProcessor, GestureListener{
void iterateLine(int startX, int startY, int endX, int endY, Cons<PlaceLine> cons){
Array<Point2> points;
boolean diagonal = Core.input.keyDown(Binding.diagonal_placement);
if(Core.settings.getBool("swapdiagonal") && mobile){
diagonal = !diagonal;
}
if(block instanceof PowerNode){
diagonal = !diagonal;
}
if(diagonal){
points = Placement.pathfindLine(block != null && block.conveyorPlacement, startX, startY, endX, endY);
}else{
points = Placement.normalizeLine(startX, startY, endX, endY);
}
if(block instanceof PowerNode){
Array<Point2> skip = new Array<>();
for(int i = 1; i < points.size; i++){
int overlaps = 0;
Point2 point = points.get(i);
//check with how many powernodes the *next* tile will overlap
for(int j = 0; j < i; j++){
if(!skip.contains(points.get(j)) && ((PowerNode)block).overlaps(world.ltile(point.x, point.y), world.ltile(points.get(j).x, points.get(j).y))){
overlaps++;
}
}
//if it's more than one, it can bridge the gap
if(overlaps > 1){
skip.add(points.get(i-1));
}
}
//remove skipped points
points.removeAll(skip);
}
float angle = Angles.angle(startX, startY, endX, endY);
int baseRotation = rotation;
if(!overrideLineRotation || diagonal){

View File

@@ -1,5 +1,6 @@
package io.anuke.mindustry.input;
import io.anuke.arc.*;
import io.anuke.arc.collection.*;
import io.anuke.arc.math.*;
import io.anuke.arc.math.geom.*;
@@ -26,7 +27,7 @@ public class Placement{
Pools.freeAll(points);
points.clear();
if(conveyors){
if(conveyors && Core.settings.getBool("conveyorpathfinding")){
if(astar(startX, startY, endX, endY)){
return points;
}else{

View File

@@ -342,6 +342,9 @@ 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);
if(!parsers.containsKey(type)){
throw new SerializationException("No parsers for content type '" + type + "'");

View File

@@ -11,6 +11,7 @@ public class Host{
public final int version;
public final String versionType;
public final Gamemode mode;
public int ping;
public Host(String name, String address, String mapname, int wave, int players, int version, String versionType, Gamemode mode, int playerLimit){
this.name = name;

View File

@@ -3,13 +3,16 @@ package io.anuke.mindustry.type;
import io.anuke.arc.*;
import io.anuke.arc.graphics.*;
import io.anuke.arc.scene.ui.layout.*;
import io.anuke.arc.util.ArcAnnotate.*;
import io.anuke.mindustry.content.*;
import io.anuke.mindustry.ctype.UnlockableContent;
import io.anuke.mindustry.ui.*;
public class Liquid extends UnlockableContent{
public final Color color;
public final @NonNull Color color;
/** Color used in bars. */
public @Nullable Color barColor;
/** 0-1, 0 is completely inflammable, anything above that may catch fire when exposed to heat, 0.5+ is very flammable. */
public float flammability;
/** temperature: 0.5 is 'room' temperature, 0 is very cold, 1 is molten hot */
@@ -20,8 +23,6 @@ public class Liquid extends UnlockableContent{
public float viscosity = 0.5f;
/** how prone to exploding this liquid is, when heated. 0 = nothing, 1 = nuke */
public float explosiveness;
/** the burning color of this liquid */
public Color flameColor = Color.valueOf("ffb763");
/** The associated status effect. */
public StatusEffect effect = StatusEffects.none;
@@ -40,6 +41,10 @@ public class Liquid extends UnlockableContent{
return flammability < 0.1f && temperature <= 0.5f;
}
public Color barColor(){
return barColor == null ? color : barColor;
}
@Override
public void displayInfo(Table table){
ContentDisplay.displayLiquid(table, this);

View File

@@ -18,7 +18,7 @@ import java.util.*;
import static io.anuke.mindustry.Vars.platform;
public class FileChooser extends FloatingDialog{
private static final FileHandle homeDirectory = Core.files.absolute(OS.isMac ? OS.getProperty("user.home") + "/Downloads/" : Core.files.getExternalStoragePath());
private static final FileHandle homeDirectory = Core.files.absolute(Core.files.getExternalStoragePath());
private static FileHandle lastDirectory = homeDirectory;
private Table files;
@@ -98,10 +98,6 @@ public class FileChooser extends FloatingDialog{
updateFiles(true);
});
//Macs are confined to the Downloads/ directory
if(OS.isMac){
up.setDisabled(true);
}
ImageButton back = new ImageButton(Icon.arrowLeft);
ImageButton forward = new ImageButton(Icon.arrowRight);
@@ -171,8 +167,7 @@ public class FileChooser extends FloatingDialog{
private void updateFiles(boolean push){
if(push) stack.push(directory);
//if is mac, don't display extra info since you can only ever go to downloads
navigation.setText(OS.isMac ? directory.name() : directory.toString());
navigation.setText(directory.toString());
GlyphLayout layout = Pools.obtain(GlyphLayout.class, GlyphLayout::new);
@@ -190,23 +185,21 @@ public class FileChooser extends FloatingDialog{
files.top().left();
FileHandle[] names = getFileNames();
//macs are confined to the Downloads/ directory
if(!OS.isMac){
Image upimage = new Image(Icon.folderParentSmall);
TextButton upbutton = new TextButton(".." + directory.toString(), Styles.clearTogglet);
upbutton.clicked(() -> {
directory = directory.parent();
lastDirectory = directory;
updateFiles(true);
});
Image upimage = new Image(Icon.folderParentSmall);
TextButton upbutton = new TextButton(".." + directory.toString(), Styles.clearTogglet);
upbutton.clicked(() -> {
directory = directory.parent();
lastDirectory = directory;
updateFiles(true);
});
upbutton.left().add(upimage).padRight(4f).padLeft(4);
upbutton.getLabel().setAlignment(Align.left);
upbutton.getCells().reverse();
upbutton.left().add(upimage).padRight(4f).padLeft(4);
upbutton.getLabel().setAlignment(Align.left);
upbutton.getCells().reverse();
files.add(upbutton).align(Align.topLeft).fillX().expandX().height(50).pad(2).colspan(2);
files.row();
files.add(upbutton).align(Align.topLeft).fillX().expandX().height(50).pad(2).colspan(2);
files.row();
}
ButtonGroup<TextButton> group = new ButtonGroup<>();
group.setMinCheckCount(0);

View File

@@ -95,7 +95,7 @@ public class ModsDialog extends FloatingDialog{
void modError(Throwable error){
ui.loadfrag.hide();
if(Strings.getCauses(error).contains(t -> t.getMessage() != null && t.getMessage().contains("SSL"))){
if(Strings.getCauses(error).contains(t -> t.getMessage() != null && (t.getMessage().contains("SSL") || t.getMessage().contains("protocol")))){
ui.showErrorMessage("$feature.unsupported");
}else{
ui.showException(error);

View File

@@ -225,10 +225,12 @@ public class SettingsMenuDialog extends SettingsDialog{
}
game.checkPref("savecreate", true);
game.checkPref("blockreplace", true);
game.checkPref("conveyorpathfinding", true);
game.checkPref("hints", true);
if(!mobile){
game.checkPref("buildautopause", false);
}
if(steam && !Version.modifier.contains("beta")){
game.checkPref("publichost", false, i -> {
@@ -257,7 +259,12 @@ public class SettingsMenuDialog extends SettingsDialog{
});
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 -> s + "%");
graphics.sliderPref("lasersopacity", 100, 0, 100, 5, s -> {
if(ui.settings != null){
Core.settings.put("preferredlaseropacity", s);
}
return s + "%";
});
if(!mobile){
graphics.checkPref("vsync", true, b -> Core.graphics.setVSync(b));

View File

@@ -164,7 +164,8 @@ public class MenuFragment extends Fragment{
),
new Buttoni("$editor", Icon.editorSmall, ui.maps::show), steam ? new Buttoni("$workshop", Icon.saveSmall, platform::openWorkshop) : null,
new Buttoni(Core.bundle.get("mods") + "\n" + Core.bundle.get("mods.alpha"), Icon.wikiSmall, ui.mods::show),
new Buttoni("$schematics", Icon.pasteSmall, ui.schematics::show),
//not enough space for this button
//new Buttoni("$schematics", Icon.pasteSmall, ui.schematics::show),
new Buttoni("$settings", Icon.toolsSmall, ui.settings::show),
new Buttoni("$about.button", Icon.infoSmall, ui.about::show),
new Buttoni("$quit", Icon.exitSmall, Core.app::exit)

View File

@@ -235,7 +235,7 @@ public class Block extends BlockStorage{
/** @return whether this block should play its idle sound.*/
public boolean shouldIdleSound(Tile tile){
return canProduce(tile);
return shouldConsume(tile);
}
public void drawLayer(Tile tile){
@@ -524,7 +524,7 @@ public class Block extends BlockStorage{
current = entity -> entity.liquids.current();
}
bars.add("liquid", entity -> new Bar(() -> entity.liquids.get(current.get(entity)) <= 0.001f ? Core.bundle.get("bar.liquid") : current.get(entity).localizedName(),
() -> current.get(entity).color, () -> entity.liquids.get(current.get(entity)) / liquidCapacity));
() -> current.get(entity).barColor(), () -> entity.liquids.get(current.get(entity)) / liquidCapacity));
}
if(hasPower && consumes.hasPower()){
@@ -716,6 +716,11 @@ public class Block extends BlockStorage{
Draw.color();
}
/** @return a custom minimap color for this tile, or 0 to use default colors. */
public int minimapColor(Tile tile){
return 0;
}
public void drawRequestConfigTop(BuildRequest req, Eachable<BuildRequest> list){
}

View File

@@ -41,6 +41,10 @@ public abstract class BlockStorage extends UnlockableContent{
return true;
}
public boolean productionValid(Tile tile){
return true;
}
public float getPowerProduction(Tile tile){
return 0f;
}
@@ -111,6 +115,8 @@ public abstract class BlockStorage extends UnlockableContent{
Tile other = proximity.get((i + dump) % proximity.size);
Tile in = Edges.getFacingEdge(tile, other);
other = other.block().getLiquidDestination(other, tile);
if(other.getTeam() == tile.getTeam() && other.block().hasLiquids && canDumpLiquid(tile, other, liquid) && other.entity.liquids != null){
float ofract = other.entity.liquids.get(liquid) / other.block().liquidCapacity;
float fract = tile.entity.liquids.get(liquid) / liquidCapacity;
@@ -142,6 +148,7 @@ public abstract class BlockStorage extends UnlockableContent{
if(next == null) return 0;
next = next.link();
next = next.block().getLiquidDestination(next, tile);
if(next.getTeam() == tile.getTeam() && next.block().hasLiquids && tile.entity.liquids.get(liquid) > 0f){
@@ -179,6 +186,10 @@ public abstract class BlockStorage extends UnlockableContent{
return 0;
}
public Tile getLiquidDestination(Tile tile, Tile from){
return tile;
}
/**
* Tries to put this item into a nearby container, if there are no available
* containers, it gets added to the block's inventory.
@@ -270,9 +281,4 @@ public abstract class BlockStorage extends UnlockableContent{
}
return false;
}
/** Returns whether this block's inventory has space and is ready for production. */
public boolean canProduce(Tile tile){
return true;
}
}

View File

@@ -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();
}

View File

@@ -144,6 +144,9 @@ public class BuildBlock extends Block{
//if the target is constructible, begin constructing
if(entity.cblock != null){
if(player.buildWasAutoPaused && !player.isBuilding){
player.isBuilding = true;
}
//player.clearBuilding();
player.addBuildRequest(new BuildRequest(tile.x, tile.y, tile.rotation(), entity.cblock), false);
}

View File

@@ -31,7 +31,6 @@ public class ForceProjector extends Block{
protected float cooldownLiquid = 1.5f;
protected float cooldownBrokenBase = 0.35f;
protected float basePowerDraw = 0.2f;
protected float powerDamage = 0.1f;
protected TextureRegion topRegion;
private static Tile paramTile;
@@ -73,8 +72,6 @@ public class ForceProjector extends Block{
super.setStats();
stats.add(BlockStat.powerUse, basePowerDraw * 60f, StatUnit.powerSecond);
stats.add(BlockStat.powerDamage, powerDamage, StatUnit.powerUnits);
stats.add(BlockStat.boostEffect, phaseRadiusBoost / tilesize, StatUnit.blocks);
}

View File

@@ -6,7 +6,7 @@ import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.meta.BlockStat;
import io.anuke.mindustry.world.meta.StatUnit;
public abstract class PowerTurret extends CooledTurret{
public class PowerTurret extends CooledTurret{
protected @NonNull BulletType shootType;
protected float powerUse = 1f;

View File

@@ -126,7 +126,8 @@ public class Conduit extends LiquidBlock implements Autotiler{
@Override
public boolean acceptLiquid(Tile tile, Tile source, Liquid liquid, float amount){
tile.entity.noSleep();
return tile.entity.liquids.get(liquid) + amount < liquidCapacity && (tile.entity.liquids.current() == liquid || tile.entity.liquids.get(tile.entity.liquids.current()) < 0.2f) && ((2 + source.relativeTo(tile.x, tile.y)) % 4 != tile.rotation());
return tile.entity.liquids.get(liquid) + amount < liquidCapacity && (tile.entity.liquids.current() == liquid || tile.entity.liquids.get(tile.entity.liquids.current()) < 0.2f)
&& ((source.absoluteRelativeTo(tile.x, tile.y) + 2) % 4 != tile.rotation());
}
@Override

View File

@@ -1,18 +1,15 @@
package io.anuke.mindustry.world.blocks.distribution;
import io.anuke.arc.Core;
import io.anuke.arc.graphics.g2d.Draw;
import io.anuke.arc.graphics.g2d.TextureRegion;
import io.anuke.mindustry.type.Liquid;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.LiquidBlock;
import io.anuke.mindustry.world.meta.BlockStat;
import io.anuke.arc.*;
import io.anuke.arc.graphics.g2d.*;
import io.anuke.mindustry.world.*;
import io.anuke.mindustry.world.blocks.*;
import io.anuke.mindustry.world.meta.*;
public class LiquidJunction extends LiquidBlock{
public LiquidJunction(String name){
super(name);
hasLiquids = true;
}
@Override
@@ -38,23 +35,10 @@ public class LiquidJunction extends LiquidBlock{
}
@Override
public void handleLiquid(Tile tile, Tile source, Liquid liquid, float amount){
public Tile getLiquidDestination(Tile tile, Tile source){
int dir = source.relativeTo(tile.x, tile.y);
dir = (dir + 4) % 4;
Tile to = tile.getNearby(dir).link();
if(to.block().hasLiquids && to.block().acceptLiquid(to, tile, liquid, amount)){
to.block().handleLiquid(to, tile, liquid, amount);
}
}
@Override
public boolean acceptLiquid(Tile dest, Tile source, Liquid liquid, float amount){
int dir = source.relativeTo(dest.x, dest.y);
dir = (dir + 4) % 4;
Tile to = dest.getNearby(dir);
if(to == null) return false;
to = to.link();
return to != null && to.entity != null && to.block().hasLiquids && to.block().acceptLiquid(to, dest, liquid, amount);
Tile next = tile.getNearby(dir).link();
return next.block().getLiquidDestination(next, tile);
}
}

View File

@@ -64,6 +64,11 @@ public class Sorter extends Block{
Draw.color();
}
@Override
public int minimapColor(Tile tile){
return tile.<SorterEntity>entity().sortItem == null ? 0 : tile.<SorterEntity>entity().sortItem.color.rgba();
}
@Override
public boolean acceptItem(Item item, Tile tile, Tile source){
Tile to = getTileTarget(item, tile, source, false);

View File

@@ -87,7 +87,7 @@ public class ItemLiquidGenerator extends PowerGenerator{
}
@Override
public boolean shouldConsume(Tile tile){
public boolean productionValid(Tile tile){
ItemLiquidGeneratorEntity entity = tile.entity();
return entity.generateTime > 0;
}

View File

@@ -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);
}
}

View File

@@ -8,6 +8,7 @@ import io.anuke.arc.graphics.g2d.*;
import io.anuke.arc.math.*;
import io.anuke.arc.math.geom.*;
import io.anuke.arc.util.*;
import io.anuke.arc.util.ArcAnnotate.*;
import io.anuke.mindustry.entities.type.*;
import io.anuke.mindustry.graphics.*;
import io.anuke.mindustry.ui.*;
@@ -302,6 +303,11 @@ public class PowerNode extends PowerBlock{
return overlaps(src.drawx(), src.drawy(), other, range);
}
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);
}
protected void drawLaser(Tile tile, Tile target){
int opacityPercentage = Core.settings.getInt("lasersopacity");
if(opacityPercentage == 0) return;

View File

@@ -129,7 +129,7 @@ public class Drill extends Block{
}
@Override
public boolean canProduce(Tile tile){
public boolean shouldConsume(Tile tile){
return tile.entity.items.total() < itemCapacity;
}

View File

@@ -43,7 +43,7 @@ public class Fracker extends SolidPump{
public void drawCracks(Tile tile){}
@Override
public boolean canProduce(Tile tile){
public boolean shouldConsume(Tile tile){
return tile.entity.liquids.get(result) < liquidCapacity - 0.01f;
}

View File

@@ -135,7 +135,7 @@ public class GenericCrafter extends Block{
@Override
public boolean canProduce(Tile tile){
public boolean shouldConsume(Tile tile){
if(outputItem != null && tile.entity.items.get(outputItem.item) >= itemCapacity){
return false;
}

View File

@@ -2,14 +2,19 @@ package io.anuke.mindustry.world.blocks.production;
import io.anuke.arc.Core;
import io.anuke.arc.collection.Array;
import io.anuke.arc.graphics.Color;
import io.anuke.arc.graphics.g2d.Draw;
import io.anuke.arc.graphics.g2d.TextureRegion;
import io.anuke.mindustry.graphics.Layer;
import io.anuke.mindustry.type.Liquid;
import io.anuke.mindustry.ui.Cicon;
import io.anuke.mindustry.world.Tile;
import io.anuke.mindustry.world.blocks.LiquidBlock;
import io.anuke.mindustry.world.meta.*;
import static io.anuke.mindustry.Vars.tilesize;
import static io.anuke.mindustry.Vars.world;
public class Pump extends LiquidBlock{
protected final Array<Tile> drawTiles = new Array<>();
protected final Array<Tile> updateTiles = new Array<>();
@@ -49,6 +54,31 @@ public class Pump extends LiquidBlock{
Draw.color();
}
@Override
public void drawPlace(int x, int y, int rotation, boolean valid) {
Tile tile = world.tile(x, y);
if(tile == null) return;
float tiles = 0f;
Liquid liquidDrop = null;
for(Tile other : tile.getLinkedTilesAs(this, tempTiles)){
if(isValid(other)){
liquidDrop = other.floor().liquidDrop;
tiles++;
}
}
if(liquidDrop != null){
float width = drawPlaceText(Core.bundle.formatFloat("bar.pumpspeed", tiles * pumpAmount / size / size * 60f, 0), x, y, valid);
float dx = x * tilesize + offset() - width/2f - 4f, dy = y * tilesize + offset() + size * tilesize / 2f + 5;
Draw.mixcol(Color.darkGray, 1f);
Draw.rect(liquidDrop.icon(Cicon.small), dx, dy - 1);
Draw.reset();
Draw.rect(liquidDrop.icon(Cicon.small), dx, dy);
}
}
@Override
public TextureRegion[] generateIcons(){
return new TextureRegion[]{Core.atlas.find(name)};

View File

@@ -61,7 +61,7 @@ public class Separator extends Block{
}
@Override
public boolean canProduce(Tile tile){
public boolean shouldConsume(Tile tile){
return tile.entity.items.total() < itemCapacity;
}

View File

@@ -44,11 +44,6 @@ public class MechPad extends Block{
stats.add(BlockStat.productionTime, buildTime / 60f, StatUnit.seconds);
}
@Override
public boolean shouldConsume(Tile tile){
return false;
}
@Remote(targets = Loc.both, called = Loc.server)
public static void onMechFactoryTap(Player player, Tile tile){
if(player == null || !(tile.block() instanceof MechPad) || !checkValidTap(tile, player)) return;

View File

@@ -186,16 +186,11 @@ public class UnitFactory extends Block{
}
@Override
public boolean canProduce(Tile tile){
public boolean shouldConsume(Tile tile){
UnitFactoryEntity entity = tile.entity();
return entity.spawned < maxSpawn;
}
@Override
public boolean shouldConsume(Tile tile){
return canProduce(tile);
}
public static class UnitFactoryEntity extends TileEntity{
float buildTime;
float time;

View File

@@ -1,5 +1,6 @@
package io.anuke.mindustry.world.consumers;
import io.anuke.arc.math.Mathf;
import io.anuke.arc.scene.ui.layout.Table;
import io.anuke.mindustry.entities.type.TileEntity;
import io.anuke.mindustry.world.Tile;
@@ -64,15 +65,20 @@ public class ConsumePower extends Consume{
/**
* Retrieves the amount of power which is requested for the given block and entity.
* @param block The block which needs power.
* @param entity The entity which contains the power module.
* @return The amount of power which is requested per tick.
*/
public float requestedPower(TileEntity entity){
if(entity.tile.entity == null) return 0f;
if(buffered){
return (1f-entity.power.satisfaction)*capacity;
}else{
return usage;
try{
return usage * Mathf.num(entity.block.shouldConsume(entity.tile));
}catch(Exception e){
//HACK an error will only happen with a bar that is checking its requested power, and the entity is null/a different class
return 0;
}
}
}

View File

@@ -23,7 +23,7 @@ public class ConsumeModule extends BlockModule{
boolean prevValid = valid();
valid = true;
optionalValid = true;
boolean docons = entity.block.shouldConsume(entity.tile);
boolean docons = entity.block.shouldConsume(entity.tile) && entity.block.productionValid(entity.tile);
for(Consume cons : entity.block.consumes.all()){
if(cons.isOptional()) continue;
@@ -51,7 +51,7 @@ public class ConsumeModule extends BlockModule{
}
public boolean valid(){
return valid && entity.block.canProduce(entity.tile);
return valid && entity.block.shouldConsume(entity.tile);
}
public boolean optionalValid(){