diff --git a/core/assets/bundles/bundle.properties b/core/assets/bundles/bundle.properties index 08f271d82d..22a9289eed 100644 --- a/core/assets/bundles/bundle.properties +++ b/core/assets/bundles/bundle.properties @@ -1225,6 +1225,7 @@ setting.bridgeopacity.name = Bridge Opacity setting.playerchat.name = Display Player Bubble Chat setting.showweather.name = Show Weather Graphics setting.hidedisplays.name = Hide Logic Displays +setting.dynamicjumpheights.name = Dynamic Jump Heights setting.macnotch.name = Adapt interface to display notch setting.macnotch.description = Restart required to apply changes steam.friendsonly = Friends Only diff --git a/core/src/mindustry/logic/LCanvas.java b/core/src/mindustry/logic/LCanvas.java index 8924f68d4b..417931e792 100644 --- a/core/src/mindustry/logic/LCanvas.java +++ b/core/src/mindustry/logic/LCanvas.java @@ -21,8 +21,10 @@ import mindustry.ui.*; public class LCanvas extends Table{ public static final int maxJumpsDrawn = 100; + private static final int invalidJump = Integer.MAX_VALUE; // terrible hack //ew static variables static LCanvas canvas; + private static boolean dynamicJumpHeights = false; public DragLayout statements; public ScrollPane pane; @@ -108,6 +110,8 @@ public class LCanvas extends Table{ statements = new DragLayout(); jumps = statements.jumps; + dynamicJumpHeights = Core.settings.getBool("dynamicjumpheights", false); + pane = pane(t -> { t.center(); t.add(statements).pad(2f).center().width(targetWidth); @@ -196,6 +200,7 @@ public class LCanvas extends Table{ int insertPosition = 0; boolean invalidated; public Group jumps = new WidgetGroup(); + private Seq processedJumps = new Seq(); { setTransform(true); @@ -251,13 +256,73 @@ public class LCanvas extends Table{ } } - if(parent != null) parent.invalidateHierarchy(); + if(dynamicJumpHeights) setJumpHeights(); + + if(parent != null) parent.invalidateHierarchy();//don't invalid self if(parent != null && parent instanceof Table){ setCullingArea(parent.getCullingArea()); } } + private void setJumpHeights(){ + SnapshotSeq jumpsChildren = jumps.getChildren(); + processedJumps.clear(); + jumpsChildren.each(e -> { + if(e instanceof JumpCurve e2){ + e2.prepareHeight(); + if(e2.jumpUIBegin != invalidJump){ + processedJumps.add(e2); + } + } + }); + processedJumps.sort((a,b) -> a.jumpUIBegin - b.jumpUIBegin); + + Seq occupiers = new Seq(); + Bits occupied = new Bits(); + for(int i = 0; i < processedJumps.size; i++){ + JumpCurve cur = processedJumps.get(i); + occupiers.retainAll(e -> { + if(e.jumpUIEnd > cur.jumpUIBegin) return true; + occupied.clear(e.predHeight); + return false; + }); + int h = getJumpHeight(i, occupiers, occupied); + occupiers.add(cur); + occupied.set(h); + } + } + + private int getJumpHeight(int index, Seq occupiers, Bits occupied){ + JumpCurve jmp = processedJumps.get(index); + if(jmp.markedDone) return jmp.predHeight; + + // TODO: optimize for LESS cloning + Seq tmpOccupiers = new Seq(occupiers); + Bits tmpOccupied = new Bits(); + tmpOccupied.set(occupied); + + int max = -1; + for(int i = index + 1; i < processedJumps.size; i++){ + JumpCurve cur = processedJumps.get(i); + if(cur.jumpUIEnd > jmp.jumpUIEnd) continue; + tmpOccupiers.retainAll(e -> { + if(e.jumpUIEnd > cur.jumpUIBegin) return true; + tmpOccupied.clear(e.predHeight); + return false; + }); + int h = getJumpHeight(i, tmpOccupiers, tmpOccupied); + tmpOccupiers.add(cur); + tmpOccupied.set(h); + max = Math.max(max, h); + } + + jmp.predHeight = occupied.nextClearBit(max + 1); + jmp.markedDone = true; + + return jmp.predHeight; + } + @Override public float getPrefWidth(){ return prefWidth; @@ -452,12 +517,14 @@ public class LCanvas extends Table{ ClickListener listener; public JumpCurve curve; + public StatementElem elem; - public JumpButton(Prov getter, Cons setter){ + public JumpButton(Prov getter, Cons setter, StatementElem elem){ super(Tex.logicNode, new ImageButtonStyle(){{ imageUpColor = Color.white; }}); + this.elem = elem; to = getter; addListener(listener = new ClickListener()); @@ -518,6 +585,11 @@ public class LCanvas extends Table{ public static class JumpCurve extends Element{ public JumpButton button; + // for jump prediction; see DragLayout + public int predHeight = 0; + public boolean markedDone = false; + public int jumpUIBegin = 0, jumpUIEnd = 0; + public JumpCurve(JumpButton button){ this.button = button; } @@ -575,7 +647,7 @@ public class LCanvas extends Table{ Lines.stroke(4f, button.color); Draw.alpha(parentAlpha); - float dist = 100f; + float dist = 100f + 100f * (float) predHeight; //square jumps if(false){ @@ -599,5 +671,20 @@ public class LCanvas extends Table{ x2, y2, Math.max(18, (int)(Mathf.dst(x, y, x2, y2) / 6))); } + + public void prepareHeight(){ + if(this.button.to.get() == null){ + this.markedDone = true; + this.predHeight = 0; + this.jumpUIBegin = this.jumpUIEnd = invalidJump; + } else { + this.markedDone = false; + int i = this.button.elem.index; + int j = this.button.to.get().index; + this.jumpUIBegin = Math.min(i,j); + this.jumpUIEnd = Math.max(i,j); + // height will be recalculated later + } + } } } diff --git a/core/src/mindustry/logic/LStatements.java b/core/src/mindustry/logic/LStatements.java index 9d8faa880a..1c03625234 100644 --- a/core/src/mindustry/logic/LStatements.java +++ b/core/src/mindustry/logic/LStatements.java @@ -870,7 +870,7 @@ public class LStatements{ table.table(this::rebuild); table.add().growX(); - table.add(new JumpButton(() -> dest, s -> dest = s)).size(30).right().padLeft(-8); + table.add(new JumpButton(() -> dest, s -> dest = s, this.elem)).size(30).right().padLeft(-8); String name = name(); diff --git a/core/src/mindustry/ui/dialogs/SettingsMenuDialog.java b/core/src/mindustry/ui/dialogs/SettingsMenuDialog.java index 01f7c05a53..04d2d93e61 100644 --- a/core/src/mindustry/ui/dialogs/SettingsMenuDialog.java +++ b/core/src/mindustry/ui/dialogs/SettingsMenuDialog.java @@ -502,6 +502,8 @@ public class SettingsMenuDialog extends BaseDialog{ if(!mobile){ Core.settings.put("swapdiagonal", false); } + + graphics.checkPref("dynamicjumpheights", true); } public void exportData(Fi file) throws IOException{