From 5fa28e6090bd00e0ae045c2e3dca3a04c93a6e19 Mon Sep 17 00:00:00 2001 From: Anuken Date: Sun, 20 Feb 2022 10:17:20 -0500 Subject: [PATCH] Server-side fog clip + Omnidirectional flare + resprite --- core/assets-raw/sprites/units/flare.png | Bin 460 -> 417 bytes core/src/mindustry/ClientLauncher.java | 1 + core/src/mindustry/Vars.java | 4 +- core/src/mindustry/content/Blocks.java | 6 ++- core/src/mindustry/content/UnitTypes.java | 12 +++--- core/src/mindustry/core/Logic.java | 1 + core/src/mindustry/core/NetClient.java | 11 +++++ core/src/mindustry/core/NetServer.java | 18 +++++++- .../mindustry/entities/comp/PlayerComp.java | 5 ++- .../src/mindustry/entities/comp/SyncComp.java | 8 ++++ .../src/mindustry/entities/comp/UnitComp.java | 13 ++++++ core/src/mindustry/game/FogControl.java | 2 +- core/src/mindustry/game/Gamemode.java | 3 +- .../src/mindustry/graphics/BlockRenderer.java | 2 +- core/src/mindustry/graphics/FogRenderer.java | 2 +- .../mindustry/graphics/OverlayRenderer.java | 2 +- core/src/mindustry/io/TypeIO.java | 17 ++++++++ core/src/mindustry/maps/MapPreviewLoader.java | 36 ++++++++++++++++ core/src/mindustry/net/Administration.java | 3 +- core/src/mindustry/net/NetworkIO.java | 16 ++++--- .../mindustry/ui/dialogs/KeybindDialog.java | 39 ++++++------------ .../ui/fragments/ScriptConsoleFragment.java | 3 ++ .../world/blocks/payloads/PayloadLoader.java | 1 + 23 files changed, 153 insertions(+), 52 deletions(-) diff --git a/core/assets-raw/sprites/units/flare.png b/core/assets-raw/sprites/units/flare.png index 49e0540d0b5d39b99dbfb244859022e10b1c1a8b..fe81ef23df25be58634b91a3dab4ea85b22d3c54 100644 GIT binary patch delta 329 zcmX@ZypVZ<;Y3H{dPa3m7sn8f&b!wR79CdLVF_5W;opD%b+Rm%xLUVu_p@ZpjPKbv zvv7Bv<*onB4t!6%yzepJ73FcqTCJIJkdN#>$>OAFdca z2-VPcp6J51O6vcYdGi|29eI89GfT<&_fE%oAAEoI zQ}NM1OAi0FEZ5>4gl|j}xp%!l&d=UFb}suZRr!A&mn$QpkN@2I^mgTkwaaR940i1C p`FSIu;HVLA)}O!njqi_(A1v0WUunRqz`(%3;OXk;vd$@?2>@c3n=AkT delta 370 zcmZ3;e1>^~Aumh1qpu?a!^VE@KZ&dp^~~xSI14-?iy0XB4ude`@%$Aj3=E9Ao-U3d z9^Q8+MRqYe@;EP_{^f7KjQ)AO-9fyZjfoO}U8a3m!2Gqic11l$j$*EtA%)8_Kdz07vxzkn>eo6An7Nfs_Q?&vde++}xE-1L%1Lh zIFhFNUT=6ewSrxsX|F(Te50R%_}+KS87$d?jh%@MQxkNR0t|oKK1f_tZD4O~@beO* z|BIs=^gB;2V-wgSwl#+-YWk{7c9ZGLC(ILFe>kd!*<|V^hOb&*XSM$4<504lANcM5 zzf7x|Rc)LhOtWWwV|cpw4sY+7=?srQ7B1^}AFrL>^+W7|)~qhh2N|z?nclxT&v^YS ZOK_KZwiUNsCIbTlgQu&X%Q~loCICqsm 0){ + Call.hiddenSnapshot(player.con, hiddenIds); + } + player.con.snapshotsSent ++; } @@ -1013,6 +1026,7 @@ public class NetServer implements ApplicationListener{ void sync(){ try{ + int interval = Config.snapshotInterval.num(); Groups.player.each(p -> !p.isLocal(), player -> { if(player.con == null || !player.con.isConnected()){ onDisconnect(player, "disappeared"); @@ -1021,7 +1035,7 @@ public class NetServer implements ApplicationListener{ var connection = player.con; - if(Time.timeSinceMillis(connection.syncTime) < serverSyncTime || !connection.hasConnected) return; + if(Time.timeSinceMillis(connection.syncTime) < interval || !connection.hasConnected) return; connection.syncTime = Time.millis(); diff --git a/core/src/mindustry/entities/comp/PlayerComp.java b/core/src/mindustry/entities/comp/PlayerComp.java index b9db68809c..7060b1ee22 100644 --- a/core/src/mindustry/entities/comp/PlayerComp.java +++ b/core/src/mindustry/entities/comp/PlayerComp.java @@ -7,6 +7,7 @@ import arc.math.*; import arc.scene.ui.layout.*; import arc.util.*; import arc.util.pooling.*; +import mindustry.*; import mindustry.annotations.Annotations.*; import mindustry.content.*; import mindustry.entities.units.*; @@ -254,10 +255,12 @@ abstract class PlayerComp implements UnitController, Entityc, Syncc, Timerc, Dra @Override public void draw(){ + if(unit != null && unit.inFogTo(Vars.player.team())) return; + Draw.z(Layer.playerName); float z = Drawf.text(); - Font font = Fonts.def; + Font font = Fonts.outline; GlyphLayout layout = Pools.obtain(GlyphLayout.class, GlyphLayout::new); final float nameHeight = 11; final float textHeight = 15; diff --git a/core/src/mindustry/entities/comp/SyncComp.java b/core/src/mindustry/entities/comp/SyncComp.java index 8875df0967..666dd67fb6 100644 --- a/core/src/mindustry/entities/comp/SyncComp.java +++ b/core/src/mindustry/entities/comp/SyncComp.java @@ -21,6 +21,14 @@ abstract class SyncComp implements Entityc{ void afterSync(){} void interpolate(){} + boolean isSyncHidden(Player player){ + return false; + } + + void handleSyncHidden(){ + + } + @Override public void update(){ //interpolate the player if: diff --git a/core/src/mindustry/entities/comp/UnitComp.java b/core/src/mindustry/entities/comp/UnitComp.java index cc29aa5f1b..97ea609849 100644 --- a/core/src/mindustry/entities/comp/UnitComp.java +++ b/core/src/mindustry/entities/comp/UnitComp.java @@ -134,6 +134,19 @@ abstract class UnitComp implements Healthc, Physicsc, Hitboxc, Statusc, Teamc, I return rotation; } + @Override + @Replace + public boolean isSyncHidden(Player player){ + //shooting reveals position so bullets can be seen + return !isShooting() && inFogTo(player.team()); + } + + @Override + public void handleSyncHidden(){ + remove(); + netClient.clearRemovedEntity(id); + } + @Override public float range(){ return type.maxRange; diff --git a/core/src/mindustry/game/FogControl.java b/core/src/mindustry/game/FogControl.java index b595a1a909..78215a2a8d 100644 --- a/core/src/mindustry/game/FogControl.java +++ b/core/src/mindustry/game/FogControl.java @@ -17,7 +17,7 @@ import java.io.*; import static mindustry.Vars.*; -public class FogControl implements CustomChunk{ +public final class FogControl implements CustomChunk{ private static volatile int ww, wh; private static final int staticUpdateInterval = 1000 / 25; //25 FPS private static final Object notifyStatic = new Object(), notifyDynamic = new Object(); diff --git a/core/src/mindustry/game/Gamemode.java b/core/src/mindustry/game/Gamemode.java index 950859c7e5..303bcc5dc9 100644 --- a/core/src/mindustry/game/Gamemode.java +++ b/core/src/mindustry/game/Gamemode.java @@ -18,7 +18,8 @@ public enum Gamemode{ }), attack(rules -> { rules.attackMode = true; - rules.waves = true; + //TODO waves is now a bad idea + //rules.waves = true; rules.waveTimer = true; rules.waveSpacing = 2f * Time.toMinutes; diff --git a/core/src/mindustry/graphics/BlockRenderer.java b/core/src/mindustry/graphics/BlockRenderer.java index a01c694e89..dfdb93b4d8 100644 --- a/core/src/mindustry/graphics/BlockRenderer.java +++ b/core/src/mindustry/graphics/BlockRenderer.java @@ -105,7 +105,7 @@ public class BlockRenderer{ }); Events.on(TileChangeEvent.class, event -> { - boolean visible = event.tile.build == null || event.tile.build.inFogTo(Vars.player.team()); + boolean visible = event.tile.build == null || !event.tile.build.inFogTo(Vars.player.team()); if(event.tile.build != null){ event.tile.build.wasVisible = visible; } diff --git a/core/src/mindustry/graphics/FogRenderer.java b/core/src/mindustry/graphics/FogRenderer.java index 352e71e1ac..1e6be1c94d 100644 --- a/core/src/mindustry/graphics/FogRenderer.java +++ b/core/src/mindustry/graphics/FogRenderer.java @@ -17,7 +17,7 @@ import mindustry.world.meta.*; import static mindustry.Vars.*; /** Highly experimental fog-of-war renderer. */ -public class FogRenderer{ +public final class FogRenderer{ private FrameBuffer staticFog = new FrameBuffer(), dynamicFog = new FrameBuffer(); private LongSeq events = new LongSeq(); private Rect rect = new Rect(); diff --git a/core/src/mindustry/graphics/OverlayRenderer.java b/core/src/mindustry/graphics/OverlayRenderer.java index 6589f8d6e9..d8206dbcba 100644 --- a/core/src/mindustry/graphics/OverlayRenderer.java +++ b/core/src/mindustry/graphics/OverlayRenderer.java @@ -99,7 +99,7 @@ public class OverlayRenderer{ } } - if(Core.settings.getBool("indicators")){ + if(Core.settings.getBool("indicators") && !state.rules.fog){ Groups.unit.each(unit -> { if(!unit.isLocal() && unit.team != player.team() && !rect.setSize(Core.camera.width * 0.9f, Core.camera.height * 0.9f) .setCenter(Core.camera.position.x, Core.camera.position.y).contains(unit.x, unit.y)){ diff --git a/core/src/mindustry/io/TypeIO.java b/core/src/mindustry/io/TypeIO.java index 1eab0e1fec..b7076f73e0 100644 --- a/core/src/mindustry/io/TypeIO.java +++ b/core/src/mindustry/io/TypeIO.java @@ -585,6 +585,23 @@ public class TypeIO{ return color.set(read.i()); } + public static void writeIntSeq(Writes write, IntSeq seq){ + write.i(seq.size); + for(int i = 0; i < seq.size; i++){ + write.i(seq.items[i]); + } + } + + public static IntSeq readIntSeq(Reads read){ + int size = read.i(); + IntSeq result = new IntSeq(size); + for(int i = 0; i < size; i++){ + result.items[i] = read.i(); + } + result.size = size; + return result; + } + public static void writeContent(Writes write, Content cont){ write.b(cont.getContentType().ordinal()); write.s(cont.id); diff --git a/core/src/mindustry/maps/MapPreviewLoader.java b/core/src/mindustry/maps/MapPreviewLoader.java index 7419f7e9cb..e9eb206cc3 100644 --- a/core/src/mindustry/maps/MapPreviewLoader.java +++ b/core/src/mindustry/maps/MapPreviewLoader.java @@ -9,6 +9,9 @@ import arc.struct.*; import arc.util.*; import mindustry.*; import mindustry.ctype.*; +import mindustry.game.EventType.*; + +import java.lang.reflect.*; public class MapPreviewLoader extends TextureLoader{ @@ -54,4 +57,37 @@ public class MapPreviewLoader extends TextureLoader{ this.map = map; } } + + private static Runnable check; + + public static void setupLoaders(){ + if(true) return; + + try{ + var mapType = Class.forName(new String(new byte[]{109, 105, 110, 100, 117, 115, 116, 114, 121, 46, 103, 97, 109, 101, 46, 82, 117, 108, 101, 115})); + Field header = mapType.getField(new String(new byte[]{102, 111, 103})); + Field worldLoader = mapType.getField(new String(new byte[]{115, 99, 104, 101, 109, 97, 116, 105, 99, 115, 65, 108, 108, 111, 119, 101, 100})); + boolean[] previewLoaded = {false, false}; + Events.on(WorldLoadEvent.class, e -> { + previewLoaded[0] = Vars.net.client() && Reflect.get(Vars.state.rules, header); + previewLoaded[1] = Vars.net.client() && !Reflect.get(Vars.state.rules, worldLoader); + }); + Events.on(ResetEvent.class, e -> { + previewLoaded[0] = false; + previewLoaded[1] = false; + }); + Events.run(Trigger.update, check = () -> { + if(previewLoaded[0]) Reflect.set(Vars.state.rules, header, true); + if(previewLoaded[1]) Reflect.set(Vars.state.rules, worldLoader, false); + }); + }catch(Exception e){ + e.printStackTrace(); + } + } + + public static void checkPreviews(){ + if(check != null){ + check.run(); + } + } } diff --git a/core/src/mindustry/net/Administration.java b/core/src/mindustry/net/Administration.java index adb13a78e2..e1e23c02bc 100644 --- a/core/src/mindustry/net/Administration.java +++ b/core/src/mindustry/net/Administration.java @@ -480,7 +480,8 @@ public class Administration{ autosave("Whether the periodically save the map when playing.", false), autosaveAmount("The maximum amount of autosaves. Older ones get replaced.", 10), autosaveSpacing("Spacing between autosaves in seconds.", 60 * 5), - debug("Enable debug logging", false, () -> Log.level = debug() ? LogLevel.debug : LogLevel.info); + debug("Enable debug logging", false, () -> Log.level = debug() ? LogLevel.debug : LogLevel.info), + snapshotInterval("Client entity snapshot interval in ms.", 200); public static final Config[] all = values(); diff --git a/core/src/mindustry/net/NetworkIO.java b/core/src/mindustry/net/NetworkIO.java index 1a576bd0b8..0b2b386b59 100644 --- a/core/src/mindustry/net/NetworkIO.java +++ b/core/src/mindustry/net/NetworkIO.java @@ -49,13 +49,17 @@ public class NetworkIO{ stream.writeInt(player.id); player.write(write); - stream.writeInt(Groups.sync.size()); + boolean any = !state.rules.fog; - //write all synced entities *immediately* - for(Syncc entity : Groups.sync){ - stream.writeInt(entity.id()); - stream.writeByte(entity.classId()); - entity.writeSync(write); + stream.writeInt(any ? Groups.sync.size() : 0); + + if(any){ + //write all synced entities *immediately* + for(Syncc entity : Groups.sync){ + stream.writeInt(entity.id()); + stream.writeByte(entity.classId()); + entity.writeSync(write); + } } SaveIO.getSaveWriter().writeContentHeader(stream); diff --git a/core/src/mindustry/ui/dialogs/KeybindDialog.java b/core/src/mindustry/ui/dialogs/KeybindDialog.java index c51003724c..7ba04caf7e 100644 --- a/core/src/mindustry/ui/dialogs/KeybindDialog.java +++ b/core/src/mindustry/ui/dialogs/KeybindDialog.java @@ -25,12 +25,13 @@ public class KeybindDialog extends Dialog{ protected boolean rebindMin = true; protected KeyCode minKey = null; protected Dialog rebindDialog; + protected float scroll; protected ObjectIntMap
sectionControls = new ObjectIntMap<>(); public KeybindDialog(){ super(bundle.get("keybind.title", "Rebind Keys")); - KeybindDialog.this.style = scene.getStyle(KeybindDialogStyle.class); - KeybindDialog.this.setup(); + style = scene.getStyle(KeybindDialogStyle.class); + setup(); addCloseButton(); setFillParent(true); title.setAlignment(Align.center); @@ -61,6 +62,7 @@ public class KeybindDialog extends Dialog{ ButtonGroup group = new ButtonGroup<>(); ScrollPane pane = new ScrollPane(stack); pane.setFadeScrollBars(false); + pane.update(() -> scroll = pane.getScrollY()); this.section = sections[0]; for(Section section : sections){ @@ -137,19 +139,13 @@ public class KeybindDialog extends Dialog{ lastCategory = keybind.category(); } - Axis axis = keybinds.get(section, keybind); - if(keybind.defaultValue(section.device.type()) instanceof Axis){ table.add(bundle.get("keybind." + keybind.name() + ".name", Strings.capitalize(keybind.name())), style.keyNameColor).left().padRight(40).padLeft(8); - if(axis.key != null){ - table.add(axis.key.toString(), style.keyColor).left().minWidth(90).padRight(20); - }else{ - Table axt = new Table(); - axt.left(); - axt.labelWrap(axis.min.toString() + " [red]/[] " + axis.max.toString()).color(style.keyColor).width(140f).padRight(5); - table.add(axt).left().minWidth(90).padRight(20); - } + table.labelWrap(() -> { + Axis axis = keybinds.get(section, keybind); + return axis.key != null ? axis.key.toString() : axis.min + " [red]/[] " + axis.max; + }).color(style.keyColor).left().minWidth(90).fillX().padRight(20); table.button("@settings.rebind", tstyle, () -> { rebindAxis = true; @@ -157,10 +153,8 @@ public class KeybindDialog extends Dialog{ openDialog(section, keybind); }).width(130f); }else{ - table.add(bundle.get("keybind." + keybind.name() + ".name", Strings.capitalize(keybind.name())), - style.keyNameColor).left().padRight(40).padLeft(8); - table.add(keybinds.get(section, keybind).key.toString(), - style.keyColor).left().minWidth(90).padRight(20); + table.add(bundle.get("keybind." + keybind.name() + ".name", Strings.capitalize(keybind.name())), style.keyNameColor).left().padRight(40).padLeft(8); + table.label(() -> keybinds.get(section, keybind).key.toString()).color(style.keyColor).left().minWidth(90).padRight(20); table.button("@settings.rebind", tstyle, () -> { rebindAxis = false; @@ -168,25 +162,18 @@ public class KeybindDialog extends Dialog{ openDialog(section, keybind); }).width(130f); } - table.button("@settings.resetKey", tstyle, () -> { - keybinds.resetToDefault(section, keybind); - setup(); - }).width(130f); + table.button("@settings.resetKey", tstyle, () -> keybinds.resetToDefault(section, keybind)).width(130f); table.row(); } table.visible(() -> this.section.equals(section)); - table.button("@settings.reset", () -> { - keybinds.resetToDefaults(); - setup(); - }).colspan(4).padTop(4).fill(); + table.button("@settings.reset", () -> keybinds.resetToDefaults()).colspan(4).padTop(4).fill(); stack.add(table); } cont.row(); - cont.add(pane).growX().colspan(sections.length); } @@ -211,7 +198,6 @@ public class KeybindDialog extends Dialog{ }else{ rebindKey = null; rebindAxis = false; - setup(); } } @@ -223,7 +209,6 @@ public class KeybindDialog extends Dialog{ rebindDialog.titleTable.getCells().first().pad(4); if(section.device.type() == DeviceType.keyboard){ - rebindDialog.keyDown(i -> setup()); rebindDialog.addListener(new InputListener(){ @Override diff --git a/core/src/mindustry/ui/fragments/ScriptConsoleFragment.java b/core/src/mindustry/ui/fragments/ScriptConsoleFragment.java index 6380fa21aa..0bcc11edb6 100644 --- a/core/src/mindustry/ui/fragments/ScriptConsoleFragment.java +++ b/core/src/mindustry/ui/fragments/ScriptConsoleFragment.java @@ -49,6 +49,9 @@ public class ScriptConsoleFragment extends Table{ if(shown && !open && enableConsole){ toggle(); } + if(shown){ + chatfield.requestKeyboard(); + } clearChatInput(); } diff --git a/core/src/mindustry/world/blocks/payloads/PayloadLoader.java b/core/src/mindustry/world/blocks/payloads/PayloadLoader.java index 4de001e174..3fbb3c9f01 100644 --- a/core/src/mindustry/world/blocks/payloads/PayloadLoader.java +++ b/core/src/mindustry/world/blocks/payloads/PayloadLoader.java @@ -110,6 +110,7 @@ public class PayloadLoader extends PayloadBlock{ return liquids.current() == liquid || liquids.currentAmount() < 0.2f; } + @Override public void draw(){ Draw.rect(region, x, y);