Merge branch 'master' of https://github.com/Anuken/Mindustry into maps_phase_2
This commit is contained in:
@@ -155,7 +155,10 @@ public class ControlPathfinder{
|
||||
return lastTargetId ++;
|
||||
}
|
||||
|
||||
/** @return whether a path is ready */
|
||||
/**
|
||||
* @return whether a path is ready.
|
||||
* @param pathId a unique ID for this location query, which should change every time the 'destination' vector is modified.
|
||||
* */
|
||||
public boolean getPathPosition(Unit unit, int pathId, Vec2 destination, Vec2 out){
|
||||
//uninitialized
|
||||
if(threads == null || !world.tiles.in(World.toTile(destination.x), World.toTile(destination.y))) return false;
|
||||
|
||||
@@ -129,8 +129,6 @@ public class CommandAI extends AIController{
|
||||
attackTarget != null ? engageRange :
|
||||
0f, unit.isFlying() ? 40f : 100f, false, null, true);
|
||||
}
|
||||
|
||||
//calculateFlock().limit(unit.speed() * flockMult)
|
||||
}
|
||||
|
||||
//if stopAtTarget is set, stop trying to move to the target once it is reached - used for defending
|
||||
@@ -145,7 +143,6 @@ public class CommandAI extends AIController{
|
||||
}
|
||||
|
||||
if(attackTarget == null){
|
||||
//TODO overshoot.
|
||||
if(unit.within(targetPos, Math.max(5f, unit.hitSize / 2f))){
|
||||
targetPos = null;
|
||||
}else if(local.size > 1){
|
||||
|
||||
@@ -15,7 +15,7 @@ public class LogicAI extends AIController{
|
||||
|
||||
public LUnitControl control = LUnitControl.idle;
|
||||
public float moveX, moveY, moveRad;
|
||||
public float itemTimer, payTimer, controlTimer = logicControlTimeout, targetTimer;
|
||||
public float controlTimer = logicControlTimeout, targetTimer;
|
||||
@Nullable
|
||||
public Building controller;
|
||||
public BuildPlan plan = new BuildPlan();
|
||||
@@ -39,8 +39,6 @@ public class LogicAI extends AIController{
|
||||
|
||||
@Override
|
||||
public void updateMovement(){
|
||||
if(itemTimer >= 0) itemTimer -= Time.delta;
|
||||
if(payTimer >= 0) payTimer -= Time.delta;
|
||||
|
||||
if(targetTimer > 0f){
|
||||
targetTimer -= Time.delta;
|
||||
|
||||
@@ -2123,17 +2123,20 @@ public class Blocks{
|
||||
requirements(Category.liquid, with(Items.titanium, 10, Items.metaglass, 15));
|
||||
liquidCapacity = 700f;
|
||||
size = 2;
|
||||
solid = true;
|
||||
}};
|
||||
|
||||
liquidTank = new LiquidRouter("liquid-tank"){{
|
||||
requirements(Category.liquid, with(Items.titanium, 30, Items.metaglass, 40));
|
||||
size = 3;
|
||||
solid = true;
|
||||
liquidCapacity = 1800f;
|
||||
health = 500;
|
||||
}};
|
||||
|
||||
liquidJunction = new LiquidJunction("liquid-junction"){{
|
||||
requirements(Category.liquid, with(Items.graphite, 4, Items.metaglass, 8));
|
||||
solid = false;
|
||||
}};
|
||||
|
||||
bridgeConduit = new LiquidBridge("bridge-conduit"){{
|
||||
@@ -2157,10 +2160,8 @@ public class Blocks{
|
||||
|
||||
//reinforced stuff
|
||||
|
||||
//TODO different name
|
||||
reinforcedPump = new Pump("reinforced-pump"){{
|
||||
requirements(Category.liquid, with(Items.beryllium, 40, Items.tungsten, 30, Items.silicon, 20));
|
||||
//TODO CUSTOM DRAW ANIMATION - pistons - repurpose DrawBlock?
|
||||
consumeLiquid(Liquids.hydrogen, 1.5f / 60f);
|
||||
|
||||
pumpAmount = 80f / 60f / 4f;
|
||||
@@ -5652,7 +5653,7 @@ public class Blocks{
|
||||
}};
|
||||
|
||||
interplanetaryAccelerator = new Accelerator("interplanetary-accelerator"){{
|
||||
requirements(Category.effect, BuildVisibility.hidden, with(Items.copper, 16000, Items.silicon, 11000, Items.thorium, 13000, Items.titanium, 12000, Items.surgeAlloy, 6000, Items.phaseFabric, 5000));
|
||||
requirements(Category.effect, BuildVisibility.campaignOnly, with(Items.copper, 16000, Items.silicon, 11000, Items.thorium, 13000, Items.titanium, 12000, Items.surgeAlloy, 6000, Items.phaseFabric, 5000));
|
||||
researchCostMultiplier = 0.1f;
|
||||
size = 7;
|
||||
hasPower = true;
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
package mindustry.editor;
|
||||
|
||||
import arc.*;
|
||||
import arc.graphics.*;
|
||||
import arc.graphics.g2d.*;
|
||||
import arc.input.*;
|
||||
import arc.math.*;
|
||||
import arc.math.geom.*;
|
||||
import arc.scene.event.*;
|
||||
import arc.scene.ui.*;
|
||||
import arc.scene.ui.ImageButton.*;
|
||||
import arc.scene.ui.layout.*;
|
||||
import arc.struct.*;
|
||||
import arc.util.*;
|
||||
@@ -28,7 +26,7 @@ public class MapObjectivesCanvas extends WidgetGroup{
|
||||
objWidth = 5, objHeight = 2,
|
||||
bounds = 100;
|
||||
|
||||
public static final float unitSize = 48f;
|
||||
public final float unitSize = Scl.scl(48f);
|
||||
|
||||
public Seq<MapObjective> objectives = new Seq<>();
|
||||
public ObjectiveTilemap tilemap;
|
||||
@@ -391,9 +389,9 @@ public class MapObjectivesCanvas extends WidgetGroup{
|
||||
setTransform(false);
|
||||
setClip(false);
|
||||
|
||||
add(conParent = new Connector(true)).size(unitSize, unitSize * 2);
|
||||
add(conParent = new Connector(true)).size(unitSize / Scl.scl(1f), unitSize * 2 / Scl.scl(1f));
|
||||
table(Tex.whiteui, t -> {
|
||||
float pad = (unitSize - 32f) / 2f - 4f;
|
||||
float pad = (unitSize / Scl.scl(1f) - 32f) / 2f - 4f;
|
||||
t.margin(pad);
|
||||
t.touchable(() -> Touchable.enabled);
|
||||
t.setColor(Pal.gray);
|
||||
@@ -425,8 +423,8 @@ public class MapObjectivesCanvas extends WidgetGroup{
|
||||
});
|
||||
b.button(Icon.trashSmall, () -> removeTile(this));
|
||||
}).left().grow();
|
||||
}).growX().height(unitSize * 2).get().addCaptureListener(mover = new Mover());
|
||||
add(conChildren = new Connector(false)).size(unitSize, unitSize * 2);
|
||||
}).growX().height(unitSize / Scl.scl(1f) * 2).get().addCaptureListener(mover = new Mover());
|
||||
add(conChildren = new Connector(false)).size(unitSize / Scl.scl(1f), unitSize / Scl.scl(1f) * 2);
|
||||
|
||||
setSize(getPrefWidth(), getPrefHeight());
|
||||
pos(x, y);
|
||||
|
||||
@@ -427,12 +427,11 @@ public class MapObjectivesDialog extends BaseDialog{
|
||||
stack(
|
||||
canvas = new MapObjectivesCanvas(),
|
||||
new Table(){{
|
||||
buttons.defaults().size(170f, 64f).pad(2f);
|
||||
buttons.defaults().size(160f, 64f).pad(2f);
|
||||
buttons.button("@back", Icon.left, MapObjectivesDialog.this::hide);
|
||||
buttons.button("@add", Icon.add, () -> getProvider(MapObjective.class).get(new TypeInfo(MapObjective.class), canvas::query));
|
||||
|
||||
if(mobile){
|
||||
buttons.row();
|
||||
buttons.button("@cancel", Icon.cancel, canvas::stopQuery).disabled(b -> !canvas.isQuerying());
|
||||
buttons.button("@ok", Icon.ok, canvas::placeQuery).disabled(b -> !canvas.isQuerying());
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ public class FlakBulletType extends BasicBulletType{
|
||||
if(b.time >= flakDelay && b.fdata >= 0 && b.timer(2, flakInterval)){
|
||||
Units.nearbyEnemies(b.team, Tmp.r1.setSize(explodeRange * 2f).setCenter(b.x, b.y), unit -> {
|
||||
//fdata < 0 means it's primed to explode
|
||||
if(b.fdata < 0f || !unit.checkTarget(collidesAir, collidesGround)) return;
|
||||
if(b.fdata < 0f || !unit.checkTarget(collidesAir, collidesGround) || !unit.type.targetable) return;
|
||||
|
||||
if(unit.within(b, explodeRange + unit.hitSize/2f)){
|
||||
//mark as primed
|
||||
|
||||
@@ -1682,7 +1682,14 @@ abstract class BuildingComp implements Posc, Teamc, Healthc, Buildingc, Timerc,
|
||||
|
||||
/** Called after efficiency is updated but before consumers are updated. Use to apply your own multiplier. */
|
||||
public void updateEfficiencyMultiplier(){
|
||||
float scale = efficiencyScale();
|
||||
efficiency *= scale;
|
||||
optionalEfficiency *= scale;
|
||||
}
|
||||
|
||||
/** Calculate your own efficiency multiplier. By default, this is applied in updateEfficiencyMultiplier. */
|
||||
public float efficiencyScale(){
|
||||
return 1f;
|
||||
}
|
||||
|
||||
public void updateConsumption(){
|
||||
|
||||
@@ -57,6 +57,17 @@ public class LExecutor{
|
||||
public Team team = Team.derelict;
|
||||
public boolean privileged = false;
|
||||
|
||||
//yes, this is a minor memory leak, but it's probably not significant enough to matter
|
||||
protected IntFloatMap unitTimeouts = new IntFloatMap();
|
||||
|
||||
boolean timeoutDone(Unit unit, float delay){
|
||||
return Time.time >= unitTimeouts.get(unit.id) + delay;
|
||||
}
|
||||
|
||||
void updateTimeout(Unit unit){
|
||||
unitTimeouts.put(unit.id, Time.time);
|
||||
}
|
||||
|
||||
public boolean initialized(){
|
||||
return instructions.length > 0;
|
||||
}
|
||||
@@ -428,15 +439,15 @@ public class LExecutor{
|
||||
}
|
||||
}
|
||||
case payDrop -> {
|
||||
if(ai.payTimer > 0) return;
|
||||
if(!exec.timeoutDone(unit, LogicAI.transferDelay)) return;
|
||||
|
||||
if(unit instanceof Payloadc pay && pay.hasPayload()){
|
||||
Call.payloadDropped(unit, unit.x, unit.y);
|
||||
ai.payTimer = LogicAI.transferDelay;
|
||||
exec.updateTimeout(unit);
|
||||
}
|
||||
}
|
||||
case payTake -> {
|
||||
if(ai.payTimer > 0) return;
|
||||
if(!exec.timeoutDone(unit, LogicAI.transferDelay)) return;
|
||||
|
||||
if(unit instanceof Payloadc pay){
|
||||
//units
|
||||
@@ -460,7 +471,7 @@ public class LExecutor{
|
||||
}
|
||||
}
|
||||
}
|
||||
ai.payTimer = LogicAI.transferDelay;
|
||||
exec.updateTimeout(unit);
|
||||
}
|
||||
}
|
||||
case payEnter -> {
|
||||
@@ -508,7 +519,7 @@ public class LExecutor{
|
||||
}
|
||||
}
|
||||
case itemDrop -> {
|
||||
if(ai.itemTimer > 0) return;
|
||||
if(!exec.timeoutDone(unit, LogicAI.transferDelay)) return;
|
||||
|
||||
//clear item when dropping to @air
|
||||
if(exec.obj(p1) == Blocks.air){
|
||||
@@ -516,7 +527,7 @@ public class LExecutor{
|
||||
if(!net.client()){
|
||||
unit.clearItem();
|
||||
}
|
||||
ai.itemTimer = LogicAI.transferDelay;
|
||||
exec.updateTimeout(unit);
|
||||
}else{
|
||||
Building build = exec.building(p1);
|
||||
int dropped = Math.min(unit.stack.amount, exec.numi(p2));
|
||||
@@ -524,13 +535,13 @@ public class LExecutor{
|
||||
int accepted = build.acceptStack(unit.item(), dropped, unit);
|
||||
if(accepted > 0){
|
||||
Call.transferItemTo(unit, unit.item(), accepted, unit.x, unit.y, build);
|
||||
ai.itemTimer = LogicAI.transferDelay;
|
||||
exec.updateTimeout(unit);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
case itemTake -> {
|
||||
if(ai.itemTimer > 0) return;
|
||||
if(!exec.timeoutDone(unit, LogicAI.transferDelay)) return;
|
||||
|
||||
Building build = exec.building(p1);
|
||||
int amount = exec.numi(p3);
|
||||
@@ -541,7 +552,7 @@ public class LExecutor{
|
||||
|
||||
if(taken > 0){
|
||||
Call.takeItems(build, item, taken, unit);
|
||||
ai.itemTimer = LogicAI.transferDelay;
|
||||
exec.updateTimeout(unit);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1634,6 +1645,8 @@ public class LExecutor{
|
||||
|
||||
@Override
|
||||
public void run(LExecutor exec){
|
||||
if(net.client()) return;
|
||||
|
||||
float
|
||||
spawnX = World.unconv(exec.numf(x)),
|
||||
spawnY = World.unconv(exec.numf(y));
|
||||
|
||||
@@ -50,8 +50,7 @@ public class MedianFilter extends GenerateFilter{
|
||||
floors.sort();
|
||||
blocks.sort();
|
||||
|
||||
int index = Math.min((int)(floors.size * percentile), floors.size - 1);
|
||||
int floor = floors.get(index), block = blocks.get(index);
|
||||
int floor = floors.get(Math.min((int)(floors.size * percentile), floors.size - 1)), block = blocks.get(Math.min((int)(blocks.size * percentile), blocks.size - 1));
|
||||
|
||||
in.floor = content.block(floor);
|
||||
if(!content.block(block).synthetic() && !in.block.synthetic()) in.block = content.block(block);
|
||||
|
||||
@@ -158,7 +158,7 @@ public class ColorPicker extends BaseDialog{
|
||||
return false;
|
||||
}
|
||||
}).get();
|
||||
});
|
||||
}).grow();
|
||||
|
||||
buttons.clear();
|
||||
addCloseButton();
|
||||
|
||||
@@ -60,7 +60,7 @@ public class ModsDialog extends BaseDialog{
|
||||
searchtxt = res;
|
||||
rebuildBrowser();
|
||||
}).growX().get();
|
||||
table.button(Icon.list, Styles.clearNonei, 32f, () -> {
|
||||
table.button(Icon.list, Styles.emptyi, 32f, () -> {
|
||||
orderDate = !orderDate;
|
||||
rebuildBrowser();
|
||||
}).update(b -> b.getStyle().imageUp = (orderDate ? Icon.list : Icon.star)).size(40f).get()
|
||||
|
||||
@@ -110,6 +110,9 @@ public class Accelerator extends Block{
|
||||
|
||||
if(!state.isCampaign() || efficiency <= 0f) return;
|
||||
|
||||
ui.showInfo("This block doesn't work properly in the beta/alpha. It maybe removed, or reworked. Check back in a later update.");
|
||||
|
||||
if(false)
|
||||
ui.planet.showPlanetLaunch(state.rules.sector, sector -> {
|
||||
//TODO cutscene, etc...
|
||||
|
||||
|
||||
@@ -224,6 +224,16 @@ public class CanvasBlock extends Block{
|
||||
}).size(40f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onConfigureBuildTapped(Building other){
|
||||
if(this == other){
|
||||
deselect();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] config(){
|
||||
return data;
|
||||
|
||||
@@ -2,6 +2,7 @@ package mindustry.world.blocks.payloads;
|
||||
|
||||
import arc.graphics.g2d.*;
|
||||
import arc.math.*;
|
||||
import arc.math.geom.*;
|
||||
import arc.scene.ui.layout.*;
|
||||
import arc.util.*;
|
||||
import arc.util.io.*;
|
||||
@@ -33,6 +34,7 @@ public class PayloadSource extends PayloadBlock{
|
||||
noUpdateDisabled = true;
|
||||
clearOnDoubleTap = true;
|
||||
regionRotated1 = 1;
|
||||
commandable = true;
|
||||
|
||||
config(Block.class, (PayloadSourceBuild build, Block block) -> {
|
||||
if(canProduce(block) && build.block != block){
|
||||
@@ -83,8 +85,19 @@ public class PayloadSource extends PayloadBlock{
|
||||
public class PayloadSourceBuild extends PayloadBlockBuild<Payload>{
|
||||
public UnitType unit;
|
||||
public Block block;
|
||||
public @Nullable Vec2 commandPos;
|
||||
public float scl;
|
||||
|
||||
@Override
|
||||
public Vec2 getCommandPosition(){
|
||||
return commandPos;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCommand(Vec2 target){
|
||||
commandPos = target;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void buildConfiguration(Table table){
|
||||
ItemSelection.buildTable(PayloadSource.this, table,
|
||||
@@ -110,6 +123,11 @@ public class PayloadSource extends PayloadBlock{
|
||||
scl = 0f;
|
||||
if(unit != null){
|
||||
payload = new UnitPayload(unit.create(team));
|
||||
|
||||
Unit p = ((UnitPayload)payload).unit;
|
||||
if(commandPos != null && p.isCommandable()){
|
||||
p.command().commandPosition(commandPos);
|
||||
}
|
||||
}else if(block != null){
|
||||
payload = new BuildPayload(block, team);
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import mindustry.gen.*;
|
||||
import mindustry.graphics.*;
|
||||
import mindustry.input.*;
|
||||
import mindustry.logic.*;
|
||||
import mindustry.ui.*;
|
||||
import mindustry.world.*;
|
||||
import mindustry.world.meta.*;
|
||||
|
||||
@@ -86,12 +87,22 @@ public class LightBlock extends Block{
|
||||
|
||||
@Override
|
||||
public void buildConfiguration(Table table){
|
||||
table.button(Icon.pencil, () -> {
|
||||
table.button(Icon.pencil, Styles.cleari, () -> {
|
||||
ui.picker.show(Tmp.c1.set(color).a(0.5f), false, res -> configure(res.rgba()));
|
||||
deselect();
|
||||
}).size(40f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onConfigureBuildTapped(Building other){
|
||||
if(this == other){
|
||||
deselect();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawLight(){
|
||||
Drawf.light(x, y, lightRadius * Math.min(smoothTime, 2f), Tmp.c1.set(color), brightness * efficiency);
|
||||
|
||||
@@ -38,8 +38,8 @@ public class AttributeCrafter extends GenericCrafter{
|
||||
if(!displayEfficiency) return;
|
||||
|
||||
addBar("efficiency", (AttributeCrafterBuild entity) ->
|
||||
new Bar(() ->
|
||||
Core.bundle.format("bar.efficiency", (int)(entity.efficiencyScale() * 100 * displayEfficiencyScale)),
|
||||
new Bar(
|
||||
() -> Core.bundle.format("bar.efficiency", (int)(entity.efficiencyScale() * 100 * displayEfficiencyScale)),
|
||||
() -> Pal.lightOrange,
|
||||
entity::efficiencyScale));
|
||||
}
|
||||
|
||||
@@ -67,11 +67,6 @@ public class HeatCrafter extends GenericCrafter{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateEfficiencyMultiplier(){
|
||||
efficiency *= efficiencyScale();
|
||||
potentialEfficiency *= efficiencyScale();
|
||||
}
|
||||
|
||||
public float efficiencyScale(){
|
||||
float over = Math.max(heat - heatRequirement, 0f);
|
||||
return Math.min(Mathf.clamp(heat / heatRequirement) + over / heatRequirement * overheatScale, maxEfficiency);
|
||||
|
||||
@@ -298,6 +298,8 @@ public class UnitAssembler extends PayloadBlock{
|
||||
for(var module : modules){
|
||||
Drawf.selected(module, Pal.accent);
|
||||
}
|
||||
|
||||
Drawf.dashRect(Tmp.c1.set(Pal.accent).lerp(Pal.remove, invalidWarmup), getRect(Tmp.r1, x, y, rotation));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -320,7 +322,7 @@ public class UnitAssembler extends PayloadBlock{
|
||||
prev = mod.block;
|
||||
}
|
||||
|
||||
t.label(() -> "[accent] -> []" + unit().emoji() + " " + unit().name);
|
||||
t.label(() -> "[accent] -> []" + unit().emoji() + " " + unit().localizedName);
|
||||
}).pad(4).padLeft(0f).fillX().left();
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ public class ConsumeLiquid extends ConsumeLiquidBase{
|
||||
|
||||
@Override
|
||||
public float efficiency(Building build){
|
||||
float ed = build.edelta();
|
||||
float ed = build.edelta() * build.efficiencyScale();
|
||||
if(ed <= 0.00000001f) return 0f;
|
||||
//there can be more liquid than necessary, so cap at 1
|
||||
return Math.min(build.liquids.get(liquid) / (amount * ed), 1f);
|
||||
|
||||
Reference in New Issue
Block a user