From 95d92f84f58e436bfc4fc5b5d6354d7ea9fd5655 Mon Sep 17 00:00:00 2001 From: BlackDeluxeCat <65377021+BlackDeluxeCat@users.noreply.github.com> Date: Sat, 30 Dec 2023 15:15:47 +0800 Subject: [PATCH 01/57] minimap ui & 2 settings --- assets/bundles/bundle.properties | 2 + assets/bundles/bundle_zh_CN.properties | 2 + src/mi2u/ui/MinimapMindow.java | 54 +++++++++++++++++++------- 3 files changed, 43 insertions(+), 15 deletions(-) diff --git a/assets/bundles/bundle.properties b/assets/bundles/bundle.properties index a468d55..3b38d7c 100644 --- a/assets/bundles/bundle.properties +++ b/assets/bundles/bundle.properties @@ -148,6 +148,8 @@ settings.mindowMap.drawSpawn = Spawn Tile settings.mindowMap.drawFog = Fog settings.mindowMap.drawIndicator = Attack Indicator settings.mindowMap.drawObjective = Map Objective +settings.mindowMap.drawUnitColorDiff = Unit Color Difference +settings.mindowMap.drawUnitOutline = Unit Outline settings.mindowMap.size = Minimap Size(Def=140) settings.mindowMap.worldDataUpdate.tiles = Space-Scan World Tiles Update Per Tick diff --git a/assets/bundles/bundle_zh_CN.properties b/assets/bundles/bundle_zh_CN.properties index 05ba4f8..f83ddee 100644 --- a/assets/bundles/bundle_zh_CN.properties +++ b/assets/bundles/bundle_zh_CN.properties @@ -148,6 +148,8 @@ settings.mindowMap.drawSpawn = 显示刷怪点 settings.mindowMap.drawFog = 显示迷雾 settings.mindowMap.drawIndicator = 显示攻击警告 settings.mindowMap.drawObjective = 显示地图目标 +settings.mindowMap.drawUnitColorDiff = 单位图标色差 +settings.mindowMap.drawUnitOutline = 单位描边 settings.mindowMap.size = 小地图尺寸(原版=140) settings.mindowMap.worldDataUpdate.tiles = 天眼查世界数据每帧更新格数 diff --git a/src/mi2u/ui/MinimapMindow.java b/src/mi2u/ui/MinimapMindow.java index b25d4a1..c3c2aae 100644 --- a/src/mi2u/ui/MinimapMindow.java +++ b/src/mi2u/ui/MinimapMindow.java @@ -66,8 +66,10 @@ public MinimapMindow(){ m.drawFog = MI2USettings.getBool(mindowName + ".drawFog", true); m.drawIndicator = MI2USettings.getBool(mindowName + ".drawIndicator", true); m.drawObjective = MI2USettings.getBool(mindowName + ".drawObjective", true); + m.drawUnitColorDifference = MI2USettings.getInt(mindowName + ".drawUnitColorDiff", 90) / 100f; + m.drawUnitOutline = MI2USettings.getInt(mindowName + ".drawUnitOutline", 0) / 100f; - buttons.defaults().height(32f).minWidth(100f).pad(2f).fillX(); + buttons.defaults().height(32f).minWidth(100f).fillX(); if(MI2USettings.getEntry(mindowName + ".drawLabel") instanceof CheckEntry ce) buttons.add(ce.newTextButton("@settings.mindowMap.drawLabel")).row(); if(MI2USettings.getEntry(mindowName + ".drawSpawn") instanceof CheckEntry ce) buttons.add(ce.newTextButton("@settings.mindowMap.drawSpawn")).row(); if(MI2USettings.getEntry(mindowName + ".drawFog") instanceof CheckEntry ce) buttons.add(ce.newTextButton("@settings.mindowMap.drawFog")).row(); @@ -81,15 +83,6 @@ public MinimapMindow(){ }); titlePane.table(t -> { - t.add().growX();//let coords being right align - Cons l = tl -> { - tl.table(tt -> { - tt.defaults().width(1f).fontScale(0.8f); - tt.label(() -> Strings.fixed(World.conv(player.x), 1) + ", "+ Strings.fixed(World.conv(player.y), 1)).get().setAlignment(Align.right); - tt.row(); - tt.label(() -> Strings.fixed(World.conv(Core.input.mouseWorldX()), 1) + ", "+ Strings.fixed(World.conv(Core.input.mouseWorldY()), 1)).color(Color.coral).get().setAlignment(Align.right); - }).right(); - }; Cons
b = tb -> { tb.table(tt -> { tt.button(Iconc.logic + "", MI2UVars.textbtoggle, () -> { @@ -106,9 +99,31 @@ public MinimapMindow(){ }).fillX().growY().height(titleButtonSize); }; - l.get(t); - b.get(t); - }).growX(); + Cons
l = tl -> { + tl.table(tt -> { + tt.defaults().width(1f); + tt.add("").with(c -> { + c.update(() -> { + c.setText(Strings.fixed(World.conv(player.x), 1) + ", "+ Strings.fixed(World.conv(player.y), 1)); + c.setFontScale(titlePane.getWidth() > 110f ? 0.8f : 0.5f); + }); + c.setAlignment(Align.right); + }); + tt.row(); + tt.add("").color(Color.coral).with(c -> { + c.update(() -> { + c.setText(Strings.fixed(World.conv(Core.input.mouseWorldX()), 1) + ", "+ Strings.fixed(Core.input.mouseWorldY(), 1)); + c.setFontScale(titlePane.getWidth() > 110f ? 0.8f : 0.5f); + }); + c.setAlignment(Align.right); + }); + }).right(); + }; + t.add(new MCollapser(b, true).setCollapsed(true, () -> !hasMouse()).setDuration(0.2f).setDirection(true, false)); + + t.add().growX(); + t.table(l).right(); + }).right().growX(); } @Override @@ -128,6 +143,8 @@ public void initSettings(){ settings.add(new CheckEntry(mindowName + ".drawIndicator", "@settings.mindowMap.drawIndicator", true, b -> m.drawIndicator = b)); settings.add(new CheckEntry(mindowName + ".drawObjective", "@settings.mindowMap.drawObjective", true, b -> m.drawObjective = b)); settings.add(new FieldEntry(mindowName + ".size", "@settings.mindowMap.size", String.valueOf(140), TextField.TextFieldFilter.digitsOnly, s -> Strings.canParseInt(s) && Strings.parseInt(s) >= 100 && Strings.parseInt(s) <= 3200, s -> rebuild())); + settings.add(new FieldEntry(mindowName + ".drawUnitColorDiff", "@settings.mindowMap.drawUnitColorDiff", String.valueOf(10), TextField.TextFieldFilter.digitsOnly, s -> Strings.canParseInt(s) && Strings.parseInt(s) >= 1 && Strings.parseInt(s) <= 100, s -> m.drawUnitColorDifference = MI2USettings.getInt(mindowName + ".drawUnitColorDiff", 90) / 100f)); + settings.add(new FieldEntry(mindowName + ".drawUnitOutline", "@settings.mindowMap.drawUnitOutline", String.valueOf(0), TextField.TextFieldFilter.digitsOnly, s -> Strings.canParseInt(s) && Strings.parseInt(s) >= 1 && Strings.parseInt(s) <= 100, s -> m.drawUnitOutline = MI2USettings.getInt(mindowName + ".drawUnitOutline", 90) / 100f)); settings.add(new FieldEntry("worldDataUpdate.tiles", "@settings.mindowMap.worldDataUpdate.tiles", String.valueOf(50), TextField.TextFieldFilter.digitsOnly, s -> Strings.canParseInt(s) && Strings.parseInt(s) >= 10 && Strings.parseInt(s) <= 10000, null)); } @@ -142,11 +159,14 @@ public boolean loadUISettingsRaw(){ public static class Minimap2 extends Table{ protected Element map; - public boolean drawLabel = false, drawSpawn = true, drawFog = true, drawIndicator = true, drawObjective = true; public Rect rect = new Rect(); private static final float baseSize = 16f; public float zoom = 4; + public boolean drawLabel = false, drawSpawn = true, drawFog = true, drawIndicator = true, drawObjective = true; + public float drawUnitOutline = 0f; + public float drawUnitColorDifference = 0.9f; + public Minimap2(float size){ float margin = 0f; this.touchable = Touchable.enabled; @@ -327,8 +347,12 @@ public void drawEntities(float x, float y, float w, float h, float scaling, bool float scale = Scl.scl(1f) / 2f * scaling * 32f; var region = unit.icon(); + if(drawUnitOutline > 0.01f){ + Draw.mixcol(Color.white, 1f); + Draw.rect(region, x + rx, y + ry, (1f + drawUnitOutline) * scale, (1f + drawUnitOutline) * scale * (float)region.height / region.width, unit.rotation() - 90); + } //color difference between block and unit in setting - Draw.mixcol(MI2UTmp.c1.set(unit.team().color).mul(0.9f), 1f); + Draw.mixcol(MI2UTmp.c1.set(unit.team().color).mul(Mathf.clamp(1f - drawUnitColorDifference)), 1f); Draw.rect(region, x + rx, y + ry, scale, scale * (float)region.height / region.width, unit.rotation() - 90); Draw.reset(); }); From f1338c5ab68d49dc161d300d8d5e827506147beb Mon Sep 17 00:00:00 2001 From: BlackDeluxeCat <65377021+BlackDeluxeCat@users.noreply.github.com> Date: Sat, 30 Dec 2023 15:16:30 +0800 Subject: [PATCH 02/57] icon +1 --- assets/sprites/ui-customai.png | Bin 0 -> 2442 bytes src/mi2u/MI2Utilities.java | 7 ++++++- src/mi2u/ai/FullAI.java | 1 + 3 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 assets/sprites/ui-customai.png diff --git a/assets/sprites/ui-customai.png b/assets/sprites/ui-customai.png new file mode 100644 index 0000000000000000000000000000000000000000..fab4fb380284d81c35f96fe5ee6542f7838cd5b1 GIT binary patch literal 2442 zcmcImU1%Id9KS@H#!3Vcr1;{veX+KC`+a*mCr|+$lUDg-J08-b#{}x zL=f~veNl=aRP;fm2nDO)gN0BUpTvh!&U4ea-Ce*gdc z{vSK9&d)tIap=B7nM`J)JX>1e*GX}VkMT47^&7@7cSN&K#hJ{V_lRR8^VZvkGnw%> z{OV$|Sa||s8f1}6Yb4taB97*hr`i$1%On9cQuo7x^uxww3HWY7I&D?dN>n5be|DXb zlk0O;yuOSbSDJblOtv8>2uOlJJ7|V6Y!{>sFXZ>)wIYEIBv~#<)50KFtjvQVWdvB+ zoQyTo0=ARYa)#+R$APYDc}2}DnjvdBXsS@xL2pRh8go6kP&(1G#h(gNBS|8tD6Lj2 z+cL70)fLTg97WX?U6(mRj@QBjwdF8A(q|}<7&AXgd>R75h-!2tDM;MY?h=A1r48er zOk6OfjUq+Ms$xkUpo>#nw8EMl<1SW6lLRD8Vvf~PELW*gN#R3jgCIr6$;>MEsJFJE z=(xHT5oLkIbcJCuv&t4ynRFJrJbIE@xw` zYnJTg9ezS4mJ#-J*|M>dC%Wli%kIxFQM@8DK+NwJgG({zNTq|0Rm<5m!;>}5wq>6C zo}5RXA=`$9wVH#8=4ySmCz;Rd5j6){g;y?TBsRi1TeoEFVS`hcy6o5nk#kP2rq__G z6U~soj@=?{QdXfZ*W3`*(8)?T>&HBLYrXn9NuKN7HGR-YM2N7cm4bvtoQW&-Ui(9I z+Mh>V+E#;b(mjITg~ilMT8NS9I@feR`K9dUe~ec5_TDjTCJ&7!Tc+d5#5En+G1a_` z43DUYSellr^;bXC`@wAdhu-(Z#SIkJ32(oOwCj2>4Oa;ph)9GO;$4@pxFC6q1^`7- z)5l1JPgxD!UNcJ*0wfgdr2npVT*CYT { MOD = mods.getMod(MI2Utilities.class); + MOD.meta.subtitle = MOD.meta.version; titleButtonSize = 32f; Pixmap fade = new Pixmap(128, 128); @@ -46,7 +47,11 @@ public MI2Utilities(){ Core.atlas.addRegion("fadeBackground", new TextureRegion(new Texture(fade))); fadeBackground = new TextureRegionDrawable(Core.atlas.find("fadeBackground")); - Mindow2.initMindowStyles(); + var whiteui = (TextureRegionDrawable)Tex.whiteui; + Mindow2.titleBarbgNormal = whiteui.tint(1f, 0.1f, 0.2f, 0.3f); + Mindow2.titleBarbgSnapped = whiteui.tint(1f, 0.1f, 0.2f, 0.2f); + Mindow2.white = whiteui.tint(1f, 1f, 1f, 1f); + Mindow2.gray2 = whiteui.tint(0.2f, 0.2f, 0.2f, 1f); MI2USettings.init(); InputUtils.init(); diff --git a/src/mi2u/ai/FullAI.java b/src/mi2u/ai/FullAI.java index 3040b1b..694bab4 100644 --- a/src/mi2u/ai/FullAI.java +++ b/src/mi2u/ai/FullAI.java @@ -477,6 +477,7 @@ public LogicMode(){ bannedInstructions.clear(); bannedInstructions.addAll(ControlI.class, WriteI.class, StopI.class, SetBlockI.class, SpawnUnitI.class, ApplyEffectI.class, SetRuleI.class, SetRateI.class, ExplosionI.class, SetFlagI.class, SpawnWaveI.class, SetPropI.class); btext = Iconc.blockWorldProcessor + ""; + bimg = Core.atlas.drawable("mi2-utilities-java-ui-customai"); Events.on(MI2UEvents.FinishSettingInitEvent.class, e -> { code = MI2USettings.getStr("ai.logic.code.0"); readCode(code); From 1055b16dd76449fca89e379e1c76d5e8b5319853 Mon Sep 17 00:00:00 2001 From: BlackDeluxeCat <65377021+BlackDeluxeCat@users.noreply.github.com> Date: Sat, 30 Dec 2023 15:17:01 +0800 Subject: [PATCH 03/57] fixed a lot of scaling problems --- src/mi2u/ui/elements/Mindow2.java | 104 ++++++++++++++++-------------- 1 file changed, 57 insertions(+), 47 deletions(-) diff --git a/src/mi2u/ui/elements/Mindow2.java b/src/mi2u/ui/elements/Mindow2.java index 390b4bb..4c0933c 100644 --- a/src/mi2u/ui/elements/Mindow2.java +++ b/src/mi2u/ui/elements/Mindow2.java @@ -78,8 +78,9 @@ public void init(){} public void rebuild(){ clear(); cont.setBackground(Styles.black3); - setupCont(cont); cont.touchable = Touchable.enabled; + setupCont(cont); + titleBar.clear(); setupTitle(); add(titleBar).growX(); @@ -87,6 +88,7 @@ public void rebuild(){ if(!minimized){ add(cont).growX(); } + setTransform(true); } /** called when rebuild Mindow2, should be overrided */ @@ -98,7 +100,6 @@ public void minimize(){ } public void setupTitle(){ - titleBar.clear(); titleBar.add(new ScrollPane(titlePane){ @Override public float getPrefWidth(){ @@ -115,14 +116,14 @@ public float getPrefWidth(){ }); sp.setFadeScrollBars(true); sp.setupFadeScrollBars(0.3f, 0f); - }).growX().left().minWidth(32f); + }).growX().right().get().hovered(() -> titleCfg = false); titleBar.image().width(2f).growY().color(Color.white); var toast = new Table(); toast.add(titleText).color(MI2UTmp.c1.set(0.8f,0.9f,1f,1f)); toast.button("-", textbtoggle, () -> { minimized = !minimized; - cury += (minimized ? 1f : -1f) * cont.getHeight(); + cury += (minimized ? 1f : -1f) * cont.getHeight() * scaleY; saveUISettings(); minimize(); }).size(titleButtonSize).update(b -> b.setChecked(minimized)); @@ -135,8 +136,8 @@ public float getPrefWidth(){ titleBar.add(new MCollapser(toast, true).setCollapsed(true, () -> { if(titleCfg && interval.check(0, 10000)) titleCfg = false; - return !titleCfg; - }).setDirection(true, true)); + return !titleCfg && !minimized; + }).setDirection(true, true).setDuration(0.2f)); titleBar.update(() -> { titleBar.invalidate(); @@ -187,10 +188,10 @@ public void act(float delta){ boolean slideAnime = edgeSnap(edgesnap); slideAnime = slideAnime | elementSnap(tbSnap, tbSnapAlign, lrSnap == null && !Align.isLeft(edgesnap) && !Align.isRight(edgesnap)); slideAnime = slideAnime | elementSnap(lrSnap, lrSnapAlign, tbSnap == null && !Align.isBottom(edgesnap) && !Align.isTop(edgesnap)); - if(slideAnime) interval.reset(1, 0); + if(slideAnime) interval.get(1, 0); if(!interval.check(1, 400)){ - setPosition(Mathf.lerpDelta(x, curx, 0.4f), Mathf.lerpDelta(y, cury, 0.4f)); + setPosition(Mathf.lerp(x, curx, 0.4f), Mathf.lerp(y, cury, 0.4f)); }else{ setPosition(curx, cury); } @@ -202,30 +203,50 @@ public void act(float delta){ } /** Returns the X position of the specified {@link Align alignment}. */ + @Override public float getX(int alignment){ float x = this.x; if((alignment & right) != 0) - x += width * cont.scaleX; + x += width * scaleX; else if((alignment & left) == 0) // - x += width * cont.scaleX / 2; + x += width * scaleX / 2; return x; } /** Returns the Y position of the specified {@link Align alignment}. */ + @Override public float getY(int alignment){ float y = this.y; if((alignment & top) != 0) - y += height * cont.scaleY; + y += height * scaleY; else if((alignment & bottom) == 0) // - y += height * cont.scaleY / 2; + y += height * scaleY / 2; return y; } + @Override + public void setPosition(float x, float y, int alignment){ + if((alignment & right) != 0) + x -= width * scaleX; + else if((alignment & left) == 0) // + x -= width * scaleX / 2; + + if((alignment & top) != 0) + y -= height * scaleY; + else if((alignment & bottom) == 0) // + y -= height * scaleY / 2; + + if(this.x != x || this.y != y){ + this.x = x; + this.y = y; + } + } + protected boolean edgeSnap(int align){ if(parent == null) return false; - if(Align.isTop(align)) cury = parent.getHeight() - getHeight() * cont.scaleY; + if(Align.isTop(align)) cury = parent.getHeight() - height * scaleY; if(Align.isBottom(align)) cury = 0; - if(Align.isRight(align)) curx = parent.getWidth() - getWidth() * cont.scaleX; + if(Align.isRight(align)) curx = parent.getWidth() - width * scaleX; if(Align.isLeft(align)) curx = 0; return align != Align.center; } @@ -233,10 +254,10 @@ protected boolean edgeSnap(int align){ protected boolean elementSnap(Element e, int align, boolean off){ if(e == null) return false; if(Align.isTop(align)) cury = e.getY(Align.top); - if(Align.isBottom(align)) cury = e.getY(Align.bottom) - getHeight() * cont.scaleY; + if(Align.isBottom(align)) cury = e.getY(Align.bottom) - height * scaleY; if(Align.isRight(align)) curx = e.getX(Align.right); - if(Align.isLeft(align)) curx = e.getX(Align.left) - getWidth() * cont.scaleX; + if(Align.isLeft(align)) curx = e.getX(Align.left) - width * scaleX; if(off){ if(Align.isTop(align) || Align.isBottom(align)){ @@ -250,9 +271,9 @@ protected boolean elementSnap(Element e, int align, boolean off){ } public int computeEdgeSnap(float mindowX, float mindowY, float dst){ - int top = Core.graphics.getHeight() - mindowY - getHeight() * cont.scaleY < dst ? Align.top : 0; + int top = Core.graphics.getHeight() - mindowY - getHeight() * scaleY < dst ? Align.top : 0; int bottom = mindowY < dst ? Align.bottom : 0; - int right = Core.graphics.getWidth() - mindowX - getWidth() * cont.scaleX < dst ? Align.right : 0; + int right = Core.graphics.getWidth() - mindowX - getWidth() * scaleX < dst ? Align.right : 0; int left = mindowX < dst ? Align.left : 0; return top | left | right | bottom; } @@ -272,8 +293,8 @@ public void setSnap(float mindowX, float mindowY){ if(m.lrSnap == this || m.tbSnap == this) continue; if(!m.visible || !m.hasParent()) continue; - dst = Math.abs(m.getX(Align.left) - (mindowX + getWidth() * cont.scaleX)); - if(dst < 32f && dst <= dst1 && between.get(mindowY, m.y - getHeight() * cont.scaleY, m.y + m.getHeight() * m.cont.scaleY)){ + dst = Math.abs(m.getX(Align.left) - (mindowX + getWidth() * scaleX)); + if(dst < 32f && dst <= dst1 && between.get(mindowY, m.y - getHeight() * scaleY, m.y + m.getHeight() * m.scaleY)){ dst1 = dst; lrSnap = m; lrSnapAlign = Align.left; @@ -281,15 +302,15 @@ public void setSnap(float mindowX, float mindowY){ }; dst = Math.abs(m.getX(Align.right) - mindowX); - if(dst < 32f && dst <= dst1 && between.get(mindowY, m.y - getHeight() * cont.scaleY, m.y + m.getHeight() * m.cont.scaleY)){ + if(dst < 32f && dst <= dst1 && between.get(mindowY, m.y - getHeight() * scaleY, m.y + m.getHeight() * m.scaleY)){ dst1 = dst; lrSnap = m; lrSnapAlign = Align.right; lrBottomOff = mindowY - m.y; }; - dst = Math.abs(m.getY(Align.bottom) - (mindowY + getHeight() * cont.scaleY)); - if(dst < 32f && dst <= dst2 && between.get(mindowX, m.x - getWidth() * cont.scaleX, m.x + m.getWidth() * m.cont.scaleX)){ + dst = Math.abs(m.getY(Align.bottom) - (mindowY + getHeight() * scaleY)); + if(dst < 32f && dst <= dst2 && between.get(mindowX, m.x - getWidth() * scaleX, m.x + m.getWidth() * m.scaleX)){ dst2 = dst; tbSnap = m; tbSnapAlign = Align.bottom; @@ -297,7 +318,7 @@ public void setSnap(float mindowX, float mindowY){ }; dst = Math.abs(m.getY(Align.top) - mindowY); - if(dst < 32f && dst <= dst2 && between.get(mindowX, m.x - getWidth() * cont.scaleX, m.x + m.getWidth() * m.cont.scaleX)){ + if(dst < 32f && dst <= dst2 && between.get(mindowX, m.x - getWidth() * scaleX, m.x + m.getWidth() * m.scaleX)){ dst2 = dst; tbSnap = m; tbSnapAlign = Align.top; @@ -338,7 +359,7 @@ public boolean addTo(Group newParent){ newParent.addChild(this); return true; } - + public void showHelp(){ new BaseDialog("@mindow2.helpInfoTitle"){ { @@ -353,7 +374,7 @@ public void showHelp(){ }; } - /** Settings shoulded be set in Seq: settings, will be shown and configurable in SettingsDialog + /** Settings shoulded be set in Seq: settings, will be shown and configurable in SettingsDialog * UISetting will be shown to, but not configurable */ public void showSettings(){ @@ -387,7 +408,6 @@ public void initSettings(){ * rebuild() called once finished loading */ public boolean loadUISettingsRaw(){ - //it is a no-named mindow2, no settings can be loaded. if(mindowName == null || mindowName.equals("")) return false; minimized = MI2USettings.getBool(mindowName + ".minimized"); edgesnap = MI2USettings.getInt(mindowName + ".edgesnap", -1); @@ -395,7 +415,7 @@ public boolean loadUISettingsRaw(){ cury = (float)MI2USettings.getInt(mindowName + ".cury"); //curw = (float)MI2USettings.getInt(mindowName + ".curw"); //curh = (float)MI2USettings.getInt(mindowName + ".curh"); - cont.setScale(MI2USettings.getInt(mindowName + ".scale", 100) / 100f); + setScale(MI2USettings.getInt(mindowName + ".scale", 100) / 100f); mindow2s.each(m -> { if(m == this) return; if(m.mindowName.equals(MI2USettings.getStr(mindowName + ".LRsnap", "null"))){ @@ -418,11 +438,12 @@ public void loadUISettings(){ rebuild(); } - /** Override this method for custom UI settings save + /** + * Override this method for custom UI settings save */ - public boolean saveUISettings(){ + public void saveUISettings(){ //it is a not-named mindow2, no settings can be saved. - if(mindowName == null || mindowName.equals("")) return false; + if(mindowName == null || mindowName.equals("")) return; MI2USettings.putBool(mindowName + ".minimized", minimized); MI2USettings.putInt(mindowName + ".edgesnap", edgesnap); //edgesnap will disable curx / cury changes, so they shouldn't be saved when edgesnapping. @@ -434,7 +455,7 @@ public boolean saveUISettings(){ } //MI2USettings.putInt(mindowName + ".curw", (int)curw); //MI2USettings.putInt(mindowName + ".curh", (int)curh); - MI2USettings.putInt(mindowName + ".scale", (int)(cont.scaleX * 100)); + MI2USettings.putInt(mindowName + ".scale", (int)(scaleX * 100)); MI2USettings.putStr(mindowName + ".LRsnap", lrSnap == null ? "null" : lrSnap.mindowName); MI2USettings.putInt(mindowName + ".LRsnapAlign", lrSnapAlign); @@ -442,23 +463,12 @@ public boolean saveUISettings(){ MI2USettings.putStr(mindowName + ".TBsnap", tbSnap == null ? "null" : tbSnap.mindowName); MI2USettings.putInt(mindowName + ".TBsnapAlign", tbSnapAlign); MI2USettings.putInt(mindowName + ".TBsnapOff", (int)tbLeftOff); - return true; } - public boolean registerName(){ + public void registerName(){ if(mindowName != null && !mindowName.equals("") && !mindow2s.contains(m -> m.mindowName.equals(this.mindowName))){ mindow2s.add(this); - return true; } - return false; - } - - public static void initMindowStyles(){ - var whiteui = (TextureRegionDrawable)Tex.whiteui; - titleBarbgNormal = whiteui.tint(1f, 0.1f, 0.2f, 0.3f); - titleBarbgSnapped = whiteui.tint(1f, 0.1f, 0.2f, 0.2f); - white = whiteui.tint(1f, 1f, 1f, 1f); - gray2 = whiteui.tint(0.2f, 0.2f, 0.2f, 1f); } public class MindowUIGroupEntry extends SettingGroupEntry{ @@ -472,7 +482,7 @@ public void build(Table table) { table.labelWrap(() -> this.name + " = " + (setting != null ? Align.toString(Strings.parseInt(setting.get())) : "invaild")).left().growX().get().setColor(0, 1, 1, 0.7f); } }; - FieldEntry entry6 = new FieldEntry(mindowName + ".scale", "@settings.mindow2.scale", "100", TextField.TextFieldFilter.digitsOnly, str -> Strings.canParseInt(str) && Strings.parseInt(str) >= 5 && Strings.parseInt(str) <= 400, str -> cont.setScale(Strings.parseInt(str, 100)/100f)); + FieldEntry entry6 = new FieldEntry(mindowName + ".scale", "@settings.mindow2.scale", "100", TextField.TextFieldFilter.digitsOnly, str -> Strings.canParseInt(str) && Strings.parseInt(str) >= 5 && Strings.parseInt(str) <= 400, str -> setScale(Strings.parseInt(str, 100)/100f)); Table buildTarget; public MindowUIGroupEntry(String name, String help) { @@ -551,8 +561,8 @@ public void draw(){ if(mind.parent != Mindow2.this.parent) return; Draw.color(mind == Mindow2.this ? Color.coral : Color.grays(0.4f)); Draw.alpha(0.8f * parentAlpha * 0.8f); - float mindw = (mind.getWidth()/Core.graphics.getWidth())*this.getWidth(), - mindh = (mind.getHeight()/Core.graphics.getHeight())*this.getHeight(); + float mindw = (mind.getWidth()*mind.scaleX/Core.graphics.getWidth())*this.getWidth(), + mindh = (mind.getHeight()*mind.scaleY/Core.graphics.getHeight())*this.getHeight(); float mindx = x + (mind.x/Core.graphics.getWidth())*this.getWidth() + mindw/2f, mindy = y + (mind.y/Core.graphics.getHeight())*this.getHeight() + mindh/2f; Fill.rect(mindx, mindy, mindw, mindh); Draw.reset(); From ac03605f9b2a0ed3349091f9c5f676b25e355046 Mon Sep 17 00:00:00 2001 From: BlackDeluxeCat <65377021+BlackDeluxeCat@users.noreply.github.com> Date: Sat, 30 Dec 2023 15:42:56 +0800 Subject: [PATCH 04/57] =?UTF-8?q?=E5=8F=96=E6=B6=88=E4=BA=86=E6=A0=87?= =?UTF-8?q?=E9=A2=98=E6=A0=8F=E5=8C=BA=E5=9F=9F=E7=9A=84=E8=A3=81=E5=89=AA?= =?UTF-8?q?=E5=BC=8F=E6=BB=91=E6=9D=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/mi2u/ui/elements/Mindow2.java | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/src/mi2u/ui/elements/Mindow2.java b/src/mi2u/ui/elements/Mindow2.java index 4c0933c..fad9882 100644 --- a/src/mi2u/ui/elements/Mindow2.java +++ b/src/mi2u/ui/elements/Mindow2.java @@ -100,23 +100,8 @@ public void minimize(){ } public void setupTitle(){ - titleBar.add(new ScrollPane(titlePane){ - @Override - public float getPrefWidth(){ - return 0f; - } - }).scrollX(true).scrollY(false).with(sp -> { - sp.update(() -> { - Element e = Core.scene.hit(Core.input.mouseX(), Core.input.mouseY(), true); - if(e != null && e.isDescendantOf(sp)){ - sp.requestScroll(); - }else if(sp.hasScroll()){ - Core.scene.setScrollFocus(null); - } - }); - sp.setFadeScrollBars(true); - sp.setupFadeScrollBars(0.3f, 0f); - }).growX().right().get().hovered(() -> titleCfg = false); + titlePane.touchable = Touchable.enabled; + titleBar.add(new MCollapser(titlePane, false).setCollapsed(() -> minimized)).growX().get().hovered(() -> titleCfg = false); titleBar.image().width(2f).growY().color(Color.white); var toast = new Table(); From 7d8cfd4863aa9a71d5f5b2886b89882a70d5fdf7 Mon Sep 17 00:00:00 2001 From: BlackDeluxeCat <65377021+BlackDeluxeCat@users.noreply.github.com> Date: Sat, 30 Dec 2023 15:42:59 +0800 Subject: [PATCH 05/57] Update MinimapMindow.java --- src/mi2u/ui/MinimapMindow.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mi2u/ui/MinimapMindow.java b/src/mi2u/ui/MinimapMindow.java index c3c2aae..9dd6f0f 100644 --- a/src/mi2u/ui/MinimapMindow.java +++ b/src/mi2u/ui/MinimapMindow.java @@ -131,7 +131,7 @@ public void setupCont(Table cont){ cont.clear(); int size = MI2USettings.getInt(mindowName + ".size", 140); m.setMapSize(size); - cont.add(m); + cont.add(m).margin(2f); } @Override From a43575ec52e480c87f3a9a29372365c8b4cd0473 Mon Sep 17 00:00:00 2001 From: BlackDeluxeCat <65377021+BlackDeluxeCat@users.noreply.github.com> Date: Sat, 30 Dec 2023 15:43:07 +0800 Subject: [PATCH 06/57] 1.5.1 --- mod.hjson | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mod.hjson b/mod.hjson index 4f5e5dc..98888aa 100644 --- a/mod.hjson +++ b/mod.hjson @@ -5,7 +5,7 @@ displayName: "MI2-Utilities Java" name: "mi2-utilities-java" #the mod version -version: 1.5.0 +version: 1.5.1 #the minimum game build required to run this mod minGameVersion: 146 From 9d1da117dc7bb1ced2663c90d55bf4e40e9bbf18 Mon Sep 17 00:00:00 2001 From: BlackDeluxeCat <65377021+BlackDeluxeCat@users.noreply.github.com> Date: Sat, 30 Dec 2023 17:25:21 +0800 Subject: [PATCH 07/57] 1.5.1b --- mod.hjson | 2 +- src/mi2u/ui/MinimapMindow.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mod.hjson b/mod.hjson index 98888aa..2e579d1 100644 --- a/mod.hjson +++ b/mod.hjson @@ -5,7 +5,7 @@ displayName: "MI2-Utilities Java" name: "mi2-utilities-java" #the mod version -version: 1.5.1 +version: 1.5.1b #the minimum game build required to run this mod minGameVersion: 146 diff --git a/src/mi2u/ui/MinimapMindow.java b/src/mi2u/ui/MinimapMindow.java index 9dd6f0f..61ee2cc 100644 --- a/src/mi2u/ui/MinimapMindow.java +++ b/src/mi2u/ui/MinimapMindow.java @@ -112,7 +112,7 @@ public MinimapMindow(){ tt.row(); tt.add("").color(Color.coral).with(c -> { c.update(() -> { - c.setText(Strings.fixed(World.conv(Core.input.mouseWorldX()), 1) + ", "+ Strings.fixed(Core.input.mouseWorldY(), 1)); + c.setText(Strings.fixed(World.conv(Core.input.mouseWorldX()), 1) + ", "+ Strings.fixed(World.conv(Core.input.mouseWorldY()), 1)); c.setFontScale(titlePane.getWidth() > 110f ? 0.8f : 0.5f); }); c.setAlignment(Align.right); @@ -131,7 +131,7 @@ public void setupCont(Table cont){ cont.clear(); int size = MI2USettings.getInt(mindowName + ".size", 140); m.setMapSize(size); - cont.add(m).margin(2f); + cont.add(m); } @Override From 80043ccd791fc6339395c0b44544ca06c4b004ea Mon Sep 17 00:00:00 2001 From: BlackDeluxeCat <65377021+BlackDeluxeCat@users.noreply.github.com> Date: Sun, 31 Dec 2023 11:36:42 +0800 Subject: [PATCH 08/57] Update MI2UI.java --- src/mi2u/ui/MI2UI.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mi2u/ui/MI2UI.java b/src/mi2u/ui/MI2UI.java index 755aeff..571003b 100644 --- a/src/mi2u/ui/MI2UI.java +++ b/src/mi2u/ui/MI2UI.java @@ -102,7 +102,7 @@ public MI2UI(){ SpeedController.update(); b.getLabel().setFontScale(1f); b.getLabel().layout(); - b.getLabel().setFontScale(Math.min((b.getWidth()- 8f - 16f - 8f) / b.getLabel().getGlyphLayout().width, 1f)); + b.getLabel().setFontScale(Mathf.clamp((b.getWidth()- 8f - 16f - 8f) / b.getLabel().getGlyphLayout().width, 0.01f, 1f)); }).with(funcSetTextb).with(b -> { b.margin(4f); b.table(bii -> { From 3c2f75ff0f97f9878d42668c65dc0ef122edf7d8 Mon Sep 17 00:00:00 2001 From: BlackDeluxeCat <1030767312@qq.com> Date: Mon, 1 Jan 2024 12:34:44 +0800 Subject: [PATCH 09/57] Wave Info ui --- assets/bundles/bundle.properties | 7 +- assets/bundles/bundle_zh_CN.properties | 7 +- src/mi2u/struct/WorldData.java | 10 +- src/mi2u/ui/MapInfoTable.java | 343 ++++++++++++------------- src/mi2u/ui/elements/PopupTable.java | 2 + 5 files changed, 187 insertions(+), 182 deletions(-) diff --git a/assets/bundles/bundle.properties b/assets/bundles/bundle.properties index 3b38d7c..a56164c 100644 --- a/assets/bundles/bundle.properties +++ b/assets/bundles/bundle.properties @@ -19,8 +19,8 @@ coreInfo.selectButton.playerteam = (Player Team) mapInfo.buttons.allAttrs = Map Attrs mapInfo.buttons.allWaves = Waves -mapInfo.buttons.preview = Preview -mapInfo.buttons.setWave = Go +mapInfo.buttons.setWave = Set Wave +mapInfo.buttons.adminFunctions = Admin mapInfo.buttons.forceRunWave = Force Next mapInfo.buttons.bannedBlocks = Banned Blocks mapInfo.buttons.bannedUnits = Banned Units @@ -28,7 +28,10 @@ mapInfo.buttons.hiddenBuildItems = Hidden Build Items mapInfo.buttons.revealedBlocks = Revealed Blocks mapInfo.buttons.objectiveFlags = Objective Flags mapInfo.buttons.mapTags = Map Tags +mapInfo.buttons.expand = Expand +mapInfo.buttons.fold = Fold +mapInfo.view = View mapInfo.buildingHpMutil = BHp mapInfo.buildingDamageMutil = BDmg mapInfo.unitHealthMultiplier = UHp diff --git a/assets/bundles/bundle_zh_CN.properties b/assets/bundles/bundle_zh_CN.properties index f83ddee..0389017 100644 --- a/assets/bundles/bundle_zh_CN.properties +++ b/assets/bundles/bundle_zh_CN.properties @@ -19,8 +19,8 @@ coreInfo.selectButton.playerteam = (玩家队伍) mapInfo.buttons.allAttrs = 地图属性 mapInfo.buttons.allWaves = 波次 -mapInfo.buttons.preview = 预览出怪 -mapInfo.buttons.setWave = 跳转 +mapInfo.buttons.setWave = 设置波次 +mapInfo.buttons.adminFunctions = 管理波次 mapInfo.buttons.forceRunWave = 强制下一波 mapInfo.buttons.bannedBlocks = 禁用的建筑 mapInfo.buttons.bannedUnits = 禁用的单位 @@ -28,7 +28,10 @@ mapInfo.buttons.hiddenBuildItems = 隐藏的建材 mapInfo.buttons.revealedBlocks = 显示的建筑 mapInfo.buttons.objectiveFlags = 地图目标Flag mapInfo.buttons.mapTags = 地图Tag +mapInfo.buttons.expand = 展开 +mapInfo.buttons.fold = 折叠 +mapInfo.view = 显示 mapInfo.buildingHpMutil = 建筑血量 mapInfo.buildingDamageMutil = 建筑伤害 mapInfo.unitHealthMultiplier = 单位血量 diff --git a/src/mi2u/struct/WorldData.java b/src/mi2u/struct/WorldData.java index 3a7b4c1..0df2eeb 100644 --- a/src/mi2u/struct/WorldData.java +++ b/src/mi2u/struct/WorldData.java @@ -23,8 +23,9 @@ public class WorldData{ static ObjectMap backTiles1 = new ObjectMap<>(), backTiles2 = new ObjectMap<>(); private static ObjectSet scanned = new ObjectSet<>(); - public static Seq spawnPoints = new Seq<>(); - public static Seq groundSpawns = new Seq<>(); + public static IntSeq spawnPoints = new IntSeq(); + public static IntSeq groundSpawns = new IntSeq(); + public static Seq usedSpawns = new Seq<>(); //temp static boolean any = false; @@ -111,12 +112,17 @@ private static void putBlock(Block block, int pos, int team){ public static void updateSpanwer(){ spawnPoints.clear(); groundSpawns.clear(); + usedSpawns.clear(); for(Tile tile : spawner.getSpawns()){ spawnPoints.add(tile.pos()); groundSpawns.add(tile.pos()); } + for(var group : state.rules.spawns){ + if(group.spawn != -1 && !usedSpawns.contains(group.spawn)) usedSpawns.add(group.spawn); + } + //rewrite Anuke's, as invoking private method "each.*Spawn" with private interface param is too hard for me. if(state.rules.attackMode && state.teams.isActive(state.rules.waveTeam) && !state.teams.playerCores().isEmpty()){ Building firstCore = state.teams.playerCores().first(); diff --git a/src/mi2u/ui/MapInfoTable.java b/src/mi2u/ui/MapInfoTable.java index ac0e9cb..4c0371d 100644 --- a/src/mi2u/ui/MapInfoTable.java +++ b/src/mi2u/ui/MapInfoTable.java @@ -4,6 +4,8 @@ import arc.func.*; import arc.graphics.*; +import arc.input.*; +import arc.math.*; import arc.math.geom.*; import arc.scene.*; import arc.scene.event.*; @@ -29,13 +31,15 @@ public class MapInfoTable extends Table{ protected Seq hpBars = new Seq<>(), pool = new Seq<>(), tmp = new Seq<>(); - protected PopupTable detailt = new PopupTable(), wavesPopup = new PopupTable(), attrsListPopup = new PopupTable(), spawnerSelect = new PopupTable(); + protected PopupTable wavesPopup = new PopupTable(); + protected PopupTable attrsListPopup = new PopupTable(); + protected PopupTable spawnerSelect = new PopupTable(); public BaseDialog mapAttsDialog; Table barsTable; - private static int lastWave = -1, lastSpawn = -1; - private MI2Utils.IntervalMillis millTimer = new MI2Utils.IntervalMillis(); - private boolean syncCurWave = true, showWaveDetail = false; + private final MI2Utils.IntervalMillis millTimer = new MI2Utils.IntervalMillis(); + private boolean syncCurWave = true; + /** start from 0 */ public static int curWave = 0, curSpawn = -1; public MapInfoTable(){ super(); @@ -66,10 +70,9 @@ public MapInfoTable(){ clearData(); return; } - if(!millTimer.get(500)) return; + if(!millTimer.get(800)) return; updateData(); - //waves update - if(barsTable != null && barsTable.hasParent()) buildBars(barsTable); + buildBars(barsTable); }); //ui on MI2U @@ -88,67 +91,78 @@ public MapInfoTable(){ //wave tools wavesPopup.addInGameVisible(); - wavesPopup.update(() -> { - wavesPopup.keepInScreen(); - }); + wavesPopup.update(() -> wavesPopup.keepInScreen()); wavesPopup.touchable = Touchable.enabled; wavesPopup.addCloseButton(); wavesPopup.addDragMove(); wavesPopup.background(Styles.black3); + //设置要检索的波次 wavesPopup.table(t -> { - t.label(() -> "Wave: " + (curWave + 1)).growX(); + t.label(() -> Core.bundle.format("mapInfo.wave", curWave + 1)).growX(); + t.button("@mapInfo.buttons.setWave", textb, () -> { + curWave = Math.max(curWave, 0); + state.wave = curWave + 1; + }).with(funcSetTextb).with(b -> b.setDisabled(() -> net.client())); t.row(); t.table(t3 -> { - t3.button("@mapInfo.buttons.setWave", textb, () -> { - curWave = Math.max(curWave, 0); - state.wave = curWave + 1; - }).with(funcSetTextb).with(b -> b.setDisabled(() -> net.client())).minSize(titleButtonSize); - t3.button("@mapInfo.buttons.forceRunWave", textb, () -> { - logic.runWave(); - }).with(funcSetTextb).with(b -> b.setDisabled(() -> net.client())).height(titleButtonSize); - t3.button("" + Iconc.refresh, textbtoggle, () -> { - if(state.rules.infiniteResources) state.rules.waveTimer = !state.rules.waveTimer; - }).update(b -> b.setChecked(state.rules.waveTimer)).with(funcSetTextb).with(b -> b.setDisabled(() -> net.client())).height(titleButtonSize); - }); - }).growX().row(); - - wavesPopup.table(t3 -> { - t3.button("<<", textb, () -> { - syncCurWave = false; - curWave = Math.max(curWave - 10, 0); - }).with(funcSetTextb).size(titleButtonSize); - t3.button("<", textb, () -> { - syncCurWave = false; - curWave = Math.max(curWave - 1, 0); - }).with(funcSetTextb).size(titleButtonSize); - t3.button("O", textbtoggle, () -> { - syncCurWave = !syncCurWave; - }).with(funcSetTextb).size(titleButtonSize).update(b -> { - b.setChecked(syncCurWave); - if(syncCurWave) curWave = Math.max(state.wave - 1, 0); - }); - t3.button(">", textb, () -> { - syncCurWave = false; - curWave = Math.max(curWave + 1, 0); - }).with(funcSetTextb).size(titleButtonSize); - t3.button(">>", textb, () -> { - syncCurWave = false; - curWave = Math.max(curWave + 10, 0); - }).with(funcSetTextb).size(titleButtonSize); - TextField tf = new TextField(); - tf.changed(() -> { - if(Strings.canParseInt(tf.getText()) && Strings.parseInt(tf.getText()) > 0){ + t3.button("<<", textb, () -> { syncCurWave = false; - curWave = Math.max(Strings.parseInt(tf.getText()) - 1, 0); - } - }); - t3.add(tf).width(80f).height(28f); - }).row(); + curWave = Math.max(curWave - 10, 0); + }).with(funcSetTextb).size(titleButtonSize); + t3.button("<", textb, () -> { + syncCurWave = false; + curWave = Math.max(curWave - 1, 0); + }).with(funcSetTextb).size(titleButtonSize); + t3.button("O", textbtoggle, () -> { + syncCurWave = !syncCurWave; + }).with(funcSetTextb).size(titleButtonSize).update(b -> { + b.setChecked(syncCurWave); + if(syncCurWave) curWave = Math.max(state.wave - 1, 0); + }); + t3.button(">", textb, () -> { + syncCurWave = false; + curWave = Math.max(curWave + 1, 0); + }).with(funcSetTextb).size(titleButtonSize); + t3.button(">>", textb, () -> { + syncCurWave = false; + curWave = Math.max(curWave + 10, 0); + }).with(funcSetTextb).size(titleButtonSize); + TextField tf = new TextField(); + tf.changed(() -> { + if(Strings.canParseInt(tf.getText()) && Strings.parseInt(tf.getText()) > 0){ + syncCurWave = false; + curWave = Math.max(Strings.parseInt(tf.getText()) - 1, 0); + } + }); + t3.add(tf).width(80f).height(28f); + }).colspan(2); + }).left().row(); + //管理员功能 + wavesPopup.table(t3 -> { + t3.defaults().fillY(); + t3.add("@mapInfo.buttons.adminFunctions"); + t3.button("@mapInfo.buttons.forceRunWave", textb, () -> { + logic.runWave(); + }).with(funcSetTextb).with(b -> b.setDisabled(() -> net.client())).height(titleButtonSize); + t3.button("@rules.wavetimer", textbtoggle, () -> { + if(state.rules.infiniteResources) state.rules.waveTimer = !state.rules.waveTimer; + }).update(b -> b.setChecked(state.rules.waveTimer)).with(funcSetTextb).with(b -> b.setDisabled(() -> net.client())).height(titleButtonSize); + }).left().row(); + + //显示设置 wavesPopup.table(t4 -> { t4.defaults().fillY(); - t4.button("@mapInfo.buttons.preview", textbtoggle, () -> showWaveDetail = !showWaveDetail).checked(showWaveDetail).with(funcSetTextb); + t4.add("@mapInfo.view"); + t4.button("@mapInfo.buttons.expand", textb, () -> { + hpBars.each(bar -> bar.collapser.setCollapsed(false, true)); + }).with(funcSetTextb); + t4.button("@mapInfo.buttons.fold", textb, () -> { + hpBars.each(bar -> bar.collapser.setCollapsed(true, true)); + }).with(funcSetTextb); + t4.button(Iconc.blockSpawn + Core.bundle.get("waves.spawn.all"), textb, null).growX().with(b -> { + b.setDisabled(() -> WorldData.usedSpawns.isEmpty()); b.clicked(() -> { var p = spawnerSelect; p.clear(); @@ -157,61 +171,33 @@ public MapInfoTable(){ p.background(Styles.grayPanel).margin(10f); int i = 0; int cols = 4; - int max = 32; - - if(spawner.getSpawns().size >= max){ - p.add("[lightgray](first " + max + ")").colspan(cols).padBottom(4).row(); - } - for(var spawn : spawner.getSpawns()){ - p.button(spawn.x + ", " + spawn.y, Styles.flatTogglet, () -> { - curSpawn = Point2.pack(spawn.x, spawn.y); - b.setText(Iconc.blockSpawn + ": " + spawn.x + ", " + spawn.y); + for(var spawn : WorldData.usedSpawns){ + int x = Point2.x(spawn), y = Point2.y(spawn); + p.button(x + ", " + y, Styles.flatTogglet, () -> { + curSpawn = spawn; + b.setText(Iconc.blockSpawn + ": " + x + ", " + y); p.hide(); - }).size(50, 32f).checked(spawn.pos() == curSpawn); + }).size(50, 32f).checked(spawn == curSpawn); if(++i % cols == 0) p.row(); - - //only display first 20 spawns, you don't need to see more. - if(i >= max) break; } - if(spawner.getSpawns().isEmpty()){ + p.button("@waves.spawn.all", Styles.flatTogglet, () -> { + curSpawn = -1; + b.setText(Iconc.blockSpawn + Core.bundle.get("waves.spawn.all")); p.hide(); - }else{ - p.button("@waves.spawn.all", Styles.flatTogglet, () -> { - curSpawn = -1; - b.setText(Iconc.blockSpawn + Core.bundle.get("waves.spawn.all")); - p.hide(); - }).size(110f, 45f).checked(-1 == curSpawn); - } + }).size(50f, 32f).checked(-1 == curSpawn); }); - b.setDisabled(() -> spawner.getSpawns().isEmpty()); - }); - }).height(24f).growX().row(); - - - wavesPopup.pane(p -> { - p.update(() -> { - if(lastWave == curWave && lastSpawn == curSpawn) return; - if(lastSpawn != curSpawn && showWaveDetail) hpBars.each(WaveBar::setupPrev); - lastWave = curWave; - lastSpawn = curSpawn; - p.clear(); - buildPreview(p, curWave, curSpawn); }); - }).fillX().maxHeight(Core.graphics.getHeight()*0.1f/Scl.scl()).update(p -> { - Element e = Core.scene.hit(Core.input.mouseX(), Core.input.mouseY(), true); - if(e != null && e.isDescendantOf(p)){ - p.requestScroll(); - }else if(p.hasScroll()){ - Core.scene.setScrollFocus(null); - } - }).row(); + }).growX().row(); + final float[] h = new float[1]; + h[0] = Core.graphics.getHeight()*0.5f/Scl.scl(); wavesPopup.pane(t -> barsTable = t).fillX().self(c -> { c.update(p -> { - c.maxHeight(Core.graphics.getHeight()*0.5f/Scl.scl()); + h[0] = Mathf.clamp(h[0], 10f, (Core.graphics.getHeight() - 200f)/Scl.scl()); + c.height(h[0]); Element e = Core.scene.hit(Core.input.mouseX(), Core.input.mouseY(), true); if(e != null && e.isDescendantOf(p)){ p.requestScroll(); @@ -219,11 +205,35 @@ public MapInfoTable(){ Core.scene.setScrollFocus(null); } }); - }); + }).row(); + wavesPopup.button("↕", textb, () -> {}).growX().with(b -> { + b.addListener(new InputListener(){ + float lastX, lastY; + @Override + public void touchDragged(InputEvent event, float mx, float my, int pointer){ + h[0] += (my - lastY)/Scl.scl(); + lastX = mx; + lastY = my; + } + + @Override + public boolean touchDown(InputEvent event, float x, float y, int pointer, KeyCode button){ + wavesPopup.cancelDrag = true; + lastX = x; + lastY = y; + return true; + } + + @Override + public void touchUp(InputEvent event, float x, float y, int pointer, KeyCode button){ + super.touchUp(event, x, y, pointer, button); + wavesPopup.cancelDrag = false; + } + }); + }); } - //single wave details public void buildBars(Table t){ tmp.clear(); t.clearChildren(); @@ -231,7 +241,7 @@ public void buildBars(Table t){ allwaves.each(d -> { if(i[0]++ > 50) return; if(d.totalHp + d.totalHp <= 0f) return; - var found = hpBars.find(b -> b.wave == d.wave); + var found = hpBars.find(b -> b.wave == d.wave);//复用相同wave if(found != null){ hpBars.remove(found); tmp.add(found); @@ -249,48 +259,13 @@ public void buildBars(Table t){ hpBars.sort(b -> b.wave); hpBars.each(b -> { t.add(b).growX(); - b.setup(showWaveDetail); + b.setup(); t.row(); }); layout(); } - public void buildPreview(Table t, int curWave, int spawn){ - t.table(tt -> { - int i = 0; - for(SpawnGroup group : state.rules.spawns){ - if(spawn != -1 && group.spawn != -1 && spawn != group.spawn) continue; - if(group.getSpawned(curWave) < 1) continue; - tt.table(g -> { - g.table(gt -> { - gt.image(group.type.uiIcon).size(18f); - gt.add("x" + group.getSpawned(curWave)).get().setFontScale(0.7f); - }); - g.row(); - g.add("" + group.getShield(curWave)).get().setFontScale(0.7f); - g.row(); - g.table(eip -> { - if(group.effect != null && group.effect != StatusEffects.none) eip.image(group.effect.uiIcon).size(12f); - if(group.items != null) eip.stack(new Image(group.items.item.uiIcon), new Label(String.valueOf(group.items.amount)){{ - this.setFillParent(true); - this.setAlignment(Align.bottomRight); - this.setFontScale(0.7f); - }}).size(12f); - if(group.payloads != null && !group.payloads.isEmpty()) eip.add("" + Iconc.units).get().setFontScale(0.7f); - if(group.spawn != -1) eip.add(Iconc.blockSpawn + "").get().clicked(() -> { - if(control.input instanceof InputOverwrite iow) iow.pan(true, MI2UTmp.v1.set(Point2.unpack(group.spawn).x, Point2.unpack(group.spawn).y).scl(tilesize)); - }); - }); - }).pad(2f); - if(++i >= 5){ - i = 0; - tt.row(); - } - } - }); - } - //single wave details public void buildDetailBars(Table t, WaveData data){ t.pane(p -> { @@ -499,17 +474,17 @@ public void setupDetailAttsInfo(){ teamt.row(); var teamRule = state.rules.teams.get(teamData.team); teamt.add("[#" + teamData.team.color + "]" + teamData.team.localized()); - teamt.add("" + teamRule.unitBuildSpeedMultiplier).color(teamData.team.color); - teamt.add("" + teamRule.unitHealthMultiplier).color(teamData.team.color); - teamt.add("" + teamRule.unitDamageMultiplier).color(teamData.team.color); - teamt.add("" + teamRule.unitCrashDamageMultiplier).color(teamData.team.color); - teamt.add("" + teamRule.blockHealthMultiplier).color(teamData.team.color); - teamt.add("" + teamRule.blockDamageMultiplier).color(teamData.team.color); - teamt.add("" + teamRule.buildSpeedMultiplier).color(teamData.team.color); - teamt.add("" + teamRule.infiniteAmmo).color(teamData.team.color); - teamt.add("" + teamRule.infiniteResources).color(teamData.team.color); - teamt.add("" + teamRule.cheat).color(teamData.team.color); - teamt.add("" + (teamRule.rtsAi ? teamRule.rtsMinWeight + "[" + teamRule.rtsMinSquad + "~" + teamRule.rtsMaxSquad + "]" + (teamRule.aiCoreSpawn ? Core.bundle.format("mapInfo.aiCoreSpawn") : "") : "")).color(teamData.team.color); + teamt.add(String.valueOf(teamRule.unitBuildSpeedMultiplier)).color(teamData.team.color); + teamt.add(String.valueOf(teamRule.unitHealthMultiplier)).color(teamData.team.color); + teamt.add(String.valueOf(teamRule.unitDamageMultiplier)).color(teamData.team.color); + teamt.add(String.valueOf(teamRule.unitCrashDamageMultiplier)).color(teamData.team.color); + teamt.add(String.valueOf(teamRule.blockHealthMultiplier)).color(teamData.team.color); + teamt.add(String.valueOf(teamRule.blockDamageMultiplier)).color(teamData.team.color); + teamt.add(String.valueOf(teamRule.buildSpeedMultiplier)).color(teamData.team.color); + teamt.add(String.valueOf(teamRule.infiniteAmmo)).color(teamData.team.color); + teamt.add(String.valueOf(teamRule.infiniteResources)).color(teamData.team.color); + teamt.add(String.valueOf(teamRule.cheat)).color(teamData.team.color); + teamt.add(teamRule.rtsAi ? teamRule.rtsMinWeight + "[" + teamRule.rtsMinSquad + "~" + teamRule.rtsMaxSquad + "]" + (teamRule.aiCoreSpawn ? Core.bundle.format("mapInfo.aiCoreSpawn") : "") : "").color(teamData.team.color); } }); @@ -553,31 +528,26 @@ public void showIterable(String title, Iterable array, Boolf boolf, Co public class WaveBar extends Table{ MI2Bar bar; Table table; + MCollapser collapser; public int wave; public WaveBar(){ bar = new MI2Bar(); table = new Table(); + collapser = new MCollapser(table, true).setDirection(false, true).setDuration(0.2f); + bar.clicked(() -> collapser.toggle(true)); table.setFillParent(true); table.background(Styles.black3); } - public void setup(boolean detail){ + public void setup(){ clear(); - if(detail){ - stack(bar, table).growX(); - }else{ - add(bar).growX().height(18f).minWidth(250f); - } - } - - public void setupPrev(){ - table.clear(); - buildPreview(table, wave, curSpawn); + add(bar).growX().height(18f).minWidth(250f); + row(); + add(collapser); } public void setWave(WaveData d){ wave = d.wave; - bar.clearListeners(); bar.set(() -> "Wave " + (d.wave + 1) + ": " + "(" + d.units.size + ") " + UI.formatAmount((long)d.sumHp()) + "/" + UI.formatAmount((long)(d.totalHp + d.totalShield)), () -> { if(state.wave - 1 <= d.wave && d.sumHp() <= 0f) return 1f; @@ -585,22 +555,43 @@ public void setWave(WaveData d){ }, () -> (state.wave - 1 > d.wave || d.sumHp() > 0) ? Color.scarlet : Color.darkGray); bar.blink(Color.white).outline(MI2UTmp.c2.set(0.3f, 0.3f, 0.6f, 0.3f), 1f).setFontScale(0.8f); - bar.tapped(() -> { - if(detailt.shown) detailt.hide(); - detailt.clear(); - detailt.background(Styles.black8); - detailt.addCloseButton(); - detailt.addDragMove(); - detailt.addInGameVisible(); - detailt.add("Wave " + (d.wave + 1)).growX().minSize(80f, 36f); - detailt.row(); - buildPreview(detailt, d.wave, -1); - detailt.row(); - buildDetailBars(detailt, d); - detailt.setPositionInScreen(Core.input.mouseX(), Core.input.mouseY()); - detailt.popup(); + table.clear(); + buildPreview(table, curSpawn); + } + + public void buildPreview(Table t, int spawn){ + t.table(tt -> { + int i = 0; + for(SpawnGroup group : state.rules.spawns){ + if(spawn != -1 && group.spawn != -1 && spawn != group.spawn) continue; + if(group.getSpawned(wave) < 1) continue; + tt.table(g -> { + g.table(gt -> { + gt.image(group.type.uiIcon).size(18f); + gt.add("x" + group.getSpawned(wave)).get().setFontScale(0.7f); + }); + g.row(); + g.add(String.valueOf(group.getShield(wave))).get().setFontScale(0.7f); + g.row(); + g.table(eip -> { + if(group.effect != null && group.effect != StatusEffects.none) eip.image(group.effect.uiIcon).size(12f); + if(group.items != null) eip.stack(new Image(group.items.item.uiIcon), new Label(String.valueOf(group.items.amount)){{ + this.setFillParent(true); + this.setAlignment(Align.bottomRight); + this.setFontScale(0.7f); + }}).size(12f); + if(group.payloads != null && !group.payloads.isEmpty()) eip.add("" + Iconc.units).get().setFontScale(0.7f); + if(group.spawn != -1) eip.add(Iconc.blockSpawn + "").get().clicked(() -> { + if(control.input instanceof InputOverwrite iow) iow.pan(true, MI2UTmp.v1.set(Point2.unpack(group.spawn).x, Point2.unpack(group.spawn).y).scl(tilesize)); + }); + }); + }).pad(2f); + if(++i >= 5){ + i = 0; + tt.row(); + } + } }); - setupPrev(); } } } diff --git a/src/mi2u/ui/elements/PopupTable.java b/src/mi2u/ui/elements/PopupTable.java index 1b94f32..39957d0 100644 --- a/src/mi2u/ui/elements/PopupTable.java +++ b/src/mi2u/ui/elements/PopupTable.java @@ -18,6 +18,7 @@ public class PopupTable extends Table{ public boolean shown = false; public float fromx, fromy; public float popupDuration = 0.15f; + public boolean cancelDrag; public void popup(int align){ if(shown) return; @@ -88,6 +89,7 @@ public boolean touchDown(InputEvent event, float x, float y, int pointer, KeyCod @Override public void touchDragged(InputEvent event, float x, float y, int pointer){ + if(cancelDrag) return; Vec2 v = localToStageCoordinates(MI2UTmp.v1.set(x, y)); setPositionInScreen(v.x - fromx, v.y - fromy); } From be73bb0c7389b33bb231854c90f70cfc12552e28 Mon Sep 17 00:00:00 2001 From: BlackDeluxeCat <65377021+BlackDeluxeCat@users.noreply.github.com> Date: Fri, 5 Jan 2024 16:57:42 +0800 Subject: [PATCH 10/57] detailed power bars --- src/mi2u/struct/FloatDataRecorder.java | 19 +- src/mi2u/ui/CoreInfoMindow.java | 49 +++-- src/mi2u/ui/PowerGraphTable.java | 288 +++++++++++++++++++++---- src/mi2u/ui/elements/MI2Bar.java | 4 +- 4 files changed, 285 insertions(+), 75 deletions(-) diff --git a/src/mi2u/struct/FloatDataRecorder.java b/src/mi2u/struct/FloatDataRecorder.java index fc8b5f9..e18fa17 100644 --- a/src/mi2u/struct/FloatDataRecorder.java +++ b/src/mi2u/struct/FloatDataRecorder.java @@ -4,12 +4,16 @@ import arc.graphics.g2d.Fill; import arc.graphics.g2d.Lines; import arc.math.Mathf; +import arc.util.*; import mi2u.MI2UTmp; +import java.util.*; + public class FloatDataRecorder{ private float[] values; public Floatp getter = null; - private int head = -1; + //the position of last data + private int head = 0; private int size = 0; public boolean disable = false; public Boolf disableF = null; @@ -36,15 +40,13 @@ public int size(){ public void reset(){ head = 0; size = 0; - for(int i = 0; i < values.length; i++){ - values[i] = 0f; - } + Arrays.fill(values, 0f); } public float get(int before){ if(before >= size) return size == 0 ? values[head] : values[Mathf.mod(head + 1, size)]; if(before < 0) return values[head]; - return values[head - before + (head - before < 0 ? values.length : 0)]; + return values[head - before + ((head - before) < 0 ? values.length : 0)]; } public void add(float value){ @@ -111,8 +113,11 @@ public void update(){ public void resize(int newSize){ float[] newArray = new float[newSize]; if(newSize > values.length){ - System.arraycopy(values, 0, newArray, 0, head); - System.arraycopy(values, head + 1, newArray, newSize - values.length + head + 1, values.length - head - 1); + System.arraycopy(values, 0, newArray, 0, head + 1); + System.arraycopy(values, head + 1, newArray, head + 1 + newSize - values.length, values.length - (head + 1)); + }else{ + //i don't want to make it, just clean data + head = 0; } this.values = newArray; } diff --git a/src/mi2u/ui/CoreInfoMindow.java b/src/mi2u/ui/CoreInfoMindow.java index 60082ce..b705779 100644 --- a/src/mi2u/ui/CoreInfoMindow.java +++ b/src/mi2u/ui/CoreInfoMindow.java @@ -34,7 +34,7 @@ public class CoreInfoMindow extends Mindow2{ protected CoreBuild core; protected Team select, team; - protected PowerGraphTable pg = new PowerGraphTable(330); + protected PowerGraphTable pg = new PowerGraphTable(); protected PopupTable teamSelect = new PopupTable(), buildPlanTable = new PopupTable(); protected int[] unitIndex = new int[content.units().size]; @@ -76,6 +76,9 @@ public CoreInfoMindow(){ b.getLabel().setColor(team == null ? Color.white:team.color); b.getLabel().setFontScale(0.8f); }); + teamt.button(t -> t.label(() -> Iconc.power + String.valueOf(pg.powerIOBars ? Iconc.list : Iconc.line)), textb, () -> { + pg.powerIOBars = !pg.powerIOBars; + }).growY(); }).height(titleButtonSize).growX(); itemRecoders = new FloatDataRecorder[content.items().size]; @@ -113,28 +116,30 @@ public CoreInfoMindow(){ } } }); + } - update(() -> { - if(select == null || !select.active()){ - team = player.team(); - }else{ - team = select; - } - core = team.core(); - pg.team = team; + @Override + public void act(float delta){ + if(select == null || !select.active()){ + team = player.team(); + }else{ + team = select; + } + core = team.core(); + pg.team = team; + super.act(delta); - if(state.isGame() && ((content.items().count(item -> core != null && core.items.get(item) > 0 && usedItems.add(item)) > 0) || (content.units().count(type -> team.data().countType(type) > 0 && usedUnits.add(type)) > 0))){ - rebuild(); - } + if(state.isGame() && ((content.items().count(item -> core != null && core.items.get(item) > 0 && usedItems.add(item)) > 0) || (content.units().count(type -> team.data().countType(type) > 0 && usedUnits.add(type)) > 0))){ + rebuild(); + } - if(player.unit() != null && player.unit().plans().isEmpty() && control.input.selectPlans.isEmpty() || !(this.visible && this.hasParent())){ - buildPlanTable.hide(); - buildPlanTable.clearChildren(); - }else{ - buildPlanTable.popup(); - buildPlanTable.setPositionInScreen(this.x, this.y - buildPlanTable.getPrefHeight()); - } - }); + if(player.unit() != null && player.unit().plans().isEmpty() && control.input.selectPlans.isEmpty() || !(this.visible && this.hasParent())){ + buildPlanTable.hide(); + buildPlanTable.clearChildren(); + }else{ + buildPlanTable.popup(); + buildPlanTable.setPositionInScreen(this.x, this.y - buildPlanTable.getPrefHeight()); + } } @Override @@ -190,9 +195,9 @@ public void setupCont(Table cont){ if(MI2USettings.getBool(mindowName + ".showPowerGraphs", true)){ ipt.row(); - ipt.add(pg).fillX(); + ipt.add(pg).grow(); } - }); + }).growY(); //cont.row(); diff --git a/src/mi2u/ui/PowerGraphTable.java b/src/mi2u/ui/PowerGraphTable.java index d3382c1..5b420eb 100644 --- a/src/mi2u/ui/PowerGraphTable.java +++ b/src/mi2u/ui/PowerGraphTable.java @@ -29,33 +29,40 @@ public class PowerGraphTable extends Table{ public Team team; - public float barsWidth; public PopupTable detailTable = new PopupTable(); - private Seq bars = new Seq<>(); + public final AlluvialDiagram diagram = new AlluvialDiagram(); + public boolean powerIOBars; + + //n x 6 Element array with icons and labels from generator, consumer, storage. static Element[][] blocksI = new Element[content.blocks().size][6]; private static Interval interval = new Interval(2); - private final Seq saved = new Seq<>(); - private float totalCap = 0f; + private final Seq pgInfos = new Seq<>(); + private float totalCap = 0f, totalCons = 0f, totalGen = 0f; - public PowerGraphTable(float w){ + public PowerGraphTable(){ super(); - barsWidth = w; - update(() -> { - saved.each(PGInfo::update); - if(interval.get(0, 50f)){ - rebuild(); - } - }); detailTable.touchable = Touchable.disabled; } + @Override + public void act(float delta){ + super.act(delta); + pgInfos.each(PGInfo::update); + if(interval.get(0, 50f)){ + pgInfos.each(PGInfo::updateG); + rebuild(); + } + } + public void rebuild(){ clear(); if(!state.isGame()) return; if(team == null) return; if(state.teams.get(team).buildings == null) return; totalCap = 0f; + totalCons = 0f; + totalGen = 0f; OrderedSet graphs = new OrderedSet<>(); state.teams.get(team).buildings.each(b -> { @@ -65,7 +72,7 @@ public void rebuild(){ //find and select presented graphs, //also select and renew remained graphs. So recorder data is probably get kept. //remove others. - saved.removeAll(pi -> { + pgInfos.removeAll(pi -> { final PowerGraph[] used = new PowerGraph[1]; boolean remove = !graphs.orderedItems().contains(pgn -> { if(pgn == pi.pg || (!pgn.batteries.isEmpty() && pi.pg.batteries.contains(pgn.batteries.find(Building::isValid)))){ @@ -76,34 +83,26 @@ public void rebuild(){ return false; }); if(used[0] != null) graphs.remove(used[0]); + if(remove){ + diagram.removeChild(pi.barGen); + diagram.removeChild(pi.barStore); + diagram.removeChild(pi.barCons); + Pools.free(pi); + } return remove; }); graphs.orderedItems().each(p -> { - if(!saved.contains(pp -> pp.pg == p)) saved.add(new PGInfo(p)); + if(!pgInfos.contains(pp -> pp.pg == p)) pgInfos.add(Pools.obtain(PGInfo.class, PGInfo::new).renew(p)); }); - saved.each(c -> totalCap += c.totalcap); - - int index = 0; - for(var info : saved){ - if(info.totalcap <= 0f) continue; - info.updateG(); - if(index >= bars.size) bars.add(new MI2Bar()); - - MI2Bar bar = bars.get(index); - bar.set(() -> barsWidth * info.totalcap / totalCap <= 50f ? "" : "" + UI.formatAmount((long)info.pg.getLastPowerStored()) + " " + (info.pg.getPowerBalance() >= 0 ? "+" : "") + UI.formatAmount((long)(info.pg.getPowerBalance() * 60)), () -> info.pg.getLastPowerStored() / info.totalcap, Pal.accent); - bar.blink(Color.white).outline(MI2UTmp.c2.set(0.3f, 0.3f, 0.6f, 0.3f), 2f); - - bar.clearListeners(); - bar.clicked(() -> { - if(control.input instanceof InputOverwrite iow) iow.pan(true, MI2UTmp.v1.set(info.pg.all.random())); - }); - bar.hovered(() -> showDetailFor(info, bar)); - - add(bars.get(index)).width(barsWidth * info.totalcap / totalCap).height(24f); - index++; - } + pgInfos.each(c -> { + totalCap += c.totalcap; + totalGen += c.totalgen; + totalCons += c.totalcons; + }); + setBackground(Styles.grayPanel); + add(diagram).grow(); } public void showDetailFor(PGInfo info, MI2Bar bar){ @@ -114,6 +113,7 @@ public void showDetailFor(PGInfo info, MI2Bar bar){ buildInfo(detailTable, info); detailTable.update(() -> { + if(info.pg == null) detailTable.clear(); detailTable.hideWithoutFocusOn(bar); detailTable.setPositionInScreen(Core.input.mouseX() - 20f, Core.input.mouseY() - detailTable.getPrefHeight() - 20f); }); @@ -230,10 +230,6 @@ public void draw(){ } } }); - - - - }); }); } @@ -242,26 +238,212 @@ public static Element getBlockImage(int id, int i3, Prov getter){ return blocksI[id][i3] != null ? blocksI[id][i3] : (blocksI[id][i3] = getter.get()); } - public static class PGInfo{ + public class AlluvialDiagram extends WidgetGroup{ + public AlluvialDiagram(){ + setFillParent(true); + setClip(true); + } + + @Override + public float getPrefHeight(){ + return powerIOBars ? 160f : 32f; + } + + @Override + public void draw(){ + if(!state.isGame()){ + clear(); + return; + } + + //三行放条,设置位置 + //IO条在简洁版会被裁剪掉 + float h = powerIOBars ? 24f : 32f, yc = powerIOBars ? 0f : -1000f, yg = (powerIOBars ? 0f : -1000f) + (getHeight() - h) / 2.5f, ys = getHeight() - h; + float x1 = 0f, x2 = 0f, x3 = 0f; + for(var info : pgInfos){ + addChild(info.barStore); + info.barStore.setSize(width * info.ltotalcap / totalCap, h); + info.barStore.x = x2; + x2 += info.barStore.getWidth(); + info.barStore.y = ys; + + addChild(info.barGen); + info.barGen.setSize(width * info.ltotalgen / Math.max(totalGen, totalCons), h); + info.barGen.x = x1; + x1 += info.barGen.getWidth(); + info.barGen.y = yg; + + addChild(info.barCons); + info.barCons.setSize(width * info.ltotalcons / Math.max(totalGen, totalCons), h); + info.barCons.x = x3; + x3 += info.barCons.getWidth(); + info.barCons.y = yc; + } + float dist = getHeight() / 6f; + + //对应条之间画曲线 + if(powerIOBars){ + for(var info : pgInfos){ + float fromx, fromy, tox, toy; + if(info.barStore.getWidth() < 1f && (info.barCons.getWidth() >= 1f && info.barGen.getWidth() >= 1f)){ + Draw.color(info.ltotalcons > info.ltotalgen ? Color.scarlet : Color.green, 0.5f); + Lines.stroke(2f); + fromx = info.barGen.getX(Align.center); + fromy = info.barGen.getY(Align.center); + tox = info.barCons.getX(Align.center); + toy = info.barCons.getY(Align.center); + Lines.curve(fromx, fromy, fromx, fromy - dist, tox, toy + dist, tox, toy, 8); + } + + if(info.barStore.getWidth() >= 1f){ + if(info.ltotalgen > info.ltotalcons){ + Draw.color(Pal.accent, 0.5f); + fillBetweenBars(info.barGen, 0f, info.ltotalcons/info.ltotalgen, info.barCons, 0f, 1f, dist); + fillBetweenBars(info.barStore, 0f, 1f, info.barGen, info.ltotalcons/info.ltotalgen, 1f, dist); + } + if(info.ltotalgen < info.ltotalcons){ + Draw.color(Pal.accent, 0.5f); + fillBetweenBars(info.barGen, 0f, 1f, info.barCons, 0f, info.ltotalgen/info.ltotalcons, dist); + Draw.color(Color.scarlet, 0.5f); + fillBetweenBars(info.barStore, 0f, 1f, info.barCons, info.ltotalgen/info.ltotalcons, 1f, dist); + } + } + } + } + + //画条 + super.draw(); + } + + public void fillBetweenBars(MI2Bar barUp, float upl, float upr, MI2Bar barDown, float downl, float downr, float dist){ + fillCurve(barUp.x + barUp.getWidth() * upl, barUp.getY(Align.bottom), barUp.x + barUp.getWidth() * upr, barUp.getY(Align.bottom), barDown.x + barDown.getWidth() * downl, barDown.getY(Align.top), barDown.x + barDown.getWidth() * downr, barDown.getY(Align.top), 8, dist); + } + + /** --------- + * | \ + * | \ + * / \ + * ---------------- + * */ + public static void fillCurve(float fx1, float fy1, float fx2, float fy2, float tx1, float ty1, float tx2, float ty2, float segments, float dist){ + float cfx1 = fx1, ctx1 = tx1, cfy1 = fy1 - dist, cty1 = ty1 + dist; + float cfx2 = fx2, ctx2 = tx2, cfy2 = fy2 - dist, cty2 = ty2 + dist; + + float subdiv_step = 1f / segments; + float subdiv_step2 = subdiv_step * subdiv_step; + float subdiv_step3 = subdiv_step * subdiv_step * subdiv_step; + + float pre1 = 3 * subdiv_step; + float pre2 = 3 * subdiv_step2; + float pre4 = 6 * subdiv_step2; + float pre5 = 6 * subdiv_step3; + + float tmp1x1 = fx1 - cfx1 * 2 + ctx1; + float tmp1y1 = fy1 - cfy1 * 2 + cty1; + float tmp1x2 = fx2 - cfx2 * 2 + ctx2; + float tmp1y2 = fy2 - cfy2 * 2 + cty2; + + float tmp2x1 = (cfx1 - ctx1) * 3 - fx1 + tx1; + float tmp2y1 = (cfy1 - cty1) * 3 - fy1 + ty1; + float tmp2x2 = (cfx2 - ctx2) * 3 - fx2 + tx2; + float tmp2y2 = (cfy2 - cty2) * 3 - fy2 + ty2; + + float f1x = fx1; + float f1y = fy1; + float f2x = fx2; + float f2y = fy2; + + float dfx1 = (cfx1 - fx1) * pre1 + tmp1x1 * pre2 + tmp2x1 * subdiv_step3; + float dfy1 = (cfy1 - fy1) * pre1 + tmp1y1 * pre2 + tmp2y1 * subdiv_step3; + float dfx2 = (cfx2 - fx2) * pre1 + tmp1x2 * pre2 + tmp2x2 * subdiv_step3; + float dfy2 = (cfy2 - fy2) * pre1 + tmp1y2 * pre2 + tmp2y2 * subdiv_step3; + + float ddfx1 = tmp1x1 * pre4 + tmp2x1 * pre5; + float ddfy1 = tmp1y1 * pre4 + tmp2y1 * pre5; + float ddfx2 = tmp1x2 * pre4 + tmp2x2 * pre5; + float ddfy2 = tmp1y2 * pre4 + tmp2y2 * pre5; + + float dddfx1 = tmp2x1 * pre5; + float dddfy1 = tmp2y1 * pre5; + float dddfx2 = tmp2x2 * pre5; + float dddfy2 = tmp2y2 * pre5; + + float l1x, l1y, l2x, l2y; + while(segments-- > 0){ + l1x = f1x; + l1y = f1y; + l2x = f2x; + l2y = f2y; + + f1x += dfx1; + f1y += dfy1; + dfx1 += ddfx1; + dfy1 += ddfy1; + ddfx1 += dddfx1; + ddfy1 += dddfy1; + + f2x += dfx2; + f2y += dfy2; + dfx2 += ddfx2; + dfy2 += ddfy2; + ddfx2 += dddfx2; + ddfy2 += dddfy2; + Fill.polyBegin(); + Fill.polyPoint(l1x, l1y); + Fill.polyPoint(l2x, l2y); + Fill.polyPoint(f2x, f2y); + Fill.polyPoint(f1x, f1y); + Fill.polyEnd(); + } + } + } + + public class PGInfo implements Pool.Poolable{ public PowerGraph pg; public FloatDataRecorder consG, genG, stG; public float totalcons, totalgen, totalcap; + public float ltotalcons, ltotalgen, ltotalcap; public float[] bcons = new float[blocksI.length], bgen = new float[blocksI.length], bstore = new float[blocksI.length]; public int[] blocks = new int[blocksI.length]; - public PGInfo(PowerGraph pg){ + MI2Bar barStore; + MI2Bar barGen; + MI2Bar barCons; + + public PGInfo(){ consG = new FloatDataRecorder(90); genG = new FloatDataRecorder(90); stG = new FloatDataRecorder(90); consG.getter = () -> totalcons; genG.getter = () -> totalgen; - renew(pg); + + Runnable clicked = () -> { + if(control.input instanceof InputOverwrite iow) iow.pan(true, MI2UTmp.v1.set(pg.all.random())); + }; + + barStore = new MI2Bar().blink(Color.white).outline(MI2UTmp.c2.set(0.3f, 0.3f, 0.6f, 0.3f), 2f); + barStore.clicked(clicked); + barStore.hovered(() -> showDetailFor(this, barStore)); + + barGen = new MI2Bar().blink(Color.white).outline(MI2UTmp.c2.set(0.3f, 0.3f, 0.6f, 0.3f), 2f); + barGen.set(() -> barGen.getWidth() <= 50f ? "" : "+" + UI.formatAmount((long)totalgen), () -> 1f, Pal.items); + barGen.clicked(clicked); + barGen.hovered(() -> showDetailFor(this, barGen)); + + barCons = new MI2Bar().blink(Color.white).outline(MI2UTmp.c2.set(0.3f, 0.3f, 0.6f, 0.3f), 2f); + barCons.set(() -> barCons.getWidth() <= 50f ? "" : "-" + UI.formatAmount((long)totalcons), () -> 1f, Pal.health); + barCons.clicked(clicked); + barCons.hovered(() -> showDetailFor(this, barCons)); } - public void renew(PowerGraph pg){ + public PGInfo renew(PowerGraph pg){ this.pg = pg; + + barStore.set(() -> barStore.getWidth() <= 50f ? "" : UI.formatAmount((long)pg.getLastPowerStored()) + (barStore.getWidth() <= 100f ? "" : (" " + (pg.getPowerBalance() >= 0 ? "+" : "") + UI.formatAmount((long)(pg.getPowerBalance() * 60)))), () -> pg.getLastPowerStored() / totalcap, Pal.accent); + update(); stG.getter = pg::getBatteryStored; + return this; } public boolean vaild(){ @@ -286,6 +468,10 @@ public void update(){ totalcons += bcons[i]; totalgen += bgen[i]; } + + ltotalcap = Mathf.lerp(ltotalcap, totalcap, 0.5f); + ltotalgen = Mathf.lerp(ltotalgen, totalgen, 0.5f); + ltotalcons = Mathf.lerp(ltotalcons, totalcons, 0.5f); } public void updateG(){ @@ -293,5 +479,21 @@ public void updateG(){ genG.update(); stG.update(); } + + @Override + public void reset(){ + pg = null; + Arrays.fill(blocks, 0); + Arrays.fill(bcons, 0); + Arrays.fill(bgen, 0); + Arrays.fill(bstore, 0); + totalcons = totalcap = totalgen = 0; + genG.reset(); + genG.resize(90); + consG.reset(); + consG.resize(90); + stG.reset(); + stG.resize(90); + } } } diff --git a/src/mi2u/ui/elements/MI2Bar.java b/src/mi2u/ui/elements/MI2Bar.java index 4f6c082..a99b1a4 100644 --- a/src/mi2u/ui/elements/MI2Bar.java +++ b/src/mi2u/ui/elements/MI2Bar.java @@ -42,9 +42,7 @@ public MI2Bar(Prov name, Prov color, Floatp fraction){ }); } - public MI2Bar(){ - - } + public MI2Bar(){} public void reset(float value){ this.value = lastValue = blink = value; From aafd58f9ccb1ec1e800c922569080b3dfb8eeab7 Mon Sep 17 00:00:00 2001 From: BlackDeluxeCat <65377021+BlackDeluxeCat@users.noreply.github.com> Date: Fri, 5 Jan 2024 16:57:49 +0800 Subject: [PATCH 11/57] 1.5.2 --- mod.hjson | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mod.hjson b/mod.hjson index 2e579d1..5af68e0 100644 --- a/mod.hjson +++ b/mod.hjson @@ -5,7 +5,7 @@ displayName: "MI2-Utilities Java" name: "mi2-utilities-java" #the mod version -version: 1.5.1b +version: 1.5.2 #the minimum game build required to run this mod minGameVersion: 146 From ac0793b9e442c88bb413150a33bee4160b957189 Mon Sep 17 00:00:00 2001 From: BlackDeluxeCat <65377021+BlackDeluxeCat@users.noreply.github.com> Date: Sat, 6 Jan 2024 01:44:03 +0800 Subject: [PATCH 12/57] fixed empty power net table, smoother digits --- assets/bundles/bundle.properties | 15 ++++++++------- assets/bundles/bundle_zh_CN.properties | 15 ++++++++------- src/mi2u/ui/PowerGraphTable.java | 17 +++++++++-------- 3 files changed, 25 insertions(+), 22 deletions(-) diff --git a/assets/bundles/bundle.properties b/assets/bundles/bundle.properties index a56164c..054e7a7 100644 --- a/assets/bundles/bundle.properties +++ b/assets/bundles/bundle.properties @@ -32,15 +32,16 @@ mapInfo.buttons.expand = Expand mapInfo.buttons.fold = Fold mapInfo.view = View -mapInfo.buildingHpMutil = BHp -mapInfo.buildingDamageMutil = BDmg +mapInfo.buildingHpMulti = BHp +mapInfo.buildingDamageMulti = BDmg mapInfo.unitHealthMultiplier = UHp -mapInfo.unitDamageMutil = UDmg +mapInfo.unitDamageMulti = UDmg mapInfo.unitCrashDamageMultiplier = UCrash -mapInfo.buildCostMutil = BCost -mapInfo.buildSpeedMutil = BSpd -mapInfo.buildRefundMutil = BRe -mapInfo.unitConstructSpeedMutil = USpd +mapInfo.buildCostMulti = BCost +mapInfo.buildSpeedMulti = BSpd +mapInfo.buildRefundMulti = BRe +mapInfo.unitConstructSpeedMulti = USpd +mapInfo.unitCostMulti = UCost mapInfo.wave = Wave {0} mapInfo.team = Team mapInfo.infAmmo = Inf Ammo diff --git a/assets/bundles/bundle_zh_CN.properties b/assets/bundles/bundle_zh_CN.properties index 0389017..0fd3242 100644 --- a/assets/bundles/bundle_zh_CN.properties +++ b/assets/bundles/bundle_zh_CN.properties @@ -32,15 +32,16 @@ mapInfo.buttons.expand = 展开 mapInfo.buttons.fold = 折叠 mapInfo.view = 显示 -mapInfo.buildingHpMutil = 建筑血量 -mapInfo.buildingDamageMutil = 建筑伤害 +mapInfo.buildingHpMulti = 建筑血量 +mapInfo.buildingDamageMulti = 建筑伤害 mapInfo.unitHealthMultiplier = 单位血量 -mapInfo.unitDamageMutil = 单位伤害 +mapInfo.unitDamageMulti = 单位伤害 mapInfo.unitCrashDamageMultiplier = 单位坠毁伤害 -mapInfo.buildCostMutil = 建造耗材 -mapInfo.buildSpeedMutil = 建造速度 -mapInfo.buildRefundMutil = 拆除返还 -mapInfo.unitConstructSpeedMutil = 单位构造速度 +mapInfo.buildCostMulti = 建造耗材 +mapInfo.buildSpeedMulti = 建造速度 +mapInfo.buildRefundMulti = 拆除返还 +mapInfo.unitConstructSpeedMulti = 单位构造速度 +mapInfo.unitCostMulti = 单位构造耗材 mapInfo.wave = 波次 {0} mapInfo.team = 队伍 mapInfo.infAmmo = 无限弹药 diff --git a/src/mi2u/ui/PowerGraphTable.java b/src/mi2u/ui/PowerGraphTable.java index 5b420eb..b4a70e7 100644 --- a/src/mi2u/ui/PowerGraphTable.java +++ b/src/mi2u/ui/PowerGraphTable.java @@ -246,7 +246,7 @@ public AlluvialDiagram(){ @Override public float getPrefHeight(){ - return powerIOBars ? 160f : 32f; + return powerIOBars ? 160f : totalCap < 1f ? 0f : 32f; } @Override @@ -260,21 +260,22 @@ public void draw(){ //IO条在简洁版会被裁剪掉 float h = powerIOBars ? 24f : 32f, yc = powerIOBars ? 0f : -1000f, yg = (powerIOBars ? 0f : -1000f) + (getHeight() - h) / 2.5f, ys = getHeight() - h; float x1 = 0f, x2 = 0f, x3 = 0f; + float maxIO = Math.max(totalGen, totalCons); for(var info : pgInfos){ addChild(info.barStore); - info.barStore.setSize(width * info.ltotalcap / totalCap, h); + info.barStore.setSize(totalCap < 10f ? 0f : width * info.ltotalcap / totalCap, h); info.barStore.x = x2; x2 += info.barStore.getWidth(); info.barStore.y = ys; addChild(info.barGen); - info.barGen.setSize(width * info.ltotalgen / Math.max(totalGen, totalCons), h); + info.barGen.setSize(maxIO < 0.1f ? 0f : (width * info.ltotalgen / maxIO), h); info.barGen.x = x1; x1 += info.barGen.getWidth(); info.barGen.y = yg; addChild(info.barCons); - info.barCons.setSize(width * info.ltotalcons / Math.max(totalGen, totalCons), h); + info.barCons.setSize(maxIO < 0.1f ? 0f : (width * info.ltotalcons / maxIO), h); info.barCons.x = x3; x3 += info.barCons.getWidth(); info.barCons.y = yc; @@ -285,7 +286,7 @@ public void draw(){ if(powerIOBars){ for(var info : pgInfos){ float fromx, fromy, tox, toy; - if(info.barStore.getWidth() < 1f && (info.barCons.getWidth() >= 1f && info.barGen.getWidth() >= 1f)){ + if(info.totalcap < 10f && (info.barCons.getWidth() >= 1f && info.barGen.getWidth() >= 1f)){ Draw.color(info.ltotalcons > info.ltotalgen ? Color.scarlet : Color.green, 0.5f); Lines.stroke(2f); fromx = info.barGen.getX(Align.center); @@ -469,9 +470,9 @@ public void update(){ totalgen += bgen[i]; } - ltotalcap = Mathf.lerp(ltotalcap, totalcap, 0.5f); - ltotalgen = Mathf.lerp(ltotalgen, totalgen, 0.5f); - ltotalcons = Mathf.lerp(ltotalcons, totalcons, 0.5f); + ltotalcap = Mathf.lerp(ltotalcap, totalcap, 0.2f); + ltotalgen = Mathf.lerp(ltotalgen, totalgen, 0.2f); + ltotalcons = Mathf.lerp(ltotalcons, totalcons, 0.2f); } public void updateG(){ From dffbe3a94a9658d4515dcbf9d1de16cf95cdbd92 Mon Sep 17 00:00:00 2001 From: BlackDeluxeCat <65377021+BlackDeluxeCat@users.noreply.github.com> Date: Sat, 6 Jan 2024 01:45:23 +0800 Subject: [PATCH 13/57] fixed wave preview didn't checkout spawnpoint also add more map rules --- src/mi2u/ui/MapInfoTable.java | 53 ++++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 22 deletions(-) diff --git a/src/mi2u/ui/MapInfoTable.java b/src/mi2u/ui/MapInfoTable.java index 4c0371d..c33e1ee 100644 --- a/src/mi2u/ui/MapInfoTable.java +++ b/src/mi2u/ui/MapInfoTable.java @@ -169,25 +169,30 @@ public MapInfoTable(){ p.popup(); p.snapTo(b); p.background(Styles.grayPanel).margin(10f); + p.defaults().size(70f, 32f); int i = 0; int cols = 4; for(var spawn : WorldData.usedSpawns){ int x = Point2.x(spawn), y = Point2.y(spawn); p.button(x + ", " + y, Styles.flatTogglet, () -> { + boolean rebuild = curSpawn != spawn; curSpawn = spawn; + if(rebuild) hpBars.each(WaveBar::buildPreview); b.setText(Iconc.blockSpawn + ": " + x + ", " + y); p.hide(); - }).size(50, 32f).checked(spawn == curSpawn); + }).checked(spawn == curSpawn); if(++i % cols == 0) p.row(); } p.button("@waves.spawn.all", Styles.flatTogglet, () -> { + boolean rebuild = curSpawn != -1; curSpawn = -1; + if(rebuild) hpBars.each(WaveBar::buildPreview); b.setText(Iconc.blockSpawn + Core.bundle.get("waves.spawn.all")); p.hide(); - }).size(50f, 32f).checked(-1 == curSpawn); + }).checked(-1 == curSpawn); }); }); }).growX().row(); @@ -267,6 +272,7 @@ public void buildBars(Table t){ } //single wave details + //TODO for future use public void buildDetailBars(Table t, WaveData data){ t.pane(p -> { for(int id = 0; id < data.totalsByType.length; id++){ @@ -442,15 +448,16 @@ public void setupDetailAttsInfo(){ t.table(tt -> { tt.defaults().left(); - addFloatAttr(() -> Strings.fixed(state.rules.buildCostMultiplier, 2), "@mapInfo.buildCostMutil", tt); - addFloatAttr(() -> Strings.fixed(state.rules.deconstructRefundMultiplier, 2), "@mapInfo.buildRefundMutil", tt); - addFloatAttr(() -> Strings.fixed(state.rules.blockHealthMultiplier, 2), "@mapInfo.buildingHpMutil", tt); - addFloatAttr(() -> Strings.fixed(state.rules.blockDamageMultiplier, 2), "@mapInfo.buildingDamageMutil", tt); - addFloatAttr(() -> Strings.fixed(state.rules.buildSpeedMultiplier, 2), "@mapInfo.buildSpeedMutil", tt); + addFloatAttr(() -> Strings.fixed(state.rules.buildCostMultiplier, 2), "@mapInfo.buildCostMulti", tt); + addFloatAttr(() -> Strings.fixed(state.rules.blockHealthMultiplier, 2), "@mapInfo.buildingHpMulti", tt); + addFloatAttr(() -> Strings.fixed(state.rules.blockDamageMultiplier, 2), "@mapInfo.buildingDamageMulti", tt); + addFloatAttr(() -> Strings.fixed(state.rules.buildSpeedMultiplier, 2), "@mapInfo.buildSpeedMulti", tt); + addFloatAttr(() -> Strings.fixed(state.rules.unitBuildSpeedMultiplier, 2), "@mapInfo.unitConstructSpeedMulti", tt); + addFloatAttr(() -> Strings.fixed(state.rules.unitCostMultiplier, 2), "@mapInfo.unitCostMulti", tt); addFloatAttr(() -> Strings.fixed(state.rules.unitHealthMultiplier, 2), "@mapInfo.unitHealthMultiplier", tt); - addFloatAttr(() -> Strings.fixed(state.rules.unitDamageMultiplier, 2), "@mapInfo.unitDamageMutil", tt); + addFloatAttr(() -> Strings.fixed(state.rules.unitDamageMultiplier, 2), "@mapInfo.unitDamageMulti", tt); addFloatAttr(() -> Strings.fixed(state.rules.unitCrashDamageMultiplier, 2), "@mapInfo.unitCrashDamageMultiplier", tt); - addFloatAttr(() -> Strings.fixed(state.rules.unitBuildSpeedMultiplier, 2), "@mapInfo.unitConstructSpeedMutil", tt); + addFloatAttr(() -> Strings.fixed(state.rules.deconstructRefundMultiplier, 2), "@mapInfo.buildRefundMulti", tt); addFloatAttr(() -> Strings.fixed(state.rules.solarMultiplier, 2), "@mapInfo.solarMulti", tt); }); @@ -458,13 +465,14 @@ public void setupDetailAttsInfo(){ t.table(teamt -> { teamt.add("@mapInfo.team").padLeft(5).padRight(5); - teamt.add("@mapInfo.unitConstructSpeedMutil").padLeft(5).padRight(5); + teamt.add("@mapInfo.buildingHpMulti").padLeft(5).padRight(5); + teamt.add("@mapInfo.buildingDamageMulti").padLeft(5).padRight(5); + teamt.add("@mapInfo.buildSpeedMulti").padLeft(5).padRight(5); + teamt.add("@mapInfo.unitConstructSpeedMulti").padLeft(5).padRight(5); + teamt.add("@mapInfo.unitCostMulti").padLeft(5).padRight(5); teamt.add("@mapInfo.unitHealthMultiplier").padLeft(5).padRight(5); - teamt.add("@mapInfo.unitDamageMutil").padLeft(5).padRight(5); + teamt.add("@mapInfo.unitDamageMulti").padLeft(5).padRight(5); teamt.add("@mapInfo.unitCrashDamageMultiplier").padLeft(5).padRight(5); - teamt.add("@mapInfo.buildingHpMutil").padLeft(5).padRight(5); - teamt.add("@mapInfo.buildingDamageMutil").padLeft(5).padRight(5); - teamt.add("@mapInfo.buildSpeedMutil").padLeft(5).padRight(5); teamt.add("@mapInfo.infAmmo").padLeft(5).padRight(5); teamt.add("@mapInfo.infRes").padLeft(5).padRight(5); teamt.add("@mapInfo.cheat").padLeft(5).padRight(5); @@ -474,13 +482,14 @@ public void setupDetailAttsInfo(){ teamt.row(); var teamRule = state.rules.teams.get(teamData.team); teamt.add("[#" + teamData.team.color + "]" + teamData.team.localized()); + teamt.add(String.valueOf(teamRule.blockHealthMultiplier)).color(teamData.team.color); + teamt.add(String.valueOf(teamRule.blockDamageMultiplier)).color(teamData.team.color); + teamt.add(String.valueOf(teamRule.buildSpeedMultiplier)).color(teamData.team.color); teamt.add(String.valueOf(teamRule.unitBuildSpeedMultiplier)).color(teamData.team.color); + teamt.add(String.valueOf(teamRule.unitCostMultiplier)).color(teamData.team.color); teamt.add(String.valueOf(teamRule.unitHealthMultiplier)).color(teamData.team.color); teamt.add(String.valueOf(teamRule.unitDamageMultiplier)).color(teamData.team.color); teamt.add(String.valueOf(teamRule.unitCrashDamageMultiplier)).color(teamData.team.color); - teamt.add(String.valueOf(teamRule.blockHealthMultiplier)).color(teamData.team.color); - teamt.add(String.valueOf(teamRule.blockDamageMultiplier)).color(teamData.team.color); - teamt.add(String.valueOf(teamRule.buildSpeedMultiplier)).color(teamData.team.color); teamt.add(String.valueOf(teamRule.infiniteAmmo)).color(teamData.team.color); teamt.add(String.valueOf(teamRule.infiniteResources)).color(teamData.team.color); teamt.add(String.valueOf(teamRule.cheat)).color(teamData.team.color); @@ -555,15 +564,15 @@ public void setWave(WaveData d){ }, () -> (state.wave - 1 > d.wave || d.sumHp() > 0) ? Color.scarlet : Color.darkGray); bar.blink(Color.white).outline(MI2UTmp.c2.set(0.3f, 0.3f, 0.6f, 0.3f), 1f).setFontScale(0.8f); - table.clear(); - buildPreview(table, curSpawn); + buildPreview(); } - public void buildPreview(Table t, int spawn){ - t.table(tt -> { + public void buildPreview(){ + table.clear(); + table.table(tt -> { int i = 0; for(SpawnGroup group : state.rules.spawns){ - if(spawn != -1 && group.spawn != -1 && spawn != group.spawn) continue; + if(curSpawn != -1 && group.spawn != -1 && curSpawn != group.spawn) continue; if(group.getSpawned(wave) < 1) continue; tt.table(g -> { g.table(gt -> { From b87638d4f373dc6dc6072124f8b483d9016c1b6c Mon Sep 17 00:00:00 2001 From: BlackDeluxeCat <65377021+BlackDeluxeCat@users.noreply.github.com> Date: Sat, 6 Jan 2024 01:45:32 +0800 Subject: [PATCH 14/57] 1.5.2b --- mod.hjson | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mod.hjson b/mod.hjson index 5af68e0..a3065d3 100644 --- a/mod.hjson +++ b/mod.hjson @@ -5,7 +5,7 @@ displayName: "MI2-Utilities Java" name: "mi2-utilities-java" #the mod version -version: 1.5.2 +version: 1.5.2b #the minimum game build required to run this mod minGameVersion: 146 From fa411ce6ffd726a7ed9f25994f411fd7c8e3f432 Mon Sep 17 00:00:00 2001 From: BlackDeluxeCat <65377021+BlackDeluxeCat@users.noreply.github.com> Date: Wed, 10 Jan 2024 15:16:09 +0800 Subject: [PATCH 15/57] fixed blockSelectTableHeight --- src/mi2u/ModifyFuncs.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mi2u/ModifyFuncs.java b/src/mi2u/ModifyFuncs.java index 2815873..91ef908 100644 --- a/src/mi2u/ModifyFuncs.java +++ b/src/mi2u/ModifyFuncs.java @@ -156,7 +156,7 @@ public static void betterTopTable(){ if(MI2USettings.getBool("modifyBlockSelectTable", false)){ Table blockCatTable = MI2Utils.getValue(ui.hudfrag.blockfrag, "blockCatTable"); - ((Table)blockCatTable.getCells().first().get()).getCells().first().maxHeight(Mathf.clamp(MI2USettings.getInt("blockSelectTableHeight", 194), 50, 1000)); + ((Table)blockCatTable.getCells().first().get()).getCells().first().height(Mathf.clamp(MI2USettings.getInt("blockSelectTableHeight", 194), 50, 1000)); blockCatTable.getCells().get(1).height(Mathf.clamp(MI2USettings.getInt("blockSelectTableHeight", 194) + 52, 50, 1000)); } } From 585b4f5a9bd9e36cf86e0ffc242d7c4cc62b92f5 Mon Sep 17 00:00:00 2001 From: BlackDeluxeCat <65377021+BlackDeluxeCat@users.noreply.github.com> Date: Wed, 10 Jan 2024 15:16:50 +0800 Subject: [PATCH 16/57] tweaked power flow diagram --- src/mi2u/ui/CoreInfoMindow.java | 5 ++- src/mi2u/ui/PowerGraphTable.java | 63 +++++++++++++++++--------------- 2 files changed, 36 insertions(+), 32 deletions(-) diff --git a/src/mi2u/ui/CoreInfoMindow.java b/src/mi2u/ui/CoreInfoMindow.java index b705779..a2a39e2 100644 --- a/src/mi2u/ui/CoreInfoMindow.java +++ b/src/mi2u/ui/CoreInfoMindow.java @@ -78,6 +78,7 @@ public CoreInfoMindow(){ }); teamt.button(t -> t.label(() -> Iconc.power + String.valueOf(pg.powerIOBars ? Iconc.list : Iconc.line)), textb, () -> { pg.powerIOBars = !pg.powerIOBars; + pg.diagram.clearChildren(); }).growY(); }).height(titleButtonSize).growX(); @@ -195,9 +196,9 @@ public void setupCont(Table cont){ if(MI2USettings.getBool(mindowName + ".showPowerGraphs", true)){ ipt.row(); - ipt.add(pg).grow(); + ipt.add(pg).growX().minWidth(300f); } - }).growY(); + }).grow(); //cont.row(); diff --git a/src/mi2u/ui/PowerGraphTable.java b/src/mi2u/ui/PowerGraphTable.java index b4a70e7..d888bd2 100644 --- a/src/mi2u/ui/PowerGraphTable.java +++ b/src/mi2u/ui/PowerGraphTable.java @@ -49,7 +49,7 @@ public PowerGraphTable(){ public void act(float delta){ super.act(delta); pgInfos.each(PGInfo::update); - if(interval.get(0, 50f)){ + if(interval.get(0, 60f)){ pgInfos.each(PGInfo::updateG); rebuild(); } @@ -101,8 +101,8 @@ public void rebuild(){ totalGen += c.totalgen; totalCons += c.totalcons; }); - setBackground(Styles.grayPanel); - add(diagram).grow(); + setBackground(Styles.black5); + add(diagram).growX(); } public void showDetailFor(PGInfo info, MI2Bar bar){ @@ -239,6 +239,7 @@ public static Element getBlockImage(int id, int i3, Prov getter){ } public class AlluvialDiagram extends WidgetGroup{ + MI2Utils.IntervalMillis timer = new MI2Utils.IntervalMillis(); public AlluvialDiagram(){ setFillParent(true); setClip(true); @@ -257,31 +258,34 @@ public void draw(){ } //三行放条,设置位置 - //IO条在简洁版会被裁剪掉 - float h = powerIOBars ? 24f : 32f, yc = powerIOBars ? 0f : -1000f, yg = (powerIOBars ? 0f : -1000f) + (getHeight() - h) / 2.5f, ys = getHeight() - h; - float x1 = 0f, x2 = 0f, x3 = 0f; - float maxIO = Math.max(totalGen, totalCons); - for(var info : pgInfos){ - addChild(info.barStore); - info.barStore.setSize(totalCap < 10f ? 0f : width * info.ltotalcap / totalCap, h); - info.barStore.x = x2; - x2 += info.barStore.getWidth(); - info.barStore.y = ys; - - addChild(info.barGen); - info.barGen.setSize(maxIO < 0.1f ? 0f : (width * info.ltotalgen / maxIO), h); - info.barGen.x = x1; - x1 += info.barGen.getWidth(); - info.barGen.y = yg; - - addChild(info.barCons); - info.barCons.setSize(maxIO < 0.1f ? 0f : (width * info.ltotalcons / maxIO), h); - info.barCons.x = x3; - x3 += info.barCons.getWidth(); - info.barCons.y = yc; + //IO条在简洁版会被移除 + if(timer.get(400)){ + float h = powerIOBars ? 24f : 32f, yc = 0f, yg = (getHeight() - h) / 2.5f, ys = getHeight() - h; + float x1 = 0f, x2 = 0f, x3 = 0f; + float maxIO = Math.max(totalGen, totalCons); + for(var info : pgInfos){ + addChild(info.barStore); + info.barStore.setSize(totalCap < 10f ? 0f : width * info.ltotalcap / totalCap, h); + info.barStore.x = x2; + x2 += info.barStore.getWidth(); + info.barStore.y = ys; + + if(!powerIOBars) continue; + addChild(info.barGen); + info.barGen.setSize(maxIO < 0.1f ? 0f : (width * info.ltotalgen / maxIO), h); + info.barGen.x = x1; + x1 += info.barGen.getWidth(); + info.barGen.y = yg; + + addChild(info.barCons); + info.barCons.setSize(maxIO < 0.1f ? 0f : (width * info.ltotalcons / maxIO), h); + info.barCons.x = x3; + x3 += info.barCons.getWidth(); + info.barCons.y = yc; + } } - float dist = getHeight() / 6f; + float dist = getHeight() / 6f; //对应条之间画曲线 if(powerIOBars){ for(var info : pgInfos){ @@ -469,10 +473,9 @@ public void update(){ totalcons += bcons[i]; totalgen += bgen[i]; } - - ltotalcap = Mathf.lerp(ltotalcap, totalcap, 0.2f); - ltotalgen = Mathf.lerp(ltotalgen, totalgen, 0.2f); - ltotalcons = Mathf.lerp(ltotalcons, totalcons, 0.2f); + ltotalcap = Mathf.lerp(ltotalcap, totalcap, 0.9f); + ltotalgen = Mathf.lerp(ltotalgen, totalgen, 0.9f); + ltotalcons = Mathf.lerp(ltotalcons, totalcons, 0.9f); } public void updateG(){ From 6cc127590b377fe030444e1eae2fc772564dd14c Mon Sep 17 00:00:00 2001 From: BlackDeluxeCat <65377021+BlackDeluxeCat@users.noreply.github.com> Date: Wed, 10 Jan 2024 16:59:08 +0800 Subject: [PATCH 17/57] max schematic size --- src/mi2u/MI2Utilities.java | 5 ++++- src/mi2u/ui/MI2UI.java | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/mi2u/MI2Utilities.java b/src/mi2u/MI2Utilities.java index c8403bf..d89e618 100644 --- a/src/mi2u/MI2Utilities.java +++ b/src/mi2u/MI2Utilities.java @@ -55,7 +55,10 @@ public MI2Utilities(){ MI2USettings.init(); InputUtils.init(); - maxSchematicSize = MI2USettings.getInt("maxSchematicSize", 64); + //anyone need max size < vanilla size, open an issue on Github + maxSchematicSize = Math.max(maxSchematicSize, MI2USettings.getInt("maxSchematicSize", 64)); + MI2USettings.putInt("maxSchematicSize", maxSchematicSize); + renderer.maxZoom = Strings.parseFloat(MI2USettings.getStr("maxZoom", "6")); renderer.minZoom = Strings.parseFloat(MI2USettings.getStr("minZoom", "1.5")); diff --git a/src/mi2u/ui/MI2UI.java b/src/mi2u/ui/MI2UI.java index 571003b..3a9f2df 100644 --- a/src/mi2u/ui/MI2UI.java +++ b/src/mi2u/ui/MI2UI.java @@ -364,10 +364,10 @@ public void initSettings(){ if(b) MI2Utilities.checkUpdate(); })); - settings.add(new FieldEntry("maxSchematicSize", "@settings.main.maxSchematicSize", String.valueOf(32), TextField.TextFieldFilter.digitsOnly, s -> Strings.parseInt(s) >= 16 && Strings.parseInt(s) <= 512, s -> Vars.maxSchematicSize = Mathf.clamp(Strings.parseInt(s), 16, 512))); + settings.add(new FieldEntry("maxSchematicSize", "@settings.main.maxSchematicSize", String.valueOf(64), TextField.TextFieldFilter.digitsOnly, s -> Strings.parseInt(s) >= 16 && Strings.parseInt(s) <= 1919810, s -> Vars.maxSchematicSize = Mathf.clamp(Strings.parseInt(s), 16, 1919810))); //zoom in - settings.add(new FieldEntry("maxZoom", "@settings.main.maxZoom", String.valueOf(renderer.maxZoom), TextField.TextFieldFilter.floatsOnly, s -> Strings.parseFloat(s) > renderer.minZoom && Strings.parseFloat(s) <= 60, s -> renderer.maxZoom = Strings.parseFloat(s))); + settings.add(new FieldEntry("maxZoom", "@settings.main.maxZoom", String.valueOf(renderer.maxZoom), TextField.TextFieldFilter.floatsOnly, s -> Strings.parseFloat(s) > renderer.minZoom && Strings.parseFloat(s) <= 100, s -> renderer.maxZoom = Strings.parseFloat(s))); //zoom out settings.add(new FieldEntry("minZoom", "@settings.main.minZoom", String.valueOf(renderer.minZoom), TextField.TextFieldFilter.floatsOnly, s -> Strings.parseFloat(s) < renderer.maxZoom && Strings.parseFloat(s) > 0.01f, s -> renderer.minZoom = Strings.parseFloat(s))); From b0f9e84964a11ef66b0acdaead56ca6e520d9def Mon Sep 17 00:00:00 2001 From: BlackDeluxeCat <65377021+BlackDeluxeCat@users.noreply.github.com> Date: Wed, 10 Jan 2024 16:59:13 +0800 Subject: [PATCH 18/57] Update CoreInfoMindow.java --- src/mi2u/ui/CoreInfoMindow.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mi2u/ui/CoreInfoMindow.java b/src/mi2u/ui/CoreInfoMindow.java index a2a39e2..ee6e461 100644 --- a/src/mi2u/ui/CoreInfoMindow.java +++ b/src/mi2u/ui/CoreInfoMindow.java @@ -71,7 +71,7 @@ public CoreInfoMindow(){ rebuildSelect(); teamSelect.popup(); teamSelect.snapTo(this); - }).grow().update(b -> { + }).grow().minWidth(32f).update(b -> { b.setText(team.localized() + (select == null ? Core.bundle.get("coreInfo.selectButton.playerteam"):"")); b.getLabel().setColor(team == null ? Color.white:team.color); b.getLabel().setFontScale(0.8f); From 800074deb62a9b29d4a4a9407bd444d4f5f347bb Mon Sep 17 00:00:00 2001 From: BlackDeluxeCat <65377021+BlackDeluxeCat@users.noreply.github.com> Date: Wed, 10 Jan 2024 16:59:48 +0800 Subject: [PATCH 19/57] better window snapping --- src/mi2u/ui/elements/Mindow2.java | 77 ++++++++++++++++--------------- 1 file changed, 41 insertions(+), 36 deletions(-) diff --git a/src/mi2u/ui/elements/Mindow2.java b/src/mi2u/ui/elements/Mindow2.java index fad9882..cdad86c 100644 --- a/src/mi2u/ui/elements/Mindow2.java +++ b/src/mi2u/ui/elements/Mindow2.java @@ -49,7 +49,7 @@ public class Mindow2 extends Table{ protected Table titleBar = new Table(), titlePane = new Table(Styles.black6); protected Table cont = new Table(); protected Seq settings = new Seq<>(); - protected MI2Utils.IntervalMillis interval = new MI2Utils.IntervalMillis(2); + protected MI2Utils.IntervalMillis interval = new MI2Utils.IntervalMillis(3); public int edgesnap = Align.center; @Nullable public Mindow2 tbSnap, lrSnap; public int tbSnapAlign, lrSnapAlign; @@ -120,7 +120,7 @@ public void setupTitle(){ toast.setBackground(titleBarbgNormal); titleBar.add(new MCollapser(toast, true).setCollapsed(true, () -> { - if(titleCfg && interval.check(0, 10000)) titleCfg = false; + if(titleCfg && interval.check(0, 5000)) titleCfg = false; return !titleCfg && !minimized; }).setDirection(true, true).setDuration(0.2f)); @@ -132,50 +132,54 @@ public void setupTitle(){ titleBar.button(b -> b.label(() -> "" + (resizing ? Iconc.resize : Iconc.move)), textb, () -> { titleCfg = !titleCfg; interval.get(0,0); - }).size(titleButtonSize).get().addListener(new InputListener(){ - Vec2 tmpv = new Vec2(); - @Override - public boolean touchDown(InputEvent event, float x, float y, int pointer, KeyCode button){ - fromx = x; - fromy = y; - tmpv.set(curx, cury); - return true; - } + }).size(titleButtonSize).with(b -> { + b.addListener(new InputListener(){ + Vec2 tmpv = new Vec2(); + @Override + public boolean touchDown(InputEvent event, float x, float y, int pointer, KeyCode button){ + fromx = x; + fromy = y; + tmpv.set(curx, cury); + return true; + } - @Override - public void touchDragged(InputEvent event, float x, float y, int pointer){ - Vec2 v = localToStageCoordinates(MI2UTmp.v1.set(x, y)); - dragging = MI2UTmp.v2.set(v).sub(fromx, fromy).sub(tmpv).len() > 5f; - if(resizing){ - curw = Mathf.clamp(v.x - getX(left), 50f, 800f); - curh = Mathf.clamp(v.y - getY(bottom), 50f, 800f); - }else{ - curx = v.x; - cury = v.y; - setSnap(v.x, v.y); + @Override + public void touchDragged(InputEvent event, float x, float y, int pointer){ + Vec2 v = localToStageCoordinates(MI2UTmp.v1.set(x, y)).sub(fromx, fromy); + dragging = MI2UTmp.v2.set(v).sub(tmpv).len() > 5f; + if(resizing){ + curw = Mathf.clamp(v.x - getX(left), 50f, 800f); + curh = Mathf.clamp(v.y - getY(bottom), 50f, 800f); + }else{ + curx = v.x; + cury = v.y; + setSnap(v.x, v.y); + } } - } - @Override - public void touchUp(InputEvent event, float x, float y, int pointer, KeyCode button){ - super.touchUp(event, x, y, pointer, button); - if(!dragging) interval.get(0, 0); - dragging = false; - Mindow2.this.toFront(); - saveUISettings(); - } + @Override + public void touchUp(InputEvent event, float x, float y, int pointer, KeyCode button){ + super.touchUp(event, x, y, pointer, button); + if(!dragging) interval.get(0, 0); + dragging = false; + Mindow2.this.toFront(); + saveUISettings(); + } + }); }); } @Override public void act(float delta){ super.act(delta); - boolean slideAnime = edgeSnap(edgesnap); - slideAnime = slideAnime | elementSnap(tbSnap, tbSnapAlign, lrSnap == null && !Align.isLeft(edgesnap) && !Align.isRight(edgesnap)); - slideAnime = slideAnime | elementSnap(lrSnap, lrSnapAlign, tbSnap == null && !Align.isBottom(edgesnap) && !Align.isTop(edgesnap)); - if(slideAnime) interval.get(1, 0); + if(interval.get(1, 300)){ + boolean slideAnime = edgeSnap(edgesnap); + slideAnime = slideAnime | elementSnap(tbSnap, tbSnapAlign, lrSnap == null && !Align.isLeft(edgesnap) && !Align.isRight(edgesnap)); + slideAnime = slideAnime | elementSnap(lrSnap, lrSnapAlign, tbSnap == null && !Align.isBottom(edgesnap) && !Align.isTop(edgesnap)); + if(slideAnime && MI2UTmp.v1.set(curx, cury).sub(x, y).len() >= 3f) interval.reset(2, 0); + } - if(!interval.check(1, 400)){ + if(!interval.check(2, 400)){ setPosition(Mathf.lerp(x, curx, 0.4f), Mathf.lerp(y, cury, 0.4f)); }else{ setPosition(curx, cury); @@ -311,6 +315,7 @@ public void setSnap(float mindowX, float mindowY){ }; } testSnaps(); + interval.reset(1, 10000); } public void testSnaps(){ From ec009b79c1d5d09e135000e88b36ccc6451ac897 Mon Sep 17 00:00:00 2001 From: BlackDeluxeCat <65377021+BlackDeluxeCat@users.noreply.github.com> Date: Wed, 10 Jan 2024 16:59:55 +0800 Subject: [PATCH 20/57] Update EmojiMindow.java --- src/mi2u/ui/EmojiMindow.java | 40 ++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/src/mi2u/ui/EmojiMindow.java b/src/mi2u/ui/EmojiMindow.java index f9ddc64..106e6bf 100644 --- a/src/mi2u/ui/EmojiMindow.java +++ b/src/mi2u/ui/EmojiMindow.java @@ -39,24 +39,26 @@ public EmojiMindow() { try{ map.clear(); Field[] fs = Iconc.class.getFields(); - - tmpindex = 0; for(Field f : fs){ if(f.getType() == char.class){ map.put(f.getName(), Reflect.get(Iconc.class, f) + ""); - var emoji = map.get(f.getName()); - tablet.button(emoji, textb, () -> { - Core.app.setClipboardText(emoji); - }).with(funcSetTextb).get().getLabel().setFontScale(1.5f); - if(++tmpindex > 8){ - tablet.row(); - tmpindex = 0; - } } } - var keyseq = map.keys().toSeq(); keyseq.sort(); + + tmpindex = 0; + for(var name : keyseq){ + var emoji = map.get(name); + tablet.button(emoji, textb, () -> { + Core.app.setClipboardText(emoji); + }).with(funcSetTextb).get().getLabel().setFontScale(1.5f); + if(++tmpindex > 8){ + tablet.row(); + tmpindex = 0; + } + } + keyseq.each(name -> { listt.button(name, textbStyle, () -> { Core.app.setClipboardText(name); @@ -68,22 +70,24 @@ public EmojiMindow() { listt.row(); }); }catch(Exception ignore){Log.err(ignore);} - } - @Override - public void setupCont(Table cont){ - cont.clear(); - cont.table(t -> { + titlePane.table(t -> { t.button("" + Iconc.list, textbtoggle, () -> { listMode = !listMode; rebuild(); }).height(titleButtonSize).update(b -> { b.setChecked(listMode); }).growX(); + }).grow().minWidth(32f); + } - t.row(); + @Override + public void setupCont(Table cont){ + cont.clear(); + cont.table(t -> { + //TODO search bar - t.pane(listMode ? listt : tablet).maxHeight(Core.graphics.getHeight() / 3).growX().update(p -> { + t.pane(listMode ? listt : tablet).maxHeight(Core.graphics.getHeight() / 3f).growX().update(p -> { Element e = Core.scene.hit(Core.input.mouseX(), Core.input.mouseY(), true); if(e != null && e.isDescendantOf(p)){ p.requestScroll(); From 23d197d07831e8be34dd4c15c27730104630c8eb Mon Sep 17 00:00:00 2001 From: BlackDeluxeCat <65377021+BlackDeluxeCat@users.noreply.github.com> Date: Wed, 10 Jan 2024 17:00:11 +0800 Subject: [PATCH 21/57] wave table init height --- src/mi2u/ui/MapInfoTable.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/mi2u/ui/MapInfoTable.java b/src/mi2u/ui/MapInfoTable.java index c33e1ee..246112c 100644 --- a/src/mi2u/ui/MapInfoTable.java +++ b/src/mi2u/ui/MapInfoTable.java @@ -198,10 +198,10 @@ public MapInfoTable(){ }).growX().row(); final float[] h = new float[1]; - h[0] = Core.graphics.getHeight()*0.5f/Scl.scl(); + h[0] = 300f; wavesPopup.pane(t -> barsTable = t).fillX().self(c -> { c.update(p -> { - h[0] = Mathf.clamp(h[0], 10f, (Core.graphics.getHeight() - 200f)/Scl.scl()); + h[0] = Mathf.clamp(h[0], 20f, (Core.graphics.getHeight() - 400f)/Scl.scl()); c.height(h[0]); Element e = Core.scene.hit(Core.input.mouseX(), Core.input.mouseY(), true); if(e != null && e.isDescendantOf(p)){ @@ -550,7 +550,7 @@ public WaveBar(){ public void setup(){ clear(); - add(bar).growX().height(18f).minWidth(250f); + add(bar).growX().height(24f).minWidth(250f); row(); add(collapser); } From 13f42a2e96d1bf912026516937a206157fe8963a Mon Sep 17 00:00:00 2001 From: BlackDeluxeCat <65377021+BlackDeluxeCat@users.noreply.github.com> Date: Wed, 10 Jan 2024 17:00:26 +0800 Subject: [PATCH 22/57] mini map setting --- src/mi2u/ui/MinimapMindow.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mi2u/ui/MinimapMindow.java b/src/mi2u/ui/MinimapMindow.java index 61ee2cc..da7403a 100644 --- a/src/mi2u/ui/MinimapMindow.java +++ b/src/mi2u/ui/MinimapMindow.java @@ -143,8 +143,8 @@ public void initSettings(){ settings.add(new CheckEntry(mindowName + ".drawIndicator", "@settings.mindowMap.drawIndicator", true, b -> m.drawIndicator = b)); settings.add(new CheckEntry(mindowName + ".drawObjective", "@settings.mindowMap.drawObjective", true, b -> m.drawObjective = b)); settings.add(new FieldEntry(mindowName + ".size", "@settings.mindowMap.size", String.valueOf(140), TextField.TextFieldFilter.digitsOnly, s -> Strings.canParseInt(s) && Strings.parseInt(s) >= 100 && Strings.parseInt(s) <= 3200, s -> rebuild())); - settings.add(new FieldEntry(mindowName + ".drawUnitColorDiff", "@settings.mindowMap.drawUnitColorDiff", String.valueOf(10), TextField.TextFieldFilter.digitsOnly, s -> Strings.canParseInt(s) && Strings.parseInt(s) >= 1 && Strings.parseInt(s) <= 100, s -> m.drawUnitColorDifference = MI2USettings.getInt(mindowName + ".drawUnitColorDiff", 90) / 100f)); - settings.add(new FieldEntry(mindowName + ".drawUnitOutline", "@settings.mindowMap.drawUnitOutline", String.valueOf(0), TextField.TextFieldFilter.digitsOnly, s -> Strings.canParseInt(s) && Strings.parseInt(s) >= 1 && Strings.parseInt(s) <= 100, s -> m.drawUnitOutline = MI2USettings.getInt(mindowName + ".drawUnitOutline", 90) / 100f)); + settings.add(new FieldEntry(mindowName + ".drawUnitColorDiff", "@settings.mindowMap.drawUnitColorDiff", String.valueOf(10), TextField.TextFieldFilter.digitsOnly, s -> Strings.canParseInt(s) && Strings.parseInt(s) >= 0 && Strings.parseInt(s) <= 100, s -> m.drawUnitColorDifference = MI2USettings.getInt(mindowName + ".drawUnitColorDiff", 90) / 100f)); + settings.add(new FieldEntry(mindowName + ".drawUnitOutline", "@settings.mindowMap.drawUnitOutline", String.valueOf(0), TextField.TextFieldFilter.digitsOnly, s -> Strings.canParseInt(s) && Strings.parseInt(s) >= 0 && Strings.parseInt(s) <= 100, s -> m.drawUnitOutline = MI2USettings.getInt(mindowName + ".drawUnitOutline", 90) / 100f)); settings.add(new FieldEntry("worldDataUpdate.tiles", "@settings.mindowMap.worldDataUpdate.tiles", String.valueOf(50), TextField.TextFieldFilter.digitsOnly, s -> Strings.canParseInt(s) && Strings.parseInt(s) >= 10 && Strings.parseInt(s) <= 10000, null)); } From 14de66fe5f5251c9738c4f08feba691b037b37e0 Mon Sep 17 00:00:00 2001 From: BlackDeluxeCat <65377021+BlackDeluxeCat@users.noreply.github.com> Date: Wed, 10 Jan 2024 17:51:09 +0800 Subject: [PATCH 23/57] Update build.gradle --- build.gradle | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index f2a473a..01137b6 100644 --- a/build.gradle +++ b/build.gradle @@ -29,9 +29,9 @@ allprojects{ } dependencies{ - compileOnly "com.github.Anuken.Arc:arc-core:$mindustryVersion" - compileOnly "com.github.Anuken.Mindustry:core:$mindustryVersion" - annotationProcessor "com.github.Anuken:jabel:$jabelVersion" + compileOnly "com.github.anuken.arc:arc-core:$mindustryVersion" + compileOnly "com.github.anuken.mindustry:core:$mindustryVersion" + annotationProcessor "com.github.anuken:jabel:$jabelVersion" } task jarAndroid{ From 5f6c64051a7b573702f4616ad89776c08acbf875 Mon Sep 17 00:00:00 2001 From: BlackDeluxeCat <65377021+BlackDeluxeCat@users.noreply.github.com> Date: Wed, 10 Jan 2024 17:55:37 +0800 Subject: [PATCH 24/57] Update build.gradle --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 01137b6..edaae43 100644 --- a/build.gradle +++ b/build.gradle @@ -29,8 +29,8 @@ allprojects{ } dependencies{ - compileOnly "com.github.anuken.arc:arc-core:$mindustryVersion" - compileOnly "com.github.anuken.mindustry:core:$mindustryVersion" + compileOnly "com.github.anuken.Arc:arc-core:$mindustryVersion" + compileOnly "com.github.anuken.Mindustry:core:$mindustryVersion" annotationProcessor "com.github.anuken:jabel:$jabelVersion" } From 2d1cac9c99b6c129928d058f5c18157ad50f4567 Mon Sep 17 00:00:00 2001 From: BlackDeluxeCat <65377021+BlackDeluxeCat@users.noreply.github.com> Date: Wed, 10 Jan 2024 18:17:11 +0800 Subject: [PATCH 25/57] Update build.gradle --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index edaae43..2efe558 100644 --- a/build.gradle +++ b/build.gradle @@ -30,8 +30,8 @@ allprojects{ dependencies{ compileOnly "com.github.anuken.Arc:arc-core:$mindustryVersion" - compileOnly "com.github.anuken.Mindustry:core:$mindustryVersion" - annotationProcessor "com.github.anuken:jabel:$jabelVersion" + compileOnly "com.github.Anuken.Mindustry:core:$mindustryVersion" + annotationProcessor "com.github.Anuken:jabel:$jabelVersion" } task jarAndroid{ From 1343aa73f7d71bb8c9855a11092f5ccc35a562ee Mon Sep 17 00:00:00 2001 From: BlackDeluxeCat <65377021+BlackDeluxeCat@users.noreply.github.com> Date: Thu, 11 Jan 2024 18:12:12 +0800 Subject: [PATCH 26/57] drown bar --- src/mi2u/graphics/RendererExt.java | 54 ++++++++++++++++-------------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/src/mi2u/graphics/RendererExt.java b/src/mi2u/graphics/RendererExt.java index e0cedb7..51ffa9a 100644 --- a/src/mi2u/graphics/RendererExt.java +++ b/src/mi2u/graphics/RendererExt.java @@ -235,7 +235,6 @@ public static void drawUnit(Unit unit){ if(enUnitHitbox){ Draw.color(unit.team.color, 0.6f); - //Lines.rect(unit.x - unit.hitSize / 2f, unit.y - unit.hitSize / 2f, unit.hitSize, unit.hitSize); float size = 14f; Lines.beginLine(); @@ -374,23 +373,26 @@ public static void drawUnitPath(Unit unit, int pathId, Vec2 destination){ } public static void drawUnitHpBar(Unit unit){ - float width = 1.2f, halfwidth = width / 2f; - if(unit.shield > Math.min(0.5f * unit.maxHealth, 100f) || !enUnitHpBarDamagedOnly || unit.damaged()){ - if(unit.hitTime > 0f){ - Lines.stroke(4f + Mathf.lerp(0f, 2f, unit.hitTime)); - Draw.color(Color.white, Mathf.lerp(0.1f, 1f, unit.hitTime)); - Lines.line(unit.x - unit.hitSize * halfwidth, unit.y + (unit.hitSize / 2f), unit.x + unit.hitSize * halfwidth, unit.y + (unit.hitSize / 2f)); - } - + float width = 1.2f, hhitsize = unit.hitSize / 2f; + float uwidth = unit.hitSize * width, uhwidth = uwidth / 2f; + if(unit.shield > Math.min(0.5f * unit.maxHealth, 100f) || !enUnitHpBarDamagedOnly || unit.damaged() || unit.drownTime > 0f){ Lines.stroke(4f); - Draw.color(unit.team.color, 0.5f); - Lines.line(unit.x - unit.hitSize * halfwidth, unit.y + (unit.hitSize / 2f), unit.x + unit.hitSize * halfwidth, unit.y + (unit.hitSize / 2f)); + Draw.color(MI2UTmp.c1.set(unit.team.color).lerp(Color.white, Mathf.clamp(unit.hitTime)), Mathf.lerp(0.5f, 1f, Mathf.clamp(unit.hitTime))); + Lines.line(unit.x - uhwidth, unit.y + hhitsize, unit.x + uhwidth, unit.y + hhitsize); Draw.color((unit.health > 0 ? Pal.health:Color.gray), 0.8f); Lines.stroke(2); Lines.line( - unit.x - unit.hitSize * halfwidth, unit.y + (unit.hitSize / 2f), - unit.x + unit.hitSize * ((unit.health > 0 ? unit.health : Mathf.maxZero(unit.maxHealth + unit.health)) / unit.maxHealth * width - halfwidth), unit.y + (unit.hitSize / 2f)); + unit.x - uhwidth, unit.y + hhitsize, + unit.x - uhwidth + uwidth * (unit.health > 0 ? unit.health : Mathf.maxZero(unit.maxHealth + unit.health)) / unit.maxHealth, unit.y + hhitsize); + + if(unit.drownTime > 0f){ + Draw.color(Color.royal, 0.5f); + Lines.stroke(2); + Lines.line( + unit.x - uhwidth, unit.y + hhitsize, + unit.x - uhwidth + uwidth * unit.drownTime, unit.y + hhitsize); + } if(unit.shield > 0){ if(unitHpBarStyle.equals("1")){ @@ -398,17 +400,17 @@ public static void drawUnitHpBar(Unit unit){ Draw.color(Pal.shield, 0.8f); float barLength = Mathf.mod(unit.shield / unit.maxHealth, Mathf.pow(10f, (float)didgt - 1f)) / Mathf.pow(10f, (float)didgt - 1f); if(didgt > 1){ - float y = unit.y + unit.hitSize / 2f + didgt * 2f; + float y = unit.y + hhitsize + didgt * 2f; float h = 2f; int counts = Mathf.floor(barLength * 10f); for(float i = 1; i <= counts; i++){ Fill.rect(unit.x - 0.55f * unit.hitSize + (i - 1f) * 0.12f * unit.hitSize, y, 0.1f * unit.hitSize, h); } }else{ - float x = unit.x - (1f - barLength) * halfwidth * unit.hitSize; - float y = unit.y + unit.hitSize / 2f + didgt * 2f; + float x = unit.x - (1f - barLength) * uhwidth; + float y = unit.y + hhitsize + didgt * 2f; float h = 2f; - float w = width * barLength * unit.hitSize; + float w = uwidth * barLength; Fill.rect(x, y, w, h); } } @@ -416,9 +418,9 @@ public static void drawUnitHpBar(Unit unit){ Draw.color(Pal.shield, 0.8f); Lines.stroke(2); Lines.line( - unit.x - unit.hitSize * halfwidth, unit.y + (unit.hitSize / 2f), - unit.x + unit.hitSize * (Mathf.mod(unit.shield / unit.maxHealth, 1f) * width - halfwidth), unit.y + (unit.hitSize / 2f)); - if(unit.shield > unit.maxHealth) drawText("x" + Mathf.floor(unit.shield / unit.maxHealth), unit.x + unit.hitSize * halfwidth - 4f, unit.y + (unit.hitSize / 2f), Pal.shield, 1f, Align.left); + unit.x - uhwidth, unit.y + hhitsize, + unit.x - uhwidth + uwidth * Mathf.mod(unit.shield / unit.maxHealth, 1f), unit.y + hhitsize); + if(unit.shield > unit.maxHealth) drawText("x" + Mathf.floor(unit.shield / unit.maxHealth), unit.x + uhwidth - 4f, unit.y + hhitsize, Pal.shield, 1f, Align.left); } } @@ -426,14 +428,14 @@ public static void drawUnitHpBar(Unit unit){ } float index = 0f; - int columns = Mathf.floor(unit.hitSize * width / 4f); + int columns = Mathf.floor(uwidth / 4f); for(StatusEffect eff : content.statusEffects()){ if(eff == StatusEffects.none) continue; if(unit.hasEffect(eff)){ Draw.alpha(unit.getDuration(eff) < 180f ? 0.3f + 0.7f * Math.abs(Mathf.sin(Time.time / 20f)) : 1f); Draw.rect(eff.uiIcon, - unit.x - unit.hitSize * halfwidth + 2f + 4f * Mathf.mod(index, columns), - unit.y + (unit.hitSize / 2f) + 3f + 5f * Mathf.floor(index / columns), + unit.x - uhwidth + 2f + 4f * Mathf.mod(index, columns), + unit.y + hhitsize + 3f + 5f * Mathf.floor(index / columns), eff.uiIcon.width / (float)eff.uiIcon.height * 5f, 5f); index++; } @@ -442,13 +444,13 @@ public static void drawUnitHpBar(Unit unit){ if(unit instanceof PayloadUnit pu && pu.payloads != null){ Draw.alpha(0.9f); //the smaller pui is, the further payload is in drop list. And those further ones can be slightly covered. - float fullIconCells = width * unit.hitSize / pu.payloads.size < 6f ? Mathf.floor(unit.hitSize * width * 0.5f / 6f) : 100f; + float fullIconCells = uwidth / pu.payloads.size < 6f ? Mathf.floor(uwidth * 0.5f / 6f) : 100f; for(int pui = 0; pui < pu.payloads.size; pui++){ var p = pu.payloads.get(pu.payloads.size - 1 - pui); if(p == null) continue; Draw.rect(p.icon(), - unit.x + (1f + (pui > fullIconCells ? unit.hitSize * -halfwidth + fullIconCells * 6f + (pui - fullIconCells) * (unit.hitSize * width - fullIconCells * 6f) / (pu.payloads.size - fullIconCells) : unit.hitSize * -halfwidth + pui * 6f)), - unit.y + (unit.hitSize / 2f) - 4f, + unit.x + (1f + (pui > fullIconCells ? -uhwidth + fullIconCells * 6f + (pui - fullIconCells) * (uwidth - fullIconCells * 6f) / (pu.payloads.size - fullIconCells) : -uhwidth + pui * 6f)), + unit.y + hhitsize - 4f, 6f, 6f); } } From 725c1a9852e38a86ebc091db2fb6c2ffc4db8ee4 Mon Sep 17 00:00:00 2001 From: BlackDeluxeCat <65377021+BlackDeluxeCat@users.noreply.github.com> Date: Thu, 11 Jan 2024 18:12:33 +0800 Subject: [PATCH 27/57] logic editor auto complete --- src/mi2u/ui/LogicHelperMindow.java | 214 ++++++++++++++++++++++++----- 1 file changed, 178 insertions(+), 36 deletions(-) diff --git a/src/mi2u/ui/LogicHelperMindow.java b/src/mi2u/ui/LogicHelperMindow.java index 97fc1de..4f730b7 100644 --- a/src/mi2u/ui/LogicHelperMindow.java +++ b/src/mi2u/ui/LogicHelperMindow.java @@ -4,14 +4,17 @@ import arc.func.Boolf; import arc.func.Cons; import arc.graphics.Color; +import arc.input.*; import arc.math.Interp; import arc.math.Mathf; import arc.scene.*; import arc.scene.actions.Actions; import arc.scene.actions.TemporalAction; +import arc.scene.event.*; import arc.scene.ui.TextField; import arc.scene.ui.layout.Table; import arc.struct.*; +import arc.struct.Queue; import arc.util.*; import mi2u.*; import mi2u.ui.elements.*; @@ -27,13 +30,15 @@ public class LogicHelperMindow extends Mindow2{ public Mode mode; + public LogicDialog targetLogicDialog; + LExecutor exec = null, lastexec = null; + Seq vars = new Seq<>(); public Table varsBaseTable; public Table varsTable; - TextField f; - LExecutor exec = null, lastexec = null; public String split = ""; public int depth = 6; + PopupTable autoFillVarTable; public Table searchBaseTable; public String keyWord = "", replace = ""; @@ -53,6 +58,139 @@ public class LogicHelperMindow extends Mindow2{ public LogicHelperMindow(){ super("LogicHelper", "@logicHelper.MI2U", "@logicHelper.help"); mode = Mode.vars; + setTargetDialog(ui.logic); + + autoFillVarTable = new PopupTable(){ + TextField field; + String last = ""; + Table buttons; + MI2Utils.IntervalMillis timer = new MI2Utils.IntervalMillis(); + int tabIndex = 0; + boolean hasKey = false, hasMouse = false; + { + Core.scene.addListener(new InputListener(){ + @Override + public boolean keyDown(InputEvent event, KeyCode keycode){ + if(field != null && keycode == KeyCode.tab){ + if(hasKey){ + field.setFocusTraversal(false); + Core.scene.setKeyboardFocus(field); + field.setCursorPosition(field.getText().length()); + Time.run(2f, () -> field.setFocusTraversal(true)); + }else{ + Core.scene.setKeyboardFocus(autoFillVarTable); + tabIndex = 0; + } + } + return super.keyDown(event, keycode); + } + }); + touchable = Touchable.enabled; + background(Styles.black5); + visible(() -> { + hasKey = hasKeyboard(); + hasMouse = hasMouse(); + if(timer.get(300)){ + if(!hasKey){ + if(targetLogicDialog != null && Core.scene.getKeyboardFocus() instanceof TextField f && targetLogicDialog.isAscendantOf(f)){ + field = f; + }else{ + field = null; + } + } + } + + if(field != null){ + var v = field.localToStageCoordinates(MI2UTmp.v1.setZero()); + setPosition(v.x, v.y, Align.bottomRight); + keepInScreen(); + setZIndex(1000); + if(!last.equals(field.getText())){ + last = field.getText(); + build(); + } + } + return field != null; + }); + + addListener(new InputListener(){ + @Override + public boolean keyDown(InputEvent event, KeyCode keycode){ + if(buttons.getChildren().size > 0){ + if(keycode == KeyCode.up) tabIndex = Mathf.mod(--tabIndex, buttons.getChildren().size); + if(keycode == KeyCode.down) tabIndex = Mathf.mod(++tabIndex, buttons.getChildren().size); + if(field != null && keycode == KeyCode.enter){ + tabIndex = Mathf.mod(tabIndex, buttons.getChildren().size); + buttons.getCells().get(tabIndex).get().fireClick(); + Core.scene.setKeyboardFocus(field); + field.setCursorPosition(field.getText().length()); + } + } + return super.keyDown(event, keycode); + } + }); + } + + void build(){ + clearChildren(); + pane(t -> { + buttons = t; + String input = field.getText(); + t.defaults().left().growX().minWidth(100f); + int mimi = 0; + try{ + if(!split.equals("")){ + int blockIndex = Strings.count(input, split); + var inputBlocks = input.split(cookSplit(split), depth); + ObjectSet used = new ObjectSet<>(); + varsfor : for(var v : vars){ + if(Strings.count(v, split) < blockIndex) continue; + var varBlocks = v.split(cookSplit(split), depth); + if(blockIndex > 0){ + for(int i = 0; i < blockIndex; i++){ + if(!inputBlocks[i].equals(varBlocks[i])) continue varsfor; + } + } + if(varBlocks[blockIndex].equals(inputBlocks[blockIndex]) || !varBlocks[blockIndex].startsWith(inputBlocks[blockIndex])) continue; + if(used.add(varBlocks[blockIndex])){ + int finalMimi = mimi++; + t.add(varBlocks[blockIndex]).with(l -> { + l.clicked(() -> { + var str = Strings.join(split, new Seq<>(false, varBlocks, 0, blockIndex + 1)); + field.setText(str); + field.change(); + }); + l.hovered(() -> tabIndex = finalMimi); + l.update(() -> l.setColor(tabIndex == finalMimi && (hasKey || hasMouse) ? Color.acid : varBlocks.length >= blockIndex + 1 ? Color.royal : Color.white)); + }); + t.row(); + } + } + }else{ + for(var v : vars){ + if(!v.startsWith(input)) continue; + int finalMimi1 = mimi++; + t.add(v).with(l -> { + l.clicked(() -> { + field.setText(v); + field.change(); + }); + l.hovered(() -> tabIndex = finalMimi1); + l.update(() -> l.setColor(tabIndex == finalMimi1 && (hasKey || hasMouse) ? Color.acid : Color.white)); + }); + t.row(); + } + } + }catch(Exception ignored){} + }).minWidth(100f).maxWidth(200f).maxHeight(300f).with(sp -> { + sp.setScrollingDisabledX(true); + sp.setFadeScrollBars(true); + sp.setupFadeScrollBars(0.5f, 0.5f); + }); + } + }; + autoFillVarTable.popup(Align.topLeft); + varsBaseTable = new Table(); varsTable = new Table(); searchBaseTable = new Table(); @@ -62,13 +200,20 @@ public LogicHelperMindow(){ setupSearchMode(searchBaseTable); setupCutPasteMode(cutPasteBaseTable); setupBackupMode(backupTable); + } - update(() -> { - var canvas = parent instanceof LogicDialog ld ? ld.canvas : null; - if(canvas != null && backupTimer.get(0, 60000)){ - backup(canvas.save()); - } - }); + @Override + public void act(float delta){ + super.act(delta); + if(targetLogicDialog.canvas != null && backupTimer.get(0, 60000)){ + backup(targetLogicDialog.canvas.save()); + } + + + } + + public void setTargetDialog(LogicDialog ld){ + targetLogicDialog = ld; } @Override @@ -116,9 +261,8 @@ public void setupBackupMode(Table cont){ t.image().color(Color.pink).width(2f).growY(); t.button(Iconc.save + "Backup Now", textb, () -> { - var canvas = parent instanceof LogicDialog ld ? ld.canvas : null; - if(canvas == null) return; - backup(canvas.save()); + if(targetLogicDialog.canvas == null) return; + backup(targetLogicDialog.canvas.save()); }).update(tb -> { tb.getLabel().setWrap(false); tb.setText(Iconc.save + Core.bundle.get("logichelper.backup.backupIn") + Strings.fixed(60 - backupTimer.getTime(0) / 1000f, 1)); @@ -135,10 +279,9 @@ public void setupBackupMode(Table cont){ backups.each(str -> { t.labelWrap(str.substring(0, Math.min(str.length(), 30))).fontScale(0.5f).growX(); t.button("" + Iconc.redo, textb, () -> { - var canvas = parent instanceof LogicDialog ld ? ld.canvas : null; - if(canvas == null) return; + if(targetLogicDialog.canvas == null) return; //backup(canvas.save()); - canvas.load(str); + targetLogicDialog.canvas.load(str); }).size(32f); t.row(); }); @@ -185,14 +328,14 @@ public void setupCutPasteMode(Table cont){ t.row(); - t.button("||| " + Iconc.play + " |||", textb, this::doCutPaste).with(funcSetTextb).height(36f).disabled(tb -> !(parent instanceof LogicDialog ld && cutStart < ld.canvas.statements.getChildren().size && cutEnd < ld.canvas.statements.getChildren().size && pasteStart <= ld.canvas.statements.getChildren().size && cutEnd >= cutStart)).colspan(2); + t.button("||| " + Iconc.play + " |||", textb, this::doCutPaste).with(funcSetTextb).height(36f).disabled(tb -> !(targetLogicDialog != null && cutStart < targetLogicDialog.canvas.statements.getChildren().size && cutEnd < targetLogicDialog.canvas.statements.getChildren().size && pasteStart <= targetLogicDialog.canvas.statements.getChildren().size && cutEnd >= cutStart)).colspan(2); }); } public void doCutPaste(){ - var stats = parent instanceof LogicDialog ld ? ld.canvas.statements : null; + var stats = targetLogicDialog != null ? targetLogicDialog.canvas.statements : null; if(stats == null) return; int times = cutEnd - cutStart + 1; int ind = 0; @@ -315,8 +458,8 @@ public void setupSearchMode(Table cont){ } private void doSearch(){ - if(!keyWord.equals("") && parent instanceof LogicDialog ld){ - if(ld.canvas.pane.getWidget() instanceof Table ldt){ + if(!keyWord.equals("") && targetLogicDialog != null){ + if(targetLogicDialog.canvas.pane.getWidget() instanceof Table ldt){ results.clear(); ldt.getChildren().each(e -> deepSelect(e, e2 -> e2 instanceof TextField tf && findMatch(keyWord, tf.getText()) != null)); } @@ -349,14 +492,14 @@ private void deepSelect(Element e, Boolf pred){ } private void locateElement(Cons cons){ - if(results.any() && parent instanceof LogicDialog ld){ - if(results.remove(rem -> !rem.isDescendantOf(ld))) doSearch(); //if remove works, probably lstatement is changed || lcanvas is rebuilt, so previous TextFields are invalid anymore. + if(results.any() && targetLogicDialog != null){ + if(results.remove(rem -> !rem.isDescendantOf(targetLogicDialog))) doSearch(); //if remove works, probably lstatement is changed || lcanvas is rebuilt, so previous TextFields are invalid anymore. if(index >= results.size) index = 0; if(index < 0) index = results.size - 1; Element e = results.get(index); - e.localToAscendantCoordinates(ld.canvas.pane.getWidget(), MI2UTmp.v2.setZero()); + e.localToAscendantCoordinates(targetLogicDialog.canvas.pane.getWidget(), MI2UTmp.v2.setZero()); //may not fit UI scaling config - ld.canvas.pane.setScrollPercentY(1 - (MI2UTmp.v2.y-0.5f*ld.canvas.pane.getScrollHeight())/(ld.canvas.pane.getWidget().getPrefHeight()-ld.canvas.pane.getScrollHeight())); + targetLogicDialog.canvas.pane.setScrollPercentY(1 - (MI2UTmp.v2.y-0.5f*targetLogicDialog.canvas.pane.getScrollHeight())/(targetLogicDialog.canvas.pane.getWidget().getPrefHeight()-targetLogicDialog.canvas.pane.getScrollHeight())); blinkElement(e); if(e instanceof TextField tf) { tf.requestKeyboard(); @@ -379,16 +522,19 @@ public void setupVarsMode(Table cont){ cont.table(t -> { t.clear(); t.table(tt -> { - f = tt.field(split, Styles.nodeField, s -> { + tt.field(split, Styles.nodeField, s -> { split = s; rebuildVars(varsTable); - }).fillX().get(); - f.setMessageText("@logicHelper.splitField.msg"); + }).fillX().with(f -> { + f.setMessageText("@logicHelper.splitField.msg"); + }); }); t.row(); - t.pane(varsTable).growX().maxHeight(Core.graphics.getHeight() / 3f); + t.pane(varsTable).growX().self(c -> { + c.maxHeight(Core.graphics.getHeight() / 3f); + }); }).growX(); cont.update(() -> { @@ -406,12 +552,12 @@ public void setupVarsMode(Table cont){ private void rebuildVars(Table tt){ if(exec != null){ tt.clear(); + vars.clear(); + new Seq<>(exec.vars).each(v -> {if(!v.constant && !v.name.startsWith("___")) this.vars.add(v.name);}); + Sort.instance().sort(vars); + if(!split.equals("")){ - Seq seq = new Seq<>(); - new Seq<>(exec.vars).each(v -> {if(!v.constant && !v.name.startsWith("___")) seq.add(v.name);}); - Sort.instance().sort(seq); - - seq.each(s -> { + vars.each(s -> { tt.button("" + Iconc.paste, textb, () -> Core.app.setClipboardText(s)).size(36,24); String[] blocks = s.split(cookSplit(split), depth); @@ -428,11 +574,7 @@ private void rebuildVars(Table tt){ tt.row(); }); }else{ - Seq seq = new Seq<>(); - new Seq<>(exec.vars).each(v -> seq.add(v.name)); - Sort.instance().sort(seq); - - seq.each(s -> { + vars.each(s -> { tt.button(s, textb, () -> Core.app.setClipboardText(s)).growX().get().getLabel().setAlignment(Align.left); tt.row(); }); From 1ee7c53dd5004942131602434283b77c26e09470 Mon Sep 17 00:00:00 2001 From: BlackDeluxeCat <65377021+BlackDeluxeCat@users.noreply.github.com> Date: Thu, 11 Jan 2024 22:52:46 +0800 Subject: [PATCH 28/57] =?UTF-8?q?=E9=80=BB=E8=BE=91=E8=87=AA=E5=8A=A8?= =?UTF-8?q?=E8=A1=A5=E5=85=A8=E4=BC=98=E5=8C=96=EF=BC=8C=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E6=9F=A5=E6=89=BE=E5=AE=9A=E4=BD=8D=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/bundles/bundle.properties | 1 + assets/bundles/bundle_zh_CN.properties | 1 + src/mi2u/ui/LogicHelperMindow.java | 119 ++++++++++++++++--------- 3 files changed, 81 insertions(+), 40 deletions(-) diff --git a/assets/bundles/bundle.properties b/assets/bundles/bundle.properties index 054e7a7..bf72181 100644 --- a/assets/bundles/bundle.properties +++ b/assets/bundles/bundle.properties @@ -156,6 +156,7 @@ settings.mindowMap.drawUnitColorDiff = Unit Color Difference settings.mindowMap.drawUnitOutline = Unit Outline settings.mindowMap.size = Minimap Size(Def=140) settings.mindowMap.worldDataUpdate.tiles = Space-Scan World Tiles Update Per Tick +settings.logicHelper.autocomplete = Autocomplete mindow2.helpInfoTitle = Help mindow2.uiHelp = Mindow2 is a lite window developed by MI2U.\ diff --git a/assets/bundles/bundle_zh_CN.properties b/assets/bundles/bundle_zh_CN.properties index 0fd3242..2207a00 100644 --- a/assets/bundles/bundle_zh_CN.properties +++ b/assets/bundles/bundle_zh_CN.properties @@ -156,6 +156,7 @@ settings.mindowMap.drawUnitColorDiff = 单位图标色差 settings.mindowMap.drawUnitOutline = 单位描边 settings.mindowMap.size = 小地图尺寸(原版=140) settings.mindowMap.worldDataUpdate.tiles = 天眼查世界数据每帧更新格数 +settings.logicHelper.autocomplete = 自动补全 mindow2.helpInfoTitle = 帮助信息 mindow2.uiHelp = Mindow2是MI2U开发的简易窗体。\ diff --git a/src/mi2u/ui/LogicHelperMindow.java b/src/mi2u/ui/LogicHelperMindow.java index 4f730b7..eb5b702 100644 --- a/src/mi2u/ui/LogicHelperMindow.java +++ b/src/mi2u/ui/LogicHelperMindow.java @@ -1,6 +1,6 @@ package mi2u.ui; -import arc.Core; +import arc.*; import arc.func.Boolf; import arc.func.Cons; import arc.graphics.Color; @@ -11,12 +11,14 @@ import arc.scene.actions.Actions; import arc.scene.actions.TemporalAction; import arc.scene.event.*; -import arc.scene.ui.TextField; +import arc.scene.ui.*; import arc.scene.ui.layout.Table; import arc.struct.*; import arc.struct.Queue; import arc.util.*; import mi2u.*; +import mi2u.game.*; +import mi2u.io.*; import mi2u.ui.elements.*; import mindustry.gen.Iconc; import mindustry.logic.LCanvas; @@ -64,19 +66,23 @@ public LogicHelperMindow(){ TextField field; String last = ""; Table buttons; - MI2Utils.IntervalMillis timer = new MI2Utils.IntervalMillis(); + ScrollPane pane; + MI2Utils.IntervalMillis timer = new MI2Utils.IntervalMillis(3); int tabIndex = 0; boolean hasKey = false, hasMouse = false; { Core.scene.addListener(new InputListener(){ @Override public boolean keyDown(InputEvent event, KeyCode keycode){ - if(field != null && keycode == KeyCode.tab){ + if(field != null && keycode == KeyCode.tab && MI2USettings.getBool(mindowName + ".autocomplete", true)){ if(hasKey){ field.setFocusTraversal(false); Core.scene.setKeyboardFocus(field); field.setCursorPosition(field.getText().length()); - Time.run(2f, () -> field.setFocusTraversal(true)); + Time.run(2f, () -> { + if(field == null) return; + field.setFocusTraversal(true); + }); }else{ Core.scene.setKeyboardFocus(autoFillVarTable); tabIndex = 0; @@ -116,21 +122,43 @@ public boolean keyDown(InputEvent event, KeyCode keycode){ addListener(new InputListener(){ @Override public boolean keyDown(InputEvent event, KeyCode keycode){ + timer.get(1, 0); if(buttons.getChildren().size > 0){ if(keycode == KeyCode.up) tabIndex = Mathf.mod(--tabIndex, buttons.getChildren().size); if(keycode == KeyCode.down) tabIndex = Mathf.mod(++tabIndex, buttons.getChildren().size); if(field != null && keycode == KeyCode.enter){ tabIndex = Mathf.mod(tabIndex, buttons.getChildren().size); - buttons.getCells().get(tabIndex).get().fireClick(); + var button = buttons.getCells().get(tabIndex).get(); + button.fireClick(); Core.scene.setKeyboardFocus(field); field.setCursorPosition(field.getText().length()); } + //scroll + if(keycode == KeyCode.up || keycode == KeyCode.down) scrollToTabIndex(); } return super.keyDown(event, keycode); } }); } + @Override + public void act(float delta){ + super.act(delta); + if(timer.check(1, 700) && Core.input.keyDown(KeyCode.up) && timer.get(2, 50)){ + tabIndex = Mathf.mod(--tabIndex, buttons.getChildren().size); + scrollToTabIndex(); + } + if(timer.check(1, 700) && Core.input.keyDown(KeyCode.down) && timer.get(2, 50)){ + tabIndex = Mathf.mod(++tabIndex, buttons.getChildren().size); + scrollToTabIndex(); + } + } + + void scrollToTabIndex(){ + var button = buttons.getCells().get(tabIndex).get(); + pane.scrollTo(button.x, button.y, button.getWidth(), button.getHeight()); + } + void build(){ clearChildren(); pane(t -> { @@ -183,44 +211,29 @@ void build(){ } }catch(Exception ignored){} }).minWidth(100f).maxWidth(200f).maxHeight(300f).with(sp -> { + pane = sp; sp.setScrollingDisabledX(true); sp.setFadeScrollBars(true); sp.setupFadeScrollBars(0.5f, 0.5f); }); } }; - autoFillVarTable.popup(Align.topLeft); + if(MI2USettings.getBool(mindowName + ".autocomplete", true)) autoFillVarTable.popup(Align.topLeft); varsBaseTable = new Table(); varsTable = new Table(); searchBaseTable = new Table(); cutPasteBaseTable = new Table(); backupTable = new Table(); - setupVarsMode(varsBaseTable); - setupSearchMode(searchBaseTable); - setupCutPasteMode(cutPasteBaseTable); - setupBackupMode(backupTable); - } - - @Override - public void act(float delta){ - super.act(delta); - if(targetLogicDialog.canvas != null && backupTimer.get(0, 60000)){ - backup(targetLogicDialog.canvas.save()); - } - - - } - - public void setTargetDialog(LogicDialog ld){ - targetLogicDialog = ld; - } + Events.on(MI2UEvents.FinishSettingInitEvent.class, e -> { + setupVarsMode(varsBaseTable); + setupSearchMode(searchBaseTable); + setupCutPasteMode(cutPasteBaseTable); + setupBackupMode(backupTable); + }); - @Override - public void setupCont(Table cont) { - cont.clear(); - cont.table(tt -> { - tt.defaults().growX().minSize(48f); + titlePane.table(tt -> { + tt.defaults().growX().minSize(32f); tt.button("" + Iconc.list, textbtoggle, () -> { mode = Mode.vars; setupCont(cont); @@ -240,14 +253,39 @@ public void setupCont(Table cont) { mode = Mode.backup; setupCont(cont); }).update(b -> b.setChecked(mode == Mode.backup)).with(funcSetTextb); - }).fillX(); - cont.row(); + }); + } + + @Override + public void act(float delta){ + super.act(delta); + if(targetLogicDialog.canvas != null && backupTimer.get(0, 60000)){ + backup(targetLogicDialog.canvas.save()); + } + } + + @Override + public void initSettings(){ + super.initSettings(); + settings.add(new MI2USettings.CheckEntry(mindowName + ".autocomplete", "@settings.logicHelper.autocomplete", true, b -> { + if(b) autoFillVarTable.popup(); + else autoFillVarTable.hide(); + })); + } + + public void setTargetDialog(LogicDialog ld){ + targetLogicDialog = ld; + } + + @Override + public void setupCont(Table cont) { + cont.clear(); cont.image().color(Color.pink).growX().height(2f); cont.row(); switch(mode){ - case vars -> cont.add(varsBaseTable); - case search -> cont.add(searchBaseTable); - case cutPaste -> cont.add(cutPasteBaseTable); + case vars -> cont.add(varsBaseTable).growX(); + case search -> cont.add(searchBaseTable).growX(); + case cutPaste -> cont.add(cutPasteBaseTable).growX(); case backup -> cont.add(backupTable).growX(); } } @@ -498,8 +536,7 @@ private void locateElement(Cons cons){ if(index < 0) index = results.size - 1; Element e = results.get(index); e.localToAscendantCoordinates(targetLogicDialog.canvas.pane.getWidget(), MI2UTmp.v2.setZero()); - //may not fit UI scaling config - targetLogicDialog.canvas.pane.setScrollPercentY(1 - (MI2UTmp.v2.y-0.5f*targetLogicDialog.canvas.pane.getScrollHeight())/(targetLogicDialog.canvas.pane.getWidget().getPrefHeight()-targetLogicDialog.canvas.pane.getScrollHeight())); + targetLogicDialog.canvas.pane.scrollTo(MI2UTmp.v2.x, MI2UTmp.v2.y, e.getWidth(), e.getHeight()); blinkElement(e); if(e instanceof TextField tf) { tf.requestKeyboard(); @@ -525,9 +562,11 @@ public void setupVarsMode(Table cont){ tt.field(split, Styles.nodeField, s -> { split = s; rebuildVars(varsTable); - }).fillX().with(f -> { + }).growX().with(f -> { f.setMessageText("@logicHelper.splitField.msg"); - }); + }).minWidth(48f); + + tt.add(((MI2USettings.CheckEntry)MI2USettings.getEntry(mindowName + ".autocomplete")).newTextButton("@settings.logicHelper.autocomplete")).minSize(32f); }); t.row(); From 2be76a5800d3d5e8463b88410f47d1d77d12bf61 Mon Sep 17 00:00:00 2001 From: BlackDeluxeCat <65377021+BlackDeluxeCat@users.noreply.github.com> Date: Thu, 11 Jan 2024 22:52:52 +0800 Subject: [PATCH 29/57] 1.5.3 --- mod.hjson | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mod.hjson b/mod.hjson index a3065d3..cb8a98b 100644 --- a/mod.hjson +++ b/mod.hjson @@ -5,7 +5,7 @@ displayName: "MI2-Utilities Java" name: "mi2-utilities-java" #the mod version -version: 1.5.2b +version: 1.5.3 #the minimum game build required to run this mod minGameVersion: 146 From e7bb42a2d743baf0b7eb00d2886f8034638ea006 Mon Sep 17 00:00:00 2001 From: BlackDeluxeCat <65377021+BlackDeluxeCat@users.noreply.github.com> Date: Thu, 11 Jan 2024 22:57:35 +0800 Subject: [PATCH 30/57] Update build.gradle --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 2efe558..f2a473a 100644 --- a/build.gradle +++ b/build.gradle @@ -29,7 +29,7 @@ allprojects{ } dependencies{ - compileOnly "com.github.anuken.Arc:arc-core:$mindustryVersion" + compileOnly "com.github.Anuken.Arc:arc-core:$mindustryVersion" compileOnly "com.github.Anuken.Mindustry:core:$mindustryVersion" annotationProcessor "com.github.Anuken:jabel:$jabelVersion" } From e5e5aebd1e438412fccf2595be30ce26633ef841 Mon Sep 17 00:00:00 2001 From: BlackDeluxeCat <65377021+BlackDeluxeCat@users.noreply.github.com> Date: Thu, 11 Jan 2024 23:06:09 +0800 Subject: [PATCH 31/57] Update build.gradle --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index f2a473a..ba12de5 100644 --- a/build.gradle +++ b/build.gradle @@ -29,7 +29,7 @@ allprojects{ } dependencies{ - compileOnly "com.github.Anuken.Arc:arc-core:$mindustryVersion" + compileOnly "com.github.Anuken.Arc:arc-core:8fdcdbfccc" compileOnly "com.github.Anuken.Mindustry:core:$mindustryVersion" annotationProcessor "com.github.Anuken:jabel:$jabelVersion" } From 4e92d68a81a482f07ce4a9738c8532688c4a5027 Mon Sep 17 00:00:00 2001 From: BlackDeluxeCat <65377021+BlackDeluxeCat@users.noreply.github.com> Date: Thu, 11 Jan 2024 23:10:21 +0800 Subject: [PATCH 32/57] Update build.gradle --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index ba12de5..1583386 100644 --- a/build.gradle +++ b/build.gradle @@ -29,8 +29,8 @@ allprojects{ } dependencies{ - compileOnly "com.github.Anuken.Arc:arc-core:8fdcdbfccc" - compileOnly "com.github.Anuken.Mindustry:core:$mindustryVersion" + compileOnly "com.github.Anuken.Arc:arc-core:$mindustryVersion" + compileOnly "com.github.anuken.Mindustry:core:$mindustryVersion" annotationProcessor "com.github.Anuken:jabel:$jabelVersion" } From 9913e68f857800c71d9b8b2c16ae02c4e0019dad Mon Sep 17 00:00:00 2001 From: BlackDeluxeCat <65377021+BlackDeluxeCat@users.noreply.github.com> Date: Thu, 11 Jan 2024 23:11:46 +0800 Subject: [PATCH 33/57] Update build.gradle --- build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 1583386..2efe558 100644 --- a/build.gradle +++ b/build.gradle @@ -29,8 +29,8 @@ allprojects{ } dependencies{ - compileOnly "com.github.Anuken.Arc:arc-core:$mindustryVersion" - compileOnly "com.github.anuken.Mindustry:core:$mindustryVersion" + compileOnly "com.github.anuken.Arc:arc-core:$mindustryVersion" + compileOnly "com.github.Anuken.Mindustry:core:$mindustryVersion" annotationProcessor "com.github.Anuken:jabel:$jabelVersion" } From 6397ef8e191dcab45ca8c04f55aad3d6d85863b1 Mon Sep 17 00:00:00 2001 From: BlackDeluxeCat <65377021+BlackDeluxeCat@users.noreply.github.com> Date: Thu, 11 Jan 2024 23:14:59 +0800 Subject: [PATCH 34/57] Update build.gradle --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 2efe558..4103bc9 100644 --- a/build.gradle +++ b/build.gradle @@ -30,7 +30,7 @@ allprojects{ dependencies{ compileOnly "com.github.anuken.Arc:arc-core:$mindustryVersion" - compileOnly "com.github.Anuken.Mindustry:core:$mindustryVersion" + compileOnly "com.github.anuken.Mindustry:core:$mindustryVersion" annotationProcessor "com.github.Anuken:jabel:$jabelVersion" } From 95dd10fcabc3ccc4d01a505d3390924db8d09048 Mon Sep 17 00:00:00 2001 From: BlackDeluxeCat <65377021+BlackDeluxeCat@users.noreply.github.com> Date: Thu, 11 Jan 2024 23:18:20 +0800 Subject: [PATCH 35/57] Update build.gradle --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 4103bc9..0a217bf 100644 --- a/build.gradle +++ b/build.gradle @@ -30,7 +30,7 @@ allprojects{ dependencies{ compileOnly "com.github.anuken.Arc:arc-core:$mindustryVersion" - compileOnly "com.github.anuken.Mindustry:core:$mindustryVersion" + compileOnly "com.github.anuken.MindustryJitpack:core:$mindustryVersion" annotationProcessor "com.github.Anuken:jabel:$jabelVersion" } From 75cc928a6fad451fcd4c1f189d9da4bb9d91846e Mon Sep 17 00:00:00 2001 From: BlackDeluxeCat <65377021+BlackDeluxeCat@users.noreply.github.com> Date: Thu, 11 Jan 2024 23:20:23 +0800 Subject: [PATCH 36/57] Update build.gradle --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 0a217bf..cc08946 100644 --- a/build.gradle +++ b/build.gradle @@ -30,7 +30,7 @@ allprojects{ dependencies{ compileOnly "com.github.anuken.Arc:arc-core:$mindustryVersion" - compileOnly "com.github.anuken.MindustryJitpack:core:$mindustryVersion" + compileOnly "com.github.anuken.Mindustry:core:26b66f9" annotationProcessor "com.github.Anuken:jabel:$jabelVersion" } From 76f490d16d83e5dfb72331aca801195d0b4e5b2b Mon Sep 17 00:00:00 2001 From: BlackDeluxeCat <65377021+BlackDeluxeCat@users.noreply.github.com> Date: Thu, 11 Jan 2024 23:23:18 +0800 Subject: [PATCH 37/57] Update build.gradle --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index cc08946..1e53838 100644 --- a/build.gradle +++ b/build.gradle @@ -30,7 +30,7 @@ allprojects{ dependencies{ compileOnly "com.github.anuken.Arc:arc-core:$mindustryVersion" - compileOnly "com.github.anuken.Mindustry:core:26b66f9" + compileOnly "com.github.anuken.Mindustry:core:master-SNAPSHOT" annotationProcessor "com.github.Anuken:jabel:$jabelVersion" } From 7bbb1fc01dd26ca57b27d10819cf98ffed28642e Mon Sep 17 00:00:00 2001 From: BlackDeluxeCat <65377021+BlackDeluxeCat@users.noreply.github.com> Date: Thu, 11 Jan 2024 23:26:09 +0800 Subject: [PATCH 38/57] Update build.gradle --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 1e53838..4103bc9 100644 --- a/build.gradle +++ b/build.gradle @@ -30,7 +30,7 @@ allprojects{ dependencies{ compileOnly "com.github.anuken.Arc:arc-core:$mindustryVersion" - compileOnly "com.github.anuken.Mindustry:core:master-SNAPSHOT" + compileOnly "com.github.anuken.Mindustry:core:$mindustryVersion" annotationProcessor "com.github.Anuken:jabel:$jabelVersion" } From e7e67ebfc110f9a9daeeade441a58ca7ddccafdc Mon Sep 17 00:00:00 2001 From: BlackDeluxeCat <65377021+BlackDeluxeCat@users.noreply.github.com> Date: Thu, 11 Jan 2024 23:39:27 +0800 Subject: [PATCH 39/57] Update build.gradle --- build.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/build.gradle b/build.gradle index 4103bc9..d7a59cf 100644 --- a/build.gradle +++ b/build.gradle @@ -11,6 +11,7 @@ sourceSets.main.java.srcDirs = ["src"] repositories{ mavenCentral() maven{ url 'https://www.jitpack.io' } + maven{ url 'https://raw.githubusercontent.com/Zelaux/MindustryRepo/master/repository' } } ext{ From 98cb72bdca49b171ae08a18b8396eab07346739c Mon Sep 17 00:00:00 2001 From: BlackDeluxeCat <65377021+BlackDeluxeCat@users.noreply.github.com> Date: Thu, 11 Jan 2024 23:47:41 +0800 Subject: [PATCH 40/57] Update build.gradle --- build.gradle | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index d7a59cf..9d9da06 100644 --- a/build.gradle +++ b/build.gradle @@ -10,8 +10,8 @@ sourceSets.main.java.srcDirs = ["src"] repositories{ mavenCentral() - maven{ url 'https://www.jitpack.io' } maven{ url 'https://raw.githubusercontent.com/Zelaux/MindustryRepo/master/repository' } + maven{ url 'https://www.jitpack.io' } } ext{ @@ -30,8 +30,8 @@ allprojects{ } dependencies{ - compileOnly "com.github.anuken.Arc:arc-core:$mindustryVersion" - compileOnly "com.github.anuken.Mindustry:core:$mindustryVersion" + compileOnly "com.github.Anuken.Arc:arc-core:$mindustryVersion" + compileOnly "com.github.Anuken.Mindustry:core:$mindustryVersion" annotationProcessor "com.github.Anuken:jabel:$jabelVersion" } From f0d31691e3d3cb3e8717643e9217aff63c89f745 Mon Sep 17 00:00:00 2001 From: BlackDeluxeCat <65377021+BlackDeluxeCat@users.noreply.github.com> Date: Fri, 12 Jan 2024 00:20:23 +0800 Subject: [PATCH 41/57] Update build.gradle --- build.gradle | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 9d9da06..6e4a186 100644 --- a/build.gradle +++ b/build.gradle @@ -17,7 +17,9 @@ repositories{ ext{ //the build number that this mod is made for mindustryVersion = 'v146' - jabelVersion = "0.7.0" + jabelVersion = "93fde537c7" + //windows sucks + isWindows = System.getProperty("os.name").toLowerCase().contains("windows") sdkRoot = System.getenv("ANDROID_HOME") ?: System.getenv("ANDROID_SDK_ROOT") } @@ -48,6 +50,8 @@ task jarAndroid{ //collect dependencies needed for desugaring def dependencies = (configurations.compileClasspath.asList() + configurations.runtimeClasspath.asList() + [new File(platformRoot, "android.jar")]).collect{ "--classpath $it.path" }.join(" ") + def d8 = isWindows ? "d8.bat" : "d8" + //dex and desugar files - this requires d8 in your PATH "d8 $dependencies --min-api 14 --output ${project.archivesBaseName}Android.jar ${project.archivesBaseName}Desktop.jar" .execute(null, new File("$buildDir/libs")).waitForProcessOutput(System.out, System.err) From c909e587c75ca13ee58819fee17f0a1a4908a854 Mon Sep 17 00:00:00 2001 From: BlackDeluxeCat <65377021+BlackDeluxeCat@users.noreply.github.com> Date: Fri, 12 Jan 2024 00:29:45 +0800 Subject: [PATCH 42/57] Update build.gradle --- build.gradle | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index 6e4a186..af04aa0 100644 --- a/build.gradle +++ b/build.gradle @@ -19,7 +19,6 @@ ext{ mindustryVersion = 'v146' jabelVersion = "93fde537c7" //windows sucks - isWindows = System.getProperty("os.name").toLowerCase().contains("windows") sdkRoot = System.getenv("ANDROID_HOME") ?: System.getenv("ANDROID_SDK_ROOT") } @@ -50,10 +49,10 @@ task jarAndroid{ //collect dependencies needed for desugaring def dependencies = (configurations.compileClasspath.asList() + configurations.runtimeClasspath.asList() + [new File(platformRoot, "android.jar")]).collect{ "--classpath $it.path" }.join(" ") - def d8 = isWindows ? "d8.bat" : "d8" + def d8 = "d8.bat" //dex and desugar files - this requires d8 in your PATH - "d8 $dependencies --min-api 14 --output ${project.archivesBaseName}Android.jar ${project.archivesBaseName}Desktop.jar" + "$d8 $dependencies --min-api 14 --output ${project.archivesBaseName}Android.jar ${project.archivesBaseName}Desktop.jar" .execute(null, new File("$buildDir/libs")).waitForProcessOutput(System.out, System.err) } } From 5e4825493c353d5eca3dacd174d000e321a35cd2 Mon Sep 17 00:00:00 2001 From: BlackDeluxeCat <65377021+BlackDeluxeCat@users.noreply.github.com> Date: Fri, 12 Jan 2024 00:33:08 +0800 Subject: [PATCH 43/57] Update build.gradle --- build.gradle | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/build.gradle b/build.gradle index af04aa0..79625f0 100644 --- a/build.gradle +++ b/build.gradle @@ -49,10 +49,8 @@ task jarAndroid{ //collect dependencies needed for desugaring def dependencies = (configurations.compileClasspath.asList() + configurations.runtimeClasspath.asList() + [new File(platformRoot, "android.jar")]).collect{ "--classpath $it.path" }.join(" ") - def d8 = "d8.bat" - //dex and desugar files - this requires d8 in your PATH - "$d8 $dependencies --min-api 14 --output ${project.archivesBaseName}Android.jar ${project.archivesBaseName}Desktop.jar" + "d8 $dependencies --min-api 14 --output ${project.archivesBaseName}Android.jar ${project.archivesBaseName}Desktop.jar" .execute(null, new File("$buildDir/libs")).waitForProcessOutput(System.out, System.err) } } From 7545295e2ff3a5386ce02d77945e42cbd87d9a7d Mon Sep 17 00:00:00 2001 From: BlackDeluxeCat <65377021+BlackDeluxeCat@users.noreply.github.com> Date: Fri, 12 Jan 2024 00:34:57 +0800 Subject: [PATCH 44/57] 1 --- .github/workflows/commitTest.yml | 2 +- .github/workflows/prTest.yml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/commitTest.yml b/.github/workflows/commitTest.yml index bf9f669..d4cac7e 100644 --- a/.github/workflows/commitTest.yml +++ b/.github/workflows/commitTest.yml @@ -10,7 +10,7 @@ jobs: - uses: actions/checkout@v2 - name: Set up PATH run: | - echo "${ANDROID_HOME}/build-tools/30.0.1" >> $GITHUB_PATH + echo "${ANDROID_HOME}/build-tools/34.0.0" >> $GITHUB_PATH - name: Set up JDK 17 uses: actions/setup-java@v1 with: diff --git a/.github/workflows/prTest.yml b/.github/workflows/prTest.yml index 489720a..dbeeaf2 100644 --- a/.github/workflows/prTest.yml +++ b/.github/workflows/prTest.yml @@ -10,11 +10,11 @@ jobs: - uses: actions/checkout@v2 - name: Set up PATH run: | - echo "${ANDROID_HOME}/build-tools/30.0.1" >> $GITHUB_PATH - - name: Set up JDK 16 + echo "${ANDROID_HOME}/build-tools/34.0.0" >> $GITHUB_PATH + - name: Set up JDK 17 uses: actions/setup-java@v1 with: - java-version: 16 + java-version: 17 - name: Build mod jar run: ./gradlew deploy - name: Upload built jar file From 03a5937731a25f941e6c912cce85d4e1e21c2ed8 Mon Sep 17 00:00:00 2001 From: BlackDeluxeCat <65377021+BlackDeluxeCat@users.noreply.github.com> Date: Fri, 12 Jan 2024 00:36:32 +0800 Subject: [PATCH 45/57] Update build.gradle --- build.gradle | 1 - 1 file changed, 1 deletion(-) diff --git a/build.gradle b/build.gradle index 79625f0..32c60f0 100644 --- a/build.gradle +++ b/build.gradle @@ -18,7 +18,6 @@ ext{ //the build number that this mod is made for mindustryVersion = 'v146' jabelVersion = "93fde537c7" - //windows sucks sdkRoot = System.getenv("ANDROID_HOME") ?: System.getenv("ANDROID_SDK_ROOT") } From e9ad1552bf39b9ebbf4654b361d7273227ba1834 Mon Sep 17 00:00:00 2001 From: BlackDeluxeCat <65377021+BlackDeluxeCat@users.noreply.github.com> Date: Fri, 12 Jan 2024 00:59:59 +0800 Subject: [PATCH 46/57] 1 --- .github/workflows/commitTest.yml | 2 +- .github/workflows/prTest.yml | 2 +- gradle/wrapper/gradle-wrapper.properties | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/commitTest.yml b/.github/workflows/commitTest.yml index d4cac7e..bf9f669 100644 --- a/.github/workflows/commitTest.yml +++ b/.github/workflows/commitTest.yml @@ -10,7 +10,7 @@ jobs: - uses: actions/checkout@v2 - name: Set up PATH run: | - echo "${ANDROID_HOME}/build-tools/34.0.0" >> $GITHUB_PATH + echo "${ANDROID_HOME}/build-tools/30.0.1" >> $GITHUB_PATH - name: Set up JDK 17 uses: actions/setup-java@v1 with: diff --git a/.github/workflows/prTest.yml b/.github/workflows/prTest.yml index dbeeaf2..618e393 100644 --- a/.github/workflows/prTest.yml +++ b/.github/workflows/prTest.yml @@ -10,7 +10,7 @@ jobs: - uses: actions/checkout@v2 - name: Set up PATH run: | - echo "${ANDROID_HOME}/build-tools/34.0.0" >> $GITHUB_PATH + echo "${ANDROID_HOME}/build-tools/30.0.1" >> $GITHUB_PATH - name: Set up JDK 17 uses: actions/setup-java@v1 with: diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 2e6e589..84a0b92 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.2.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists From d48cbf1217f8b5eced9307eb2671577585382137 Mon Sep 17 00:00:00 2001 From: BlackDeluxeCat <65377021+BlackDeluxeCat@users.noreply.github.com> Date: Fri, 12 Jan 2024 01:02:31 +0800 Subject: [PATCH 47/57] Update commitTest.yml --- .github/workflows/commitTest.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/commitTest.yml b/.github/workflows/commitTest.yml index bf9f669..c5b692a 100644 --- a/.github/workflows/commitTest.yml +++ b/.github/workflows/commitTest.yml @@ -11,10 +11,10 @@ jobs: - name: Set up PATH run: | echo "${ANDROID_HOME}/build-tools/30.0.1" >> $GITHUB_PATH - - name: Set up JDK 17 + - name: Set up JDK 16 uses: actions/setup-java@v1 with: - java-version: 17 + java-version: 16 - name: Build mod jar run: ./gradlew deploy - name: Upload built jar file From e6978f4954288f8ce3a20d1c71c119f025f890cf Mon Sep 17 00:00:00 2001 From: BlackDeluxeCat <65377021+BlackDeluxeCat@users.noreply.github.com> Date: Fri, 12 Jan 2024 01:04:14 +0800 Subject: [PATCH 48/57] Update gradle-wrapper.properties --- gradle/wrapper/gradle-wrapper.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 84a0b92..2e6e589 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.2.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists From bef39de1dad124ff668b24a2be7f4c791041b250 Mon Sep 17 00:00:00 2001 From: BlackDeluxeCat <65377021+BlackDeluxeCat@users.noreply.github.com> Date: Fri, 12 Jan 2024 01:06:32 +0800 Subject: [PATCH 49/57] t --- .github/workflows/commitTest.yml | 6 +++--- build.gradle | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/commitTest.yml b/.github/workflows/commitTest.yml index c5b692a..d4cac7e 100644 --- a/.github/workflows/commitTest.yml +++ b/.github/workflows/commitTest.yml @@ -10,11 +10,11 @@ jobs: - uses: actions/checkout@v2 - name: Set up PATH run: | - echo "${ANDROID_HOME}/build-tools/30.0.1" >> $GITHUB_PATH - - name: Set up JDK 16 + echo "${ANDROID_HOME}/build-tools/34.0.0" >> $GITHUB_PATH + - name: Set up JDK 17 uses: actions/setup-java@v1 with: - java-version: 16 + java-version: 17 - name: Build mod jar run: ./gradlew deploy - name: Upload built jar file diff --git a/build.gradle b/build.gradle index 32c60f0..9d9da06 100644 --- a/build.gradle +++ b/build.gradle @@ -17,7 +17,7 @@ repositories{ ext{ //the build number that this mod is made for mindustryVersion = 'v146' - jabelVersion = "93fde537c7" + jabelVersion = "0.7.0" sdkRoot = System.getenv("ANDROID_HOME") ?: System.getenv("ANDROID_SDK_ROOT") } From 00d8e2746d5b6f91c895421ca2489022ebfedd33 Mon Sep 17 00:00:00 2001 From: BlackDeluxeCat <65377021+BlackDeluxeCat@users.noreply.github.com> Date: Wed, 17 Jan 2024 16:52:44 +0800 Subject: [PATCH 50/57] logic custom AI programmable cfg --- src/mi2u/ai/FullAI.java | 80 +++++++++++++++++++++++++++-------------- src/mi2u/ui/MI2UI.java | 19 +++++++++- 2 files changed, 71 insertions(+), 28 deletions(-) diff --git a/src/mi2u/ai/FullAI.java b/src/mi2u/ai/FullAI.java index 694bab4..3ae22ad 100644 --- a/src/mi2u/ai/FullAI.java +++ b/src/mi2u/ai/FullAI.java @@ -8,12 +8,12 @@ import arc.scene.ui.*; import arc.scene.ui.layout.*; import arc.struct.*; +import arc.struct.Queue; import arc.util.*; import mi2u.*; import mi2u.game.*; import mi2u.input.*; import mi2u.io.*; -import mi2u.ui.elements.*; import mindustry.ai.types.*; import mindustry.content.*; import mindustry.entities.*; @@ -24,13 +24,15 @@ import mindustry.logic.*; import mindustry.logic.LExecutor.*; import mindustry.type.*; -import mindustry.type.weapons.RepairBeamWeapon; +import mindustry.type.weapons.*; import mindustry.world.*; import mindustry.world.blocks.*; import mindustry.world.meta.*; -import static mindustry.Vars.*; +import java.util.*; + import static mi2u.MI2UVars.*; +import static mindustry.Vars.*; public class FullAI extends AIController{ public Seq modes = new Seq<>(); @@ -91,29 +93,15 @@ public class Mode{ public boolean enable = false; public String btext; public Drawable bimg; + + public boolean configUIExpand = true; public Mode(){ btext = Iconc.units + ""; } /** override it. enable auto checked. */ public void act(){} - public void buildConfig(Table table){ - table.table(t -> { - t.setBackground(Mindow2.gray2); - t.button(b -> { - b.image().grow().update(img -> img.setColor(enable ? Color.acid : Color.red)); - }, textb, () -> { - enable = !enable; - }).size(16f); - if(bimg != null){ - t.image(bimg).size(18f).scaling(Scaling.fit); - }else{ - t.add(btext).color(Color.sky).left(); - } - t.add().growX(); - }).growX().minHeight(18f).padTop(8f); - table.row(); - } + public void buildConfig(Table table){} } public class BaseMineMode extends Mode{ @@ -457,7 +445,7 @@ public void buildConfig(Table table) { public class LogicMode extends Mode{ public static final Seq> bannedInstructions = new Seq<>(); - static LogicMode logicMode; + public static LogicMode logicMode; public LExecutor exec = new LExecutor(); public String code; public LogicAI ai = new LogicAI(); @@ -468,11 +456,15 @@ public class LogicMode extends Mode{ public static StringBuffer log = new StringBuffer(); Queue plans = new Queue<>(); + public Table customAIUITable = new Table(); + //public int lastPathId = 0; //public float lastMoveX, lastMoveY; public LogicMode(){ super(); + Events.on(EventType.WorldLoadEvent.class, e -> readCode(code)); + logicMode = this; bannedInstructions.clear(); bannedInstructions.addAll(ControlI.class, WriteI.class, StopI.class, SetBlockI.class, SpawnUnitI.class, ApplyEffectI.class, SetRuleI.class, SetRateI.class, ExplosionI.class, SetFlagI.class, SpawnWaveI.class, SetPropI.class); @@ -524,7 +516,7 @@ public void act(){ if(!actionTimer.check(0, (int)LogicAI.logicControlTimeout / 60 * 1000)){ boostAction(ai.boost); if(ai.control != LUnitControl.pathfind || unit.isFlying()){ - moveAction(ai.moveX, ai.moveY, Math.max(ai.moveRad, 1f), false); + moveAction(ai.moveX, ai.moveY, Math.max(ai.moveRad, 1f), ai.control == LUnitControl.approach); }/*else{ if(!Mathf.equal(ai.moveX, lastMoveX, 0.1f) || !Mathf.equal(ai.moveY, lastMoveY, 0.1f)){ lastPathId ++; @@ -550,9 +542,7 @@ public void buildConfig(Table table){ table.table(t -> { t.name = "cfg"; t.button(Iconc.pencil + "" + Iconc.blockWorldProcessor, textb, () -> { - ui.logic.show(code, exec, true, str -> { - readCode(str); - }); + ui.logic.show(code, exec, true, this::readCode); }).grow().minWidth(40f); t.add("ipt="); t.field(String.valueOf(instructionsPerTick), TextField.TextFieldFilter.digitsOnly, str -> instructionsPerTick = Strings.parseInt(str)).growX(); @@ -561,6 +551,8 @@ public void buildConfig(Table table){ }).size(32f); }).grow(); table.row(); + table.pane(customAIUITable).grow().maxHeight(200f); + table.row(); table.add("Print Log").left().color(Color.royal); table.row(); table.pane(t -> { @@ -568,7 +560,6 @@ public void buildConfig(Table table){ t.image().color(Color.royal).growY().width(2f); t.labelWrap(() -> log).grow(); }).grow().maxHeight(200f); - } public void readCode(String str){ @@ -581,6 +572,8 @@ public void readCode(String str){ asm.putConst("@ipt", instructionsPerTick); exec.load(asm); exec.privileged = true; + customAIUITable.clear(); + customAIUITable.defaults().size(80, 32); } public void updatePlayerActionTimer(){ @@ -671,9 +664,42 @@ public boolean tryRunOverwrite(LInstruction inst){ return true; } } + }else if(inst instanceof PrintI printI){ + return printUI(printI); } return false; } + + public boolean printUI(PrintI inst){ + //format: UI.type(var) + var v = exec.var(inst.value); + var str = v.isobj && inst.value != 0 ? PrintI.toString(v.objval) : String.valueOf(v.numval); + if(!str.endsWith(")")) return false; + String[] blocks = str.substring(0, str.length() - 1).split("\\.|\\(", 3); + + if(blocks.length < 2 || !blocks[0].equals("UI")) return false; + var type = blocks[1]; + if(type.equals("row")){ + customAIUITable.row(); + return true; + } + if(blocks.length < 3) return false; + var targetName = blocks[2]; + for(int i = 0; i < exec.vars.length; i++){ + if(exec.var(i).name.equals(targetName)){ + int tgt = i; + if(exec.var(tgt).isobj) return false;//Can't handle object right now + if(customAIUITable.getChildren().size > 30) return false;//no too many uis + switch(type){ + case "row" -> customAIUITable.row(); + case "button" -> customAIUITable.button(targetName, textbtoggle, () -> exec.setbool(tgt, !exec.bool(tgt))).update(tb -> tb.setChecked(exec.bool(tgt))); + case "field" -> customAIUITable.field(String.valueOf(exec.num(tgt)), TextField.TextFieldFilter.floatsOnly, s -> exec.setnum(tgt, Strings.parseDouble(s, 0))); + } + return true; + } + } + return false; + } } -} +} \ No newline at end of file diff --git a/src/mi2u/ui/MI2UI.java b/src/mi2u/ui/MI2UI.java index 3a9f2df..50815b5 100644 --- a/src/mi2u/ui/MI2UI.java +++ b/src/mi2u/ui/MI2UI.java @@ -133,7 +133,24 @@ public MI2UI(){ popup.row(); popup.pane(p -> { for(var mode : fullAI.modes){ - p.table(mode::buildConfig).growX(); + p.table(t -> { + t.setBackground(Mindow2.gray2); + t.button(b -> { + b.image().grow().update(img -> img.setColor(mode.enable ? Color.acid : Color.red)); + }, textb, () -> { + mode.enable = !mode.enable; + }).size(16f); + if(mode.bimg != null){ + t.image(mode.bimg).size(18f).scaling(Scaling.fit); + }else{ + t.add(mode.btext).color(Color.sky).left(); + } + t.image().update(img -> img.setColor(mode.configUIExpand ? Color.royal : Color.darkGray)).grow().get().clicked(() -> { + mode.configUIExpand = !mode.configUIExpand; + }); + }).growX().minHeight(18f).padTop(8f); + p.row(); + p.add(new MCollapser(mode::buildConfig, true).setCollapsed(true, () -> !mode.configUIExpand)).growX(); p.row(); } }).growX().update(p -> { From 78b5e2cea24ae2d552b714abbeab1c67af21ea3f Mon Sep 17 00:00:00 2001 From: BlackDeluxeCat <65377021+BlackDeluxeCat@users.noreply.github.com> Date: Fri, 19 Jan 2024 08:14:11 +0800 Subject: [PATCH 51/57] json setting --- src/mi2u/io/MI2USettings.java | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/src/mi2u/io/MI2USettings.java b/src/mi2u/io/MI2USettings.java index 3a15a4f..635f1d6 100644 --- a/src/mi2u/io/MI2USettings.java +++ b/src/mi2u/io/MI2USettings.java @@ -2,9 +2,7 @@ import arc.*; import arc.files.*; -import arc.func.Boolp; -import arc.func.Cons; -import arc.func.Func; +import arc.func.*; import arc.graphics.Color; import arc.math.Mathf; import arc.scene.ui.Button; @@ -14,6 +12,7 @@ import arc.struct.*; import arc.util.*; import arc.util.io.Writes; +import arc.util.serialization.*; import mi2u.game.MI2UEvents; import mi2u.ui.elements.Mindow2; import mindustry.game.EventType.*; @@ -24,7 +23,6 @@ import static mi2u.MI2UVars.*; public class MI2USettings{ - public static final OrderedMap map = new OrderedMap<>(); private static Fi root, dir; public static boolean modified = false; @@ -32,6 +30,8 @@ public class MI2USettings{ public static Seq entries = new Seq<>(); + public static Json json = new Json(); + public static void init(){ Core.settings.setAppName(Vars.appName); root = Vars.dataDirectory.child("mods").child("MI2U_Settings"); @@ -123,6 +123,23 @@ public static boolean getBool(String name){ return getBool(name, false); } + public static MI2USetting putJson(String name, Object obj, Class knownClass, Class elementclass){ + MI2USetting ss = map.get(name); + if(ss != null){ + ss.value = json.toJson(obj, knownClass, elementclass); + }else{ + ss = new MI2USetting(name, json.toJson(obj, knownClass, elementclass)); + } + modified = true; + return ss; + } + + public static T getJson(String name, Class clazz, Class elementClazz, Prov def){ + MI2USetting obj = map.get(name); + if(obj == null) return def.get(); + return json.fromJson(clazz, elementClazz, obj.value); + } + public static boolean load(){ if(!dir.exists()){ Log.warn("MI2U settings file not found, load failed"); From 86c013987c055dcfc98c6227e97d8388e184cc74 Mon Sep 17 00:00:00 2001 From: BlackDeluxeCat <65377021+BlackDeluxeCat@users.noreply.github.com> Date: Fri, 19 Jan 2024 08:14:25 +0800 Subject: [PATCH 52/57] fixed minimized minimap --- src/mi2u/ui/MinimapMindow.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mi2u/ui/MinimapMindow.java b/src/mi2u/ui/MinimapMindow.java index da7403a..897b584 100644 --- a/src/mi2u/ui/MinimapMindow.java +++ b/src/mi2u/ui/MinimapMindow.java @@ -119,7 +119,7 @@ public MinimapMindow(){ }); }).right(); }; - t.add(new MCollapser(b, true).setCollapsed(true, () -> !hasMouse()).setDuration(0.2f).setDirection(true, false)); + t.add(new MCollapser(b, true).setCollapsed(false, () -> minimized || !hasMouse()).setDuration(0.2f).setDirection(true, false)); t.add().growX(); t.table(l).right(); From bc1dcd850c4e02d1a949169bf28250057c915254 Mon Sep 17 00:00:00 2001 From: BlackDeluxeCat <65377021+BlackDeluxeCat@users.noreply.github.com> Date: Fri, 19 Jan 2024 08:14:31 +0800 Subject: [PATCH 53/57] Update HoverTopTable.java --- src/mi2u/ui/HoverTopTable.java | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/src/mi2u/ui/HoverTopTable.java b/src/mi2u/ui/HoverTopTable.java index 67e0574..9dadbf6 100644 --- a/src/mi2u/ui/HoverTopTable.java +++ b/src/mi2u/ui/HoverTopTable.java @@ -46,9 +46,13 @@ public class HoverTopTable extends PopupTable{ public HoverTopTable(){ initChild(); build(); + visible(() -> Vars.state.isGame() && Vars.ui.hudfrag.shown && hasInfo()); + + Core.scene.root.hovered(this::cleanHover); Events.run(EventType.Trigger.update, () -> { - if(state.isGame()) hovered(); + if(state.isGame() && !Core.scene.hasMouse()) hovered(); + if(state.isMenu()) cleanHover(); }); //伤害事件不带伤害值,手算 @@ -195,7 +199,6 @@ public void initChild(){ public void build(){ clear(); - visible(() -> Vars.state.isGame() && Vars.ui.hudfrag.shown && hasInfo()); table(t -> { t.clear(); t.background(Styles.black3); @@ -209,8 +212,6 @@ public void build(){ t.row(); t.add(tilet); - }).update(t -> { - if(state.isMenu()) cleanHover(); }).growX(); } @@ -302,14 +303,6 @@ public void display(Table table, Unit unit){ /** Returns the thing being hovered over. */ @Nullable public void hovered(){ - Vec2 v = this.stageToLocalCoordinates(Core.input.mouse()); - - //if the mouse intersects the table or the *touchable* UI has the mouse, no hovering can occur - if(Core.scene.hasMouse() || this.hit(v.x, v.y, true) != null){ - cleanHover(); - return; - } - //check for a unit unit = Units.closestOverlap(null, Core.input.mouseWorldX(), Core.input.mouseWorldY(), 5f, u -> true); @@ -337,4 +330,18 @@ public void cleanHover(){ public boolean hasInfo(){ return unit != null || tile != null || build != null; } + + public void setHovered(Object u){ + if(u == null) return; + cleanHover(); + if(u instanceof Unit uu){ + unit = uu; + } + if(u instanceof Building bb){ + build = bb; + } + if(u instanceof Tile tt){ + tile = tt; + } + } } From 8b44df079dad9b659deb9deb92df79409ad82009 Mon Sep 17 00:00:00 2001 From: BlackDeluxeCat <65377021+BlackDeluxeCat@users.noreply.github.com> Date: Fri, 19 Jan 2024 10:20:07 +0800 Subject: [PATCH 54/57] Logic custom ai UI --- assets/bundles/bundle.properties | 16 ++ assets/bundles/bundle_zh_CN.properties | 15 ++ src/mi2u/ai/FullAI.java | 253 +++++++++++++++++++++---- src/mi2u/ui/MI2UI.java | 4 +- 4 files changed, 245 insertions(+), 43 deletions(-) diff --git a/assets/bundles/bundle.properties b/assets/bundles/bundle.properties index bf72181..afb79de 100644 --- a/assets/bundles/bundle.properties +++ b/assets/bundles/bundle.properties @@ -71,6 +71,7 @@ ai.config.autorebuild = Auto Rebuild ai.config.attack = Attack ai.config.heal = Heal ai.config.oneTime = One-Time Pick +ai.config.logic.ui = Custom UI main.MI2U = MI2U logicHelper.MI2U = Logic Helper @@ -208,4 +209,19 @@ fullAI.help = Logic Custom AI can control player unit with processor code. After \n\nPlayer actions are divided into two parts: move, attack, and two timers are independent. 10s without control or using [accent]idle|stop[] will release the control to other AIs.\ \n\nLogic is based on world processor and can use world-sense instructions, but world-modifying and unsimulable instructions only work in single-player sandbox, such as [accent]SetProp, Write, SetBlock, etc.[] \ \n\nAlternative implementations by simulating player for some instructions, such as [accent]Control-config[].\ + \n\nSome logic functions are implemented by simulating players, such as [accent]Control-config[].\ + \n\nMultiple custom logics can be stored, but only one can be run at a time.\ + \n\nYou can customize the UI using Print statements. The statements for creating controls are as follows:\ + \n[accent]UI.row()[]\ + \nStarts a new row in the UI pane.\ + \n[accent]UI.button(variable name)[]\ + \nGenerates a button that sets boolean variable.\ + \n[accent]UI.field(variable name)[]\ + \nGenerates a text box that sets numeric variable.\ + \n[accent]UI.choose(variable name)[]\ + \nGenerates a selection box that sets variable to an item, unit, building, or other type. The variable needs to be initialized to a quantity of that type.\ + \n[accent]UI.info(variable name)[]\ + \nGenerates a label and monitors the variable.\ + \nSimply write the statement (in double quotes) in the Print statement. \ + \nEach time the statement is executed, a new control is generated, so please place it in the initialization statement.\ \n\nThe Developer shall not be liable for any consequences arising from the improper use of this feature. \ No newline at end of file diff --git a/assets/bundles/bundle_zh_CN.properties b/assets/bundles/bundle_zh_CN.properties index 2207a00..59c6730 100644 --- a/assets/bundles/bundle_zh_CN.properties +++ b/assets/bundles/bundle_zh_CN.properties @@ -71,6 +71,7 @@ ai.config.autorebuild = 自动重建 ai.config.attack = 攻击敌人 ai.config.heal = 修理建筑 ai.config.oneTime = 一次性抓取 +ai.config.logic.ui = 自定义UI main.MI2U = MI2U logicHelper.MI2U = 逻辑辅助 @@ -208,4 +209,18 @@ fullAI.help = 逻辑自定义AI可以用逻辑代码控制玩家单位行动. \n\n玩家动作分为两部分: 移动, 攻击, 2个计时器相互独立. 10s不进行控制或者使用[accent]idle, stop[], 就会释放控制权给其他AI.\ \n\n逻辑基于世界处理器, 可以使用世处的感知世界的指令, 但不能模拟的, 修改世界的指令只能在单人沙盒生效, 例如[accent]SetProp, Write, SetBlock[]等. \ \n\n部分逻辑功能通过模拟玩家实现, 例如[accent]Control-config[].\ + \n\n可以存储多个自定义逻辑, 但同时只能运行其中一个.\ + \n\n利用Print语句可以自定义UI. 创建控件的语句如下:\ + \n[accent]UI.row()[]\ + \n给UI窗格换行\ + \n[accent]UI.button(变量名)[]\ + \n生成按钮, 设置1,0\ + \n[accent]UI.field(变量名)[]\ + \n生成文本框, 设置数字变量\ + \n[accent]UI.choose(变量名)[]\ + \n生成选择框, 设置物品, 单位, 建筑等类型. 需要初始化变量为一个类型量.\ + \n[accent]UI.info(变量名)[]\ + \n生成信息栏, 监控变量\ + \n在Print语句中编写语句(需要双引号)即可. \ + \n语句每次执行都会生成新控件, 因此请放在初始化语句中.\ \n\n开发者对不当使用本功能产生的后果无需承担任何责任. Never Mind the Scandal and Liber. \ No newline at end of file diff --git a/src/mi2u/ai/FullAI.java b/src/mi2u/ai/FullAI.java index 3ae22ad..124262c 100644 --- a/src/mi2u/ai/FullAI.java +++ b/src/mi2u/ai/FullAI.java @@ -1,21 +1,25 @@ package mi2u.ai; import arc.*; +import arc.func.*; import arc.graphics.*; import arc.math.*; import arc.math.geom.*; +import arc.scene.event.*; import arc.scene.style.*; import arc.scene.ui.*; import arc.scene.ui.layout.*; import arc.struct.*; -import arc.struct.Queue; import arc.util.*; import mi2u.*; import mi2u.game.*; import mi2u.input.*; import mi2u.io.*; +import mi2u.ui.*; +import mi2u.ui.elements.*; import mindustry.ai.types.*; import mindustry.content.*; +import mindustry.ctype.*; import mindustry.entities.*; import mindustry.entities.units.*; import mindustry.game.*; @@ -25,12 +29,11 @@ import mindustry.logic.LExecutor.*; import mindustry.type.*; import mindustry.type.weapons.*; +import mindustry.ui.*; import mindustry.world.*; import mindustry.world.blocks.*; import mindustry.world.meta.*; -import java.util.*; - import static mi2u.MI2UVars.*; import static mindustry.Vars.*; @@ -446,8 +449,10 @@ public void buildConfig(Table table) { public class LogicMode extends Mode{ public static final Seq> bannedInstructions = new Seq<>(); public static LogicMode logicMode; + public LogicModeCode code; + public Seq codes; + public LExecutor exec = new LExecutor(); - public String code; public LogicAI ai = new LogicAI(); public int instructionsPerTick = 100; MI2Utils.IntervalMillis timer = new MI2Utils.IntervalMillis(); @@ -456,33 +461,139 @@ public class LogicMode extends Mode{ public static StringBuffer log = new StringBuffer(); Queue plans = new Queue<>(); - public Table customAIUITable = new Table(); + public PopupTable customAIUITable = new PopupTable(); + + public static PopupTable chooseContentTable = new PopupTable(); //public int lastPathId = 0; //public float lastMoveX, lastMoveY; public LogicMode(){ super(); - Events.on(EventType.WorldLoadEvent.class, e -> readCode(code)); + chooseContentTable.update(() -> chooseContentTable.keepInScreen()); + + Events.on(EventType.WorldLoadEvent.class, e -> readCode(code.value)); logicMode = this; bannedInstructions.clear(); bannedInstructions.addAll(ControlI.class, WriteI.class, StopI.class, SetBlockI.class, SpawnUnitI.class, ApplyEffectI.class, SetRuleI.class, SetRateI.class, ExplosionI.class, SetFlagI.class, SpawnWaveI.class, SetPropI.class); btext = Iconc.blockWorldProcessor + ""; bimg = Core.atlas.drawable("mi2-utilities-java-ui-customai"); + Events.on(MI2UEvents.FinishSettingInitEvent.class, e -> { - code = MI2USettings.getStr("ai.logic.code.0"); - readCode(code); + LogicMode.logicMode.codes = MI2USettings.getJson("ai.logic.codes", Seq.class, LogicModeCode.class, () -> Seq.with(new LogicModeCode("", ""))); + //old version support + if(MI2USettings.getSetting("ai.logic.code.0") != null){ + MI2USettings.map.remove("ai.logic.code.0"); + var old = new LogicModeCode("old", MI2USettings.getStr("ai.logic.code.0")); + codes.add(old); + code = old; + }else{ + code = codes.first(); + } + readCode(code.value); }); + Events.on(EventType.WorldLoadEvent.class, e-> { if(logicMode != null){ - logicMode.readCode(logicMode.code); + logicMode.readCode(logicMode.code.value); } }); } + @Override + public void buildConfig(Table table){ + table.clear(); + super.buildConfig(table); + table.table(t -> { + t.table(this::buildChoose).growX(); + t.button("" + Iconc.add, textb, () -> { + var newCode = new LogicModeCode(String.valueOf(codes.size), ""); + codes.add(newCode); + code = newCode; + saveCodes(); + buildConfig(table); + }).size(32f); + }).growX(); + table.row(); + table.image().height(2f).growX().color(Color.white); + table.row(); + + table.table(t -> { + t.name = "cfg"; + t.button("" + Iconc.edit, textb, () -> { + ui.showTextInput("Edit Logic AI Name", "Edit Logic AI Name", code.name, s -> { + if(!s.equals(code.name)){ + code.name = s; + saveCodes(); + } + }); + }).size(32f); + t.label(() -> code.name).grow(); + t.button("" + Iconc.blockWorldProcessor, textb, () -> { + ui.logic.show(code.value, exec, true, s -> { + code.value = s; + this.readCode(code.value); + saveCodes(); + }); + }).size(32f); + t.button(Iconc.info + "", textb, () -> { + ui.showText("", Core.bundle.get("fullAI.help"), Align.left); + }).size(32f); + t.button(Iconc.cancel + "", textb, () -> ui.showConfirm("Confirm Delete:" + code.name, () -> { + int index = codes.indexOf(code) - 1; + if(index < 0) index = 0; + codes.remove(code); + saveCodes(); + code = codes.get(index); + buildConfig(table); + })).disabled(tb -> codes.size <= 1).size(32f).get().getLabel().setColor(Color.scarlet); + }).grow(); + table.row(); + + table.table(t -> { + t.add("Message Log").left().color(Color.royal).growX(); + t.button("@ai.config.logic.ui", textbtoggle, () -> { + if(customAIUITable.shown){ + customAIUITable.hide(); + }else{ + customAIUITable.popup(); + customAIUITable.setPositionInScreen(Core.input.mouseX(), Core.input.mouseY()); + } + }).checked(tb -> customAIUITable.shown).size(80f, 32f); + }).growX(); + + table.row(); + table.pane(t -> { + t.name = "log"; + t.image().color(Color.royal).growY().width(2f); + t.labelWrap(() -> log).grow(); + }).grow().maxHeight(200f); + } + + public void buildChoose(Table table){ + int i = 0; + for(var lmc : codes){ + table.button(lmc.name.substring(0, Math.min(lmc.name.length(), 6)), textbtoggle, () -> { + code = lmc; + readCode(code.value); + }).with(funcSetTextb).width(60f).height(28f).margin(2f).with(tb -> { + tb.getLabel().setFontScale(0.8f); + tb.update(() -> { + tb.setChecked(code == lmc); + tb.setText(lmc.name); + }); + }); + if(i++ > 2){ + i = 0; + table.row(); + } + } + } + @Override public void act(){ + exec.vars[exec.iptIndex].numval = instructionsPerTick; var ctrl = unit.controller(); unit.controller(ai); @@ -536,35 +647,12 @@ public void act(){ } } - @Override - public void buildConfig(Table table){ - super.buildConfig(table); - table.table(t -> { - t.name = "cfg"; - t.button(Iconc.pencil + "" + Iconc.blockWorldProcessor, textb, () -> { - ui.logic.show(code, exec, true, this::readCode); - }).grow().minWidth(40f); - t.add("ipt="); - t.field(String.valueOf(instructionsPerTick), TextField.TextFieldFilter.digitsOnly, str -> instructionsPerTick = Strings.parseInt(str)).growX(); - t.button(Iconc.info + "", textb, () -> { - ui.showText("", Core.bundle.get("fullAI.help"), Align.left); - }).size(32f); - }).grow(); - table.row(); - table.pane(customAIUITable).grow().maxHeight(200f); - table.row(); - table.add("Print Log").left().color(Color.royal); - table.row(); - table.pane(t -> { - t.name = "log"; - t.image().color(Color.royal).growY().width(2f); - t.labelWrap(() -> log).grow(); - }).grow().maxHeight(200f); + public void saveCodes(){ + MI2USettings.putJson("ai.logic.codes", codes, Seq.class, LogicModeCode.class); } public void readCode(String str){ - code = str; - MI2USettings.putStr("ai.logic.code.0", code); + code.value = str; LAssembler asm = LAssembler.assemble(str, true); asm.putConst("@mapw", world.width()); asm.putConst("@maph", world.height()); @@ -573,6 +661,13 @@ public void readCode(String str){ exec.load(asm); exec.privileged = true; customAIUITable.clear(); + customAIUITable.touchable = Touchable.enabled; + customAIUITable.margin(2f); + customAIUITable.background(Styles.black3); + customAIUITable.addDragMove(); + customAIUITable.addCloseButton(20f); + customAIUITable.add("@ai.config.logic.ui").height(20f).row(); + customAIUITable.update(() -> customAIUITable.keepInScreen()); customAIUITable.defaults().size(80, 32); } @@ -586,7 +681,10 @@ public boolean isLocalSandbox(){ } public boolean tryRunOverwrite(LInstruction inst){ - if(inst instanceof ControlI li){ + if(inst instanceof SetRateI sr){ + instructionsPerTick = exec.numi(sr.amount); + return true; + }else if(inst instanceof ControlI li){ if(!player.dead() && exec.obj(li.target) instanceof Building b && (isLocalSandbox() || b.team == exec.team)){ if(li.type == LAccess.config){ b.configured(player.unit(), exec.obj(li.p1)); @@ -673,8 +771,8 @@ public boolean tryRunOverwrite(LInstruction inst){ public boolean printUI(PrintI inst){ //format: UI.type(var) - var v = exec.var(inst.value); - var str = v.isobj && inst.value != 0 ? PrintI.toString(v.objval) : String.valueOf(v.numval); + var text = exec.var(inst.value); + var str = text.isobj && inst.value != 0 ? PrintI.toString(text.objval) : String.valueOf(text.numval); if(!str.endsWith(")")) return false; String[] blocks = str.substring(0, str.length() - 1).split("\\.|\\(", 3); @@ -689,17 +787,90 @@ public boolean printUI(PrintI inst){ for(int i = 0; i < exec.vars.length; i++){ if(exec.var(i).name.equals(targetName)){ int tgt = i; - if(exec.var(tgt).isobj) return false;//Can't handle object right now - if(customAIUITable.getChildren().size > 30) return false;//no too many uis + if(customAIUITable.getChildren().size > 60) return false;//no too many uis switch(type){ - case "row" -> customAIUITable.row(); case "button" -> customAIUITable.button(targetName, textbtoggle, () -> exec.setbool(tgt, !exec.bool(tgt))).update(tb -> tb.setChecked(exec.bool(tgt))); case "field" -> customAIUITable.field(String.valueOf(exec.num(tgt)), TextField.TextFieldFilter.floatsOnly, s -> exec.setnum(tgt, Strings.parseDouble(s, 0))); + case "choose" -> { + if(exec.var(tgt).isobj && !(exec.obj(tgt) instanceof MappableContent)) return false; + customAIUITable.button(targetName, textb, () -> { + chooseContentTable.clear(); + chooseContentTable.addDragMove(); + chooseContentTable.addCloseButton(); + chooseContentTable.visible(() -> state.isGame()); + buildTable(chooseContentTable, new Seq().add(content.items()).add(content.liquids()).add(content.statusEffects()).add(content.blocks()).add(content.units()), () -> exec.obj(tgt) instanceof UnlockableContent uc ? uc : null, content -> exec.setobj(tgt, content), false, 8, 8); + chooseContentTable.popup(); + chooseContentTable.snapTo(customAIUITable); + }); + } + case "info" -> { + customAIUITable.button("", textbtoggle, () -> {}).fill().with(b -> { + b.update(() -> { + b.setText(PrintI.toString(exec.obj(tgt))); + b.getLabel().setFontScale(0.7f); + if(b.hasMouse()) HoverTopTable.hoverInfo.setHovered(exec.obj(tgt)); + if(b.isChecked()){ + if(exec.obj(tgt) instanceof Posc posc && control.input instanceof InputOverwrite ipo){ + ipo.pan(true, MI2UTmp.v1.set(posc)); + }else{ + b.setChecked(false); + } + } + }); + }); + } } return true; } } return false; } + + public static void buildTable(Table table, Seq items, Prov holder, Cons consumer, boolean closeSelect, int rows, int columns){ + ButtonGroup group = new ButtonGroup<>(); + group.setMinCheckCount(0); + Table cont = new Table().top(); + cont.defaults().size(40); + + Table main = new Table().background(Styles.black6); + + Runnable rebuild = () -> { + group.clear(); + cont.clearChildren(); + + int i = 0; + for(T item : items){ + ImageButton button = cont.button(Tex.whiteui, Styles.clearNoneTogglei, Mathf.clamp(item.selectionSize, 0f, 40f), () -> { + if(closeSelect) control.input.config.hideConfig(); + }).tooltip(item.localizedName).group(group).get(); + button.changed(() -> consumer.get(button.isChecked() ? item : null)); + button.getStyle().imageUp = new TextureRegionDrawable(item.uiIcon); + button.update(() -> button.setChecked(holder.get() == item)); + + if(i++ % columns == (columns - 1)){ + cont.row(); + } + } + }; + + rebuild.run(); + + ScrollPane pane = new ScrollPane(cont, Styles.smallPane); + pane.setScrollingDisabled(true, false); + + pane.setOverscroll(false, false); + main.add(pane).maxHeight(40 * rows); + table.top().add(main); + } + + public static class LogicModeCode{ + String name; + String value; + public LogicModeCode(){} + public LogicModeCode(String n, String v){ + name = n; + value = v; + } + } } } \ No newline at end of file diff --git a/src/mi2u/ui/MI2UI.java b/src/mi2u/ui/MI2UI.java index 50815b5..bdd66de 100644 --- a/src/mi2u/ui/MI2UI.java +++ b/src/mi2u/ui/MI2UI.java @@ -145,12 +145,12 @@ public MI2UI(){ }else{ t.add(mode.btext).color(Color.sky).left(); } - t.image().update(img -> img.setColor(mode.configUIExpand ? Color.royal : Color.darkGray)).grow().get().clicked(() -> { + t.label(() -> mode.configUIExpand ? "-" : ">").grow().get().clicked(() -> { mode.configUIExpand = !mode.configUIExpand; }); }).growX().minHeight(18f).padTop(8f); p.row(); - p.add(new MCollapser(mode::buildConfig, true).setCollapsed(true, () -> !mode.configUIExpand)).growX(); + p.add(new MCollapser(mode::buildConfig, true).setCollapsed(false, () -> !mode.configUIExpand)).growX(); p.row(); } }).growX().update(p -> { From 4c8c59f265c8f15668dc3ef16af9ff7299b42d81 Mon Sep 17 00:00:00 2001 From: BlackDeluxeCat <65377021+BlackDeluxeCat@users.noreply.github.com> Date: Fri, 19 Jan 2024 11:32:04 +0800 Subject: [PATCH 55/57] Update FullAI.java --- src/mi2u/ai/FullAI.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/mi2u/ai/FullAI.java b/src/mi2u/ai/FullAI.java index 124262c..9e5c03a 100644 --- a/src/mi2u/ai/FullAI.java +++ b/src/mi2u/ai/FullAI.java @@ -804,16 +804,17 @@ public boolean printUI(PrintI inst){ }); } case "info" -> { - customAIUITable.button("", textbtoggle, () -> {}).fill().with(b -> { + + customAIUITable.add("").fill().with(b -> { + b.setFontScale(0.7f); + b.clicked(() -> b.cullable = !b.cullable); b.update(() -> { b.setText(PrintI.toString(exec.obj(tgt))); - b.getLabel().setFontScale(0.7f); + b.setColor(b.cullable ? Color.cyan : Color.white); if(b.hasMouse()) HoverTopTable.hoverInfo.setHovered(exec.obj(tgt)); - if(b.isChecked()){ + if(b.cullable){ if(exec.obj(tgt) instanceof Posc posc && control.input instanceof InputOverwrite ipo){ ipo.pan(true, MI2UTmp.v1.set(posc)); - }else{ - b.setChecked(false); } } }); From 8465d8fce405fb7a8cb54ba0c9f9faca675bb81b Mon Sep 17 00:00:00 2001 From: BlackDeluxeCat <65377021+BlackDeluxeCat@users.noreply.github.com> Date: Fri, 19 Jan 2024 17:50:19 +0800 Subject: [PATCH 56/57] example --- assets/bundles/bundle.properties | 1 + assets/bundles/bundle_zh_CN.properties | 1 + src/mi2u/ai/FullAI.java | 61 +++++++++++++++++++++++++- 3 files changed, 62 insertions(+), 1 deletion(-) diff --git a/assets/bundles/bundle.properties b/assets/bundles/bundle.properties index afb79de..46d46a9 100644 --- a/assets/bundles/bundle.properties +++ b/assets/bundles/bundle.properties @@ -211,6 +211,7 @@ fullAI.help = Logic Custom AI can control player unit with processor code. After \n\nAlternative implementations by simulating player for some instructions, such as [accent]Control-config[].\ \n\nSome logic functions are implemented by simulating players, such as [accent]Control-config[].\ \n\nMultiple custom logics can be stored, but only one can be run at a time.\ + \n\nOn first load, a default logic with sandbox map editor will be loaded.\ \n\nYou can customize the UI using Print statements. The statements for creating controls are as follows:\ \n[accent]UI.row()[]\ \nStarts a new row in the UI pane.\ diff --git a/assets/bundles/bundle_zh_CN.properties b/assets/bundles/bundle_zh_CN.properties index 59c6730..443a220 100644 --- a/assets/bundles/bundle_zh_CN.properties +++ b/assets/bundles/bundle_zh_CN.properties @@ -210,6 +210,7 @@ fullAI.help = 逻辑自定义AI可以用逻辑代码控制玩家单位行动. \n\n逻辑基于世界处理器, 可以使用世处的感知世界的指令, 但不能模拟的, 修改世界的指令只能在单人沙盒生效, 例如[accent]SetProp, Write, SetBlock[]等. \ \n\n部分逻辑功能通过模拟玩家实现, 例如[accent]Control-config[].\ \n\n可以存储多个自定义逻辑, 但同时只能运行其中一个.\ + \n\n首次使用时, 会加载一个沙盒地形编辑器的默认逻辑.\ \n\n利用Print语句可以自定义UI. 创建控件的语句如下:\ \n[accent]UI.row()[]\ \n给UI窗格换行\ diff --git a/src/mi2u/ai/FullAI.java b/src/mi2u/ai/FullAI.java index 9e5c03a..e2b07b9 100644 --- a/src/mi2u/ai/FullAI.java +++ b/src/mi2u/ai/FullAI.java @@ -481,7 +481,66 @@ public LogicMode(){ bimg = Core.atlas.drawable("mi2-utilities-java-ui-customai"); Events.on(MI2UEvents.FinishSettingInitEvent.class, e -> { - LogicMode.logicMode.codes = MI2USettings.getJson("ai.logic.codes", Seq.class, LogicModeCode.class, () -> Seq.with(new LogicModeCode("", ""))); + LogicMode.logicMode.codes = MI2USettings.getJson("ai.logic.codes", Seq.class, LogicModeCode.class, () -> Seq.with(new LogicModeCode("" + Iconc.edit + Iconc.map, "jump 26 strictEqual init 2\n" + + "set brush.size 2\n" + + "set floor @air\n" + + "set ore @air\n" + + "set block @air\n" + + "set title \"TerraEditor\"\n" + + "set text.ipt \"Ipt\"\n" + + "set ipt 50\n" + + "print \"UI.info(title)\"\n" + + "print \"UI.row()\"\n" + + "print \"UI.info(text.ipt)\"\n" + + "print \"UI.field(ipt)\"\n" + + "print \"UI.row()\"\n" + + "print \"UI.choose(floor)\"\n" + + "print \"UI.info(floor)\"\n" + + "print \"UI.row()\"\n" + + "print \"UI.choose(ore)\"\n" + + "print \"UI.info(ore)\"\n" + + "print \"UI.row()\"\n" + + "print \"UI.info(brush.name)\"\n" + + "print \"UI.button(brush.type)\"\n" + + "print \"UI.row()\"\n" + + "print \"UI.info(brush.size.name)\"\n" + + "print \"UI.field(brush.size)\"\n" + + "set init 2\n" + + "set brush.size.name \"Radius\"\n" + + "sensor en @unit @shooting\n" + + "set brush.name \"suqare\"\n" + + "jump 30 equal brush.type 0\n" + + "set brush.name \"circle\"\n" + + "sensor tx @unit @shootX\n" + + "op add tx tx 0.5\n" + + "op idiv tx tx 1\n" + + "sensor ty @unit @shootY\n" + + "op add ty ty 0.5\n" + + "op idiv ty ty 1\n" + + "op sub x.min tx brush.size\n" + + "op idiv x.min x.min 1\n" + + "op add x.max x.min brush.size\n" + + "op add x.max x.max brush.size\n" + + "op sub y.min ty brush.size\n" + + "op idiv y.min y.min 1\n" + + "op add y.max y.min brush.size\n" + + "op add y.max y.max brush.size\n" + + "set x x.min\n" + + "op add x x 1\n" + + "set y y.min\n" + + "op add y y 1\n" + + "jump 53 equal brush.type 0\n" + + "op sub dx x tx\n" + + "op sub dy y ty\n" + + "op len d dx dy\n" + + "jump 57 greaterThan d brush.size\n" + + "effect lightBlock x y 0.5 %ffbd530f \n" + + "jump 57 notEqual en 1\n" + + "setblock floor floor x y @derelict 0\n" + + "setblock ore ore x y @derelict 0\n" + + "jump 47 lessThan y y.max\n" + + "setrate ipt\n" + + "jump 45 lessThan x x.max\n"))); //old version support if(MI2USettings.getSetting("ai.logic.code.0") != null){ MI2USettings.map.remove("ai.logic.code.0"); From 8f1dcc850c7f3fb35b1677810cd8ce6a7f6872ae Mon Sep 17 00:00:00 2001 From: BlackDeluxeCat <65377021+BlackDeluxeCat@users.noreply.github.com> Date: Fri, 19 Jan 2024 17:50:28 +0800 Subject: [PATCH 57/57] 1.5.4 --- mod.hjson | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mod.hjson b/mod.hjson index cb8a98b..74f2c8b 100644 --- a/mod.hjson +++ b/mod.hjson @@ -5,7 +5,7 @@ displayName: "MI2-Utilities Java" name: "mi2-utilities-java" #the mod version -version: 1.5.3 +version: 1.5.4 #the minimum game build required to run this mod minGameVersion: 146