From 909dff76084187a8170f3a81fd2d08702c37eee9 Mon Sep 17 00:00:00 2001 From: Anuken Date: Sun, 22 Nov 2020 11:59:53 -0500 Subject: [PATCH] Bugfixes --- core/assets/baseparts/1605281306347.msch | Bin 730 -> 771 bytes core/assets/baseparts/759638168080351252.msch | Bin 744 -> 0 bytes core/src/mindustry/ai/BaseAI.java | 95 +++++++++++++++++- .../mindustry/graphics/OverlayRenderer.java | 2 +- core/src/mindustry/input/DesktopInput.java | 2 +- core/src/mindustry/input/InputHandler.java | 4 + .../maps/generators/BaseGenerator.java | 10 ++ .../mindustry/ui/fragments/HintsFragment.java | 2 +- .../ui/fragments/PlacementFragment.java | 2 +- .../world/blocks/campaign/Accelerator.java | 2 + .../blocks/distribution/StackConveyor.java | 10 +- .../world/blocks/units/UnitFactory.java | 5 +- 12 files changed, 121 insertions(+), 13 deletions(-) delete mode 100644 core/assets/baseparts/759638168080351252.msch diff --git a/core/assets/baseparts/1605281306347.msch b/core/assets/baseparts/1605281306347.msch index a200060661491cb0574d378cfec766b30b48fb3f..1ef95d9ea57ab6bea274b6bd5cbf65a4722827ee 100644 GIT binary patch literal 771 zcmc~TPR?MgnBzO;b>1xpf!6le+Y&qy#p)}C0>A3>KW&=5%Sd7^Z|3|Z@4asAc>ZQZ z*3<*(=g*xvC;C%GzK7-cpAe5fk3OBg?tRyzNM}~FwtjBpeAl!|rlnJN|5ddYzbfai z-}+^?cVR}XqTm<3P{o(iZ^?H3J$m(iL4dV|=Im=z=dZ6hd27?z^H0BSvA^;>`XlqA zhfC{p@BE9A=bm|e`ytub%HQ`LD^9Nu)qa_M&uRUSd%NzORt}F>ocN^Wu@IYU^MuuV z8pUctrXIOo9Qxe-g->z$s@TFm<+)Lh4sI1N-TFCimbTEX?LBUjHtG6V>{JpL{HdAr zG2Nv~=%K8HK$zQ)2liJt&rI@UStYq5Z9zKY`4@*h`XwBrf33Q?d>P}iBwd5>WbM5I z9HJ8!t?v+JJ{nME;&DY!RD)lod-1zipYr$jj{Nd}zMlK21oPz98+HxVP6G@nwP>{UIPa*Uob%DXoF zzPq&nuI zi{}~gnU`(&^0qd;*s!IXrRMnOxu1LUnKQ5Kja;=@O6R}IyTGg6%U+e8GzkAPkFmac z*CoN|mmOlX5}iGO=Ckz2pv{ulQ=tJa8m<{z!~E7GZ4=J~Ko>EUtv<7S6_nw;CeZdX}ovEWSai)N)S`L2ITdd<9V z-ddhpt8L59c`@zJ&Q1Nbw9vhJ$F676YEtbAp|^Lw`rO;RX!Wj7L3hu!Cl~L$EpNcP z{%m(?yLa)XO&Ra5&5bGjZ|_i}pI@qedHSa2`G4>2ymVXm`kjP{e|lbWap!bTdA+Gs zJn72TCELC4PEr4H#;ZJUj_u#uWl;|gml|yC{hWA9ny=)=jNT`q>E~zce5j-JDOhC! zi@bwdi_szFiBif^FB4Q0+$2soJZGC@e8A_BK*Wk_jYOU!LIRyh3p_+;CTTE=KiQS1 zRd8;J$K!vE8xsF>`@i4bbyR}+`_dL>g~xo(lE$Y3)ViDumzVdc@bC-0<~TOxUCi;z zGkF|Dl9tSPd1p?bn?=|0peDr)j|`7*T6lWKX<-Hb;1u!i`F|I`{~d1lS9 zv;Tj1r@hSJ;VKz-A61ni)-%cr1dI=SZ~CYnW3Wu(gl&sm@DkbM3`zns<|#z4Kjjmw zJtK-^&*F^(Tdqt8>t8Q{Xb9LCq zlJHT3dA%TOXTXsa@BiL0>Qy*Bd&8MHofF3${yD6eFr(uW_qON{iv)HuRc};d6`hgX zDEWC)WnFHE1maU9DWaGe6`5ug%0~(=y#1 zPW-#E>QD6EchOmnk3)J}rJnO_yFBl9=J~f&ln?feg*O%r`gh sW&KdQ_xim1n{V1UH||9 diff --git a/core/assets/baseparts/759638168080351252.msch b/core/assets/baseparts/759638168080351252.msch deleted file mode 100644 index 7ebed705a81f83cd065d3553a5d7ddde66aad8cc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 744 zcmc~TPR?MgnBzMoJMXrEKuh?Q?rFK6+mx68z0UnZ$OGa zRY|{YGe%pboxjp{s-()lNlrPr?`~;WP2~%_TDvdKw|#RhZDf8OUw-%5&bxW$x3}$o zpY!eijH|~F7hli+*1rDk{GYFO${Jj%mH+iE&*Dqi9oyXYP>#EjFj-rR@@@)Q%Zv`Muymv=h*=wp^;l;OU}wr9u91C-A&zRD1FwplB4bIQu2 zGIIskIDenG)-Qf!j$!?=JC*|3``%87pCH=Gr`MR` zqnNfyaLF_iAH{?F18tOrRh|TSyu6$+=fH`DH!CF9n;eZvbxR#UnF+=R)0)nP%(k5Dq2MPpquB6y z$|ms{#fIKjmxbhd8G0Lft445!fnerE)4xGqq~=T%QGNW;e9FhJGR~!|BdqStco3e= zYx*ZiZr_9O)9aVXufFsmkM(wIj`*h7jAZeaquWBRc?V9jTJJ5R)!TM?$Cb<&u3bVU zsxP`Oh%^bGo3rtyc+S7n8uw~m^_tcr$zD4G&9(mW@@hUjcJIMgOR*Z+`x{H{T^3y4 z@%)AC{ykdj1Lmy>zjOQg$DWVINfp8QPL2xP55vXS4)d9wx$0;%|H0Jk6|Y!leE!k4 z!Y#hPEuP(5BzX-3mSCb2SRS15lHo7$ tmpTiles = new Seq<>(); private static int correct = 0, incorrect = 0; @@ -36,6 +40,13 @@ public class BaseAI{ TeamData data; Interval timer = new Interval(4); + IntSet path = new IntSet(); + IntSet calcPath = new IntSet(); + @Nullable Tile calcTile; + boolean calculating, startedCalculating; + int calcCount = 0; + int totalCalcs = 0; + public BaseAI(TeamData data){ this.data = data; } @@ -53,8 +64,76 @@ public class BaseAI{ } } + //refresh path + if(!calculating && (timer.get(timerRefreshPath, 3f * Time.toMinutes) || !startedCalculating) && data.hasCore()){ + calculating = true; + startedCalculating = true; + calcPath.clear(); + } + + //didn't find tile in time + if(calculating && calcCount >= world.width() * world.height()){ + calculating = false; + calcCount = 0; + calcPath.clear(); + totalCalcs ++; + } + + //calculate path for units so schematics are not placed on it + if(calculating){ + if(calcTile == null){ + Vars.spawner.eachGroundSpawn((x, y) -> calcTile = world.tile(x, y)); + if(calcTile == null){ + calculating = false; + } + }else{ + var field = pathfinder.getField(state.rules.waveTeam, Pathfinder.costGround, Pathfinder.fieldCore); + + int[][] weights = field.weights; + for(int i = 0; i < pathStep; i++){ + int minCost = Integer.MAX_VALUE; + int cx = calcTile.x, cy = calcTile.y; + boolean foundAny = false; + for(Point2 p : Geometry.d4){ + int nx = cx + p.x, ny = cy + p.y; + + Tile other = world.tile(nx, ny); + if(other != null && weights[nx][ny] < minCost && weights[nx][ny] != -1){ + minCost = weights[nx][ny]; + calcTile = other; + foundAny = true; + } + } + + //didn't find anything, break out of loop, this will trigger a clear later + if(!foundAny){ + calcCount = Integer.MAX_VALUE; + break; + } + + calcPath.add(calcTile.pos()); + + //found the end. + if(calcTile.build instanceof CoreBuild b && b.team == state.rules.defaultTeam){ + //clean up calculations and flush results + calculating = false; + calcCount = 0; + path.clear(); + path.addAll(calcPath); + calcPath.clear(); + calcTile = null; + totalCalcs ++; + + break; + } + + calcCount ++; + } + } + } + //only schedule when there's something to build. - if(data.blocks.isEmpty() && timer.get(timerStep, Mathf.lerp(20f, 4f, data.team.rules().aiTier))){ + if(totalCalcs > 0 && data.blocks.isEmpty() && timer.get(timerStep, Mathf.lerp(20f, 4f, data.team.rules().aiTier))){ if(!triedWalls){ tryWalls(); triedWalls = true; @@ -123,6 +202,13 @@ public class BaseAI{ if(!Build.validPlace(tile.block, data.team, realX, realY, tile.rotation)){ return false; } + Tile wtile = world.tile(realX, realY); + + //may intersect AI path + tmpTiles.clear(); + if(tile.block.solid && wtile != null && wtile.getLinkedTilesAs(tile.block, tmpTiles).contains(t -> path.contains(t.pos()))){ + return false; + } } //make sure at least X% of resource requirements are met @@ -191,7 +277,8 @@ public class BaseAI{ } } - if(any && Build.validPlace(wall, data.team, tile.x, tile.y, 0)){ + tmpTiles.clear(); + if(any && Build.validPlace(wall, data.team, tile.x, tile.y, 0) && !tile.getLinkedTilesAs(wall, tmpTiles).contains(t -> path.contains(t.pos()))){ data.blocks.add(new BlockPlan(tile.x, tile.y, (short)0, wall.id, null)); } } diff --git a/core/src/mindustry/graphics/OverlayRenderer.java b/core/src/mindustry/graphics/OverlayRenderer.java index 6723f81c66..6cc1a1a851 100644 --- a/core/src/mindustry/graphics/OverlayRenderer.java +++ b/core/src/mindustry/graphics/OverlayRenderer.java @@ -171,7 +171,7 @@ public class OverlayRenderer{ Draw.reset(); Building tile = world.buildWorld(v.x, v.y); - if(tile != null && tile.interactable(player.team()) && tile.acceptStack(player.unit().item(), player.unit().stack.amount, player.unit()) > 0 && player.within(tile, itemTransferRange)){ + if(input.canDropItem() && tile != null && tile.interactable(player.team()) && tile.acceptStack(player.unit().item(), player.unit().stack.amount, player.unit()) > 0 && player.within(tile, itemTransferRange)){ Lines.stroke(3f, Pal.gray); Lines.square(tile.x, tile.y, tile.block.size * tilesize / 2f + 3 + Mathf.absin(Time.time(), 5f, 1f)); Lines.stroke(1f, Pal.place); diff --git a/core/src/mindustry/input/DesktopInput.java b/core/src/mindustry/input/DesktopInput.java index 7771b30fed..b106abf168 100644 --- a/core/src/mindustry/input/DesktopInput.java +++ b/core/src/mindustry/input/DesktopInput.java @@ -484,7 +484,7 @@ public class DesktopInput extends InputHandler{ deleting = true; }else if(selected != null){ //only begin shooting if there's no cursor event - if(!tileTapped(selected.build) && !tryTapPlayer(Core.input.mouseWorld().x, Core.input.mouseWorld().y) && !player.unit().activelyBuilding() && !droppingItem && + if(!tryTapPlayer(Core.input.mouseWorld().x, Core.input.mouseWorld().y) && !tileTapped(selected.build) && !player.unit().activelyBuilding() && !droppingItem && !tryBeginMine(selected) && player.unit().mineTile == null && !Core.scene.hasKeyboard()){ player.shooting = shouldShoot; } diff --git a/core/src/mindustry/input/InputHandler.java b/core/src/mindustry/input/InputHandler.java index ed219c026e..c2ab8423c9 100644 --- a/core/src/mindustry/input/InputHandler.java +++ b/core/src/mindustry/input/InputHandler.java @@ -1056,6 +1056,10 @@ public abstract class InputHandler implements InputProcessor, GestureListener{ return droppingItem; } + public boolean canDropItem(){ + return droppingItem && !canTapPlayer(Core.input.mouseWorldX(), Core.input.mouseWorldY()); + } + public void tryDropItems(@Nullable Building tile, float x, float y){ if(!droppingItem || player.unit().stack.amount <= 0 || canTapPlayer(x, y) || state.isPaused() ){ droppingItem = false; diff --git a/core/src/mindustry/maps/generators/BaseGenerator.java b/core/src/mindustry/maps/generators/BaseGenerator.java index 5a1a72ad5e..8a5bf215ab 100644 --- a/core/src/mindustry/maps/generators/BaseGenerator.java +++ b/core/src/mindustry/maps/generators/BaseGenerator.java @@ -5,6 +5,7 @@ import arc.math.*; import arc.math.geom.*; import arc.struct.*; import arc.util.*; +import mindustry.ai.*; import mindustry.ai.BaseRegistry.*; import mindustry.content.*; import mindustry.game.*; @@ -146,6 +147,15 @@ public class BaseGenerator{ } }); } + + //clear path for ground units + for(Tile tile : cores){ + Astar.pathfind(tile, spawn, t -> t.team() == state.rules.waveTeam && !t.within(tile, 25f * 8) ? 100000 : t.floor().hasSurface() ? 1 : 10, t -> !t.block().isStatic()).each(t -> { + if(t.team() == state.rules.waveTeam && !t.within(tile, 25f * 8)){ + t.setBlock(Blocks.air); + } + }); + } } public void postGenerate(){ diff --git a/core/src/mindustry/ui/fragments/HintsFragment.java b/core/src/mindustry/ui/fragments/HintsFragment.java index eb7d8ca854..1bc8ad6f1e 100644 --- a/core/src/mindustry/ui/fragments/HintsFragment.java +++ b/core/src/mindustry/ui/fragments/HintsFragment.java @@ -154,7 +154,7 @@ public class HintsFragment extends Fragment{ respawn(visibleMobile, () -> !player.dead() && !player.unit().spawnedByCore, () -> !player.dead() && player.unit().spawnedByCore), launch(() -> isTutorial.get() && state.rules.sector.isCaptured(), () -> ui.planet.isShown()), schematicSelect(visibleDesktop, () -> ui.hints.placedBlocks.contains(Blocks.router), () -> Core.input.keyRelease(Binding.schematic_select) || Core.input.keyTap(Binding.pick)), - conveyorPathfind(() -> control.input.block == Blocks.titaniumConveyor, () -> Core.input.keyTap(Binding.diagonal_placement) || (mobile && Core.settings.getBool("swapdiagonal"))), + conveyorPathfind(() -> control.input.block == Blocks.titaniumConveyor, () -> Core.input.keyRelease(Binding.diagonal_placement) || (mobile && Core.settings.getBool("swapdiagonal"))), boost(visibleDesktop, () -> !player.dead() && player.unit().type.canBoost, () -> Core.input.keyDown(Binding.boost)), command(() -> state.rules.defaultTeam.data().units.size > 3 && !net.active(), () -> player.unit().isCommanding()), payloadPickup(() -> !player.unit().dead && player.unit() instanceof Payloadc p && p.payloads().isEmpty(), () -> player.unit() instanceof Payloadc p && p.payloads().any()), diff --git a/core/src/mindustry/ui/fragments/PlacementFragment.java b/core/src/mindustry/ui/fragments/PlacementFragment.java index 9115b16785..a42e1d6aa5 100644 --- a/core/src/mindustry/ui/fragments/PlacementFragment.java +++ b/core/src/mindustry/ui/fragments/PlacementFragment.java @@ -97,7 +97,7 @@ public class PlacementFragment extends Fragment{ boolean gridUpdate(InputHandler input){ scrollPositions.put(currentCategory, blockPane.getScrollY()); - if(Core.input.keyDown(Binding.pick) && player.isBuilder()){ //mouse eyedropper select + if(Core.input.keyTap(Binding.pick) && player.isBuilder()){ //mouse eyedropper select Building tile = world.buildWorld(Core.input.mouseWorld().x, Core.input.mouseWorld().y); Block tryRecipe = tile == null ? null : tile.block instanceof ConstructBlock ? ((ConstructBuild)tile).cblock : tile.block; Object tryConfig = tile == null ? null : tile.config(); diff --git a/core/src/mindustry/world/blocks/campaign/Accelerator.java b/core/src/mindustry/world/blocks/campaign/Accelerator.java index 419186fe56..9dd9040f8f 100644 --- a/core/src/mindustry/world/blocks/campaign/Accelerator.java +++ b/core/src/mindustry/world/blocks/campaign/Accelerator.java @@ -32,8 +32,10 @@ public class Accelerator extends Block{ @Override public void init(){ + itemCapacity = 0; for(ItemStack stack : launching.requirements){ capacities[stack.item.id] = stack.amount; + itemCapacity += stack.amount; } consumes.items(launching.requirements); super.init(); diff --git a/core/src/mindustry/world/blocks/distribution/StackConveyor.java b/core/src/mindustry/world/blocks/distribution/StackConveyor.java index 06d6f12068..b35f1630fb 100644 --- a/core/src/mindustry/world/blocks/distribution/StackConveyor.java +++ b/core/src/mindustry/world/blocks/distribution/StackConveyor.java @@ -106,6 +106,8 @@ public class StackConveyor extends Block implements Autotiler{ public float cooldown; public Item lastItem; + boolean proxUpdating = false; + @Override public void draw(){ Draw.rect(regions[state], x, y, rotdeg()); @@ -168,15 +170,15 @@ public class StackConveyor extends Block implements Autotiler{ //update other conveyor state when this conveyor's state changes if(state != lastState){ + proxUpdating = true; for(Building near : proximity){ - if(near instanceof StackConveyorBuild){ + if(!(near instanceof StackConveyorBuild b && b.proxUpdating && b.state != stateUnload)){ near.onProximityUpdate(); - for(Building other : near.proximity){ - if(!(other instanceof StackConveyorBuild)) other.onProximityUpdate(); - } } } + proxUpdating = false; } + } @Override diff --git a/core/src/mindustry/world/blocks/units/UnitFactory.java b/core/src/mindustry/world/blocks/units/UnitFactory.java index 1a257d9565..6b2156e566 100644 --- a/core/src/mindustry/world/blocks/units/UnitFactory.java +++ b/core/src/mindustry/world/blocks/units/UnitFactory.java @@ -53,12 +53,15 @@ public class UnitFactory extends UnitBlock{ @Override public void init(){ capacities = new int[Vars.content.items().size]; + itemCapacity = 0; for(UnitPlan plan : plans){ for(ItemStack stack : plan.requirements){ capacities[stack.item.id] = Math.max(capacities[stack.item.id], stack.amount * 2); - itemCapacity = Math.max(itemCapacity, stack.amount * 2); } } + for(int i : capacities){ + itemCapacity += i; + } super.init(); }