From 4daf889c9d7ce772232a1c2a309470b7be0f0a01 Mon Sep 17 00:00:00 2001 From: Nicolas BARBOTIN Date: Wed, 14 Feb 2018 15:43:44 +0100 Subject: [PATCH] + Added IsEmitting(x, y) and GetEmissionArray() --- README.md | 2 + .../montoyo/wd/client/JSQueryDispatcher.java | 69 +++++++++++-------- .../montoyo/wd/entity/TileEntityScreen.java | 35 +++++----- .../montoyo/wd/utilities/ScreenIterator.java | 64 +++++++++++++++++ .../resources/assets/webdisplays/html/io.html | 57 ++++++++------- .../assets/webdisplays/html/wdlib.js | 18 +++++ 6 files changed, 171 insertions(+), 74 deletions(-) create mode 100644 src/main/java/net/montoyo/wd/utilities/ScreenIterator.java diff --git a/README.md b/README.md index 2a985c2..6a4a251 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,8 @@ This is the unfinished port of the WebDisplays mod for Minecraft 1.12.2. The text below is my "TODO" list. ### Things before release +* Add IsEmitting and GetEmissionArray +* Do some nice screenshots * "Anti-9minecraft" * Update website * Publish diff --git a/src/main/java/net/montoyo/wd/client/JSQueryDispatcher.java b/src/main/java/net/montoyo/wd/client/JSQueryDispatcher.java index 159b6f3..ba67596 100644 --- a/src/main/java/net/montoyo/wd/client/JSQueryDispatcher.java +++ b/src/main/java/net/montoyo/wd/client/JSQueryDispatcher.java @@ -22,10 +22,7 @@ import net.montoyo.wd.entity.TileEntityScreen; import net.montoyo.wd.net.server.SMessageScreenCtrl; import net.montoyo.wd.utilities.*; -import java.util.ArrayDeque; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; +import java.util.*; @SideOnly(Side.CLIENT) public final class JSQueryDispatcher { @@ -250,34 +247,17 @@ public final class JSQueryDispatcher { register("GetRedstoneArray", (cb, tes, side, args) -> { if(tes.hasUpgrade(side, DefaultUpgrade.REDSTONE_INPUT)) { - final Vector2i size = tes.getScreen(side).size; final EnumFacing facing = EnumFacing.VALUES[side.reverse().ordinal()]; - final BlockPos.MutableBlockPos mbp = new BlockPos.MutableBlockPos(); - final Vector3i vec1 = new Vector3i(tes.getPos()); - final Vector3i vec2 = new Vector3i(); - final StringBuilder resp = new StringBuilder("{\"levels\":["); + final StringJoiner resp = new StringJoiner(",", "{\"levels\":[", "]}"); - for(int y = 0; y < size.y; y++) { - vec2.set(vec1); + tes.forEachScreenBlocks(side, bp -> { + if(tes.getWorld().getBlockState(bp).getValue(BlockScreen.emitting)) + resp.add("0"); + else + resp.add("" + tes.getWorld().getRedstonePower(bp, facing)); + }); - for(int x = 0; x < size.x; x++) { - if(x > 0 || y > 0) - resp.append(','); - - vec2.toBlock(mbp); - - if(tes.getWorld().getBlockState(mbp).getValue(BlockScreen.emitting)) - resp.append(0); - else - resp.append(tes.getWorld().getRedstonePower(mbp, facing)); - - vec2.add(side.right.x, side.right.y, side.right.z); - } - - vec1.add(side.up.x, side.up.y, side.up.z); - } - - cb.success(resp.append("]}").toString()); + cb.success(resp.toString()); } else cb.failure(403, "Missing upgrade"); }); @@ -321,6 +301,37 @@ public final class JSQueryDispatcher { makeServerQuery(tes, side, cb, JSServerRequest.SET_REDSTONE_AT, x, y, state); }); + register("IsEmitting", (cb, tes, side, args) -> { + if(!tes.hasUpgrade(side, DefaultUpgrade.REDSTONE_OUTPUT)) { + cb.failure(403, "Missing upgrade"); + return; + } + + if(args.length == 2 && args[0] instanceof Double && args[1] instanceof Double) { + TileEntityScreen.Screen scr = tes.getScreen(side); + int x = ((Double) args[0]).intValue(); + int y = ((Double) args[1]).intValue(); + + if(x < 0 || x >= scr.size.x || y < 0 || y >= scr.size.y) + cb.failure(403, "Out of range"); + else { + BlockPos bpos = (new Vector3i(tes.getPos())).addMul(side.right, x).addMul(side.up, y).toBlock(); + boolean e = tes.getWorld().getBlockState(bpos).getValue(BlockScreen.emitting); + cb.success("{\"emitting\":" + (e ? "true" : "false") + "}"); + } + } else + cb.failure(400, "Wrong arguments"); + }); + + register("GetEmissionArray", (cb, tes, side, args) -> { + if(tes.hasUpgrade(side, DefaultUpgrade.REDSTONE_OUTPUT)) { + final StringJoiner resp = new StringJoiner(",", "{\"emission\":[", "]}"); + tes.forEachScreenBlocks(side, bp -> resp.add(tes.getWorld().getBlockState(bp).getValue(BlockScreen.emitting) ? "1" : "0")); + cb.success(resp.toString()); + } else + cb.failure(403, "Missing upgrade"); + }); + register("GetLocation", (cb, tes, side, args) -> { if(!tes.hasUpgrade(side, DefaultUpgrade.GPS)) { cb.failure(403, "Missing upgrade"); diff --git a/src/main/java/net/montoyo/wd/entity/TileEntityScreen.java b/src/main/java/net/montoyo/wd/entity/TileEntityScreen.java index 6d69de3..4b7ae0b 100644 --- a/src/main/java/net/montoyo/wd/entity/TileEntityScreen.java +++ b/src/main/java/net/montoyo/wd/entity/TileEntityScreen.java @@ -37,6 +37,7 @@ import net.montoyo.wd.utilities.Rotation; import javax.annotation.Nonnull; import javax.annotation.Nullable; import java.util.*; +import java.util.function.Consumer; public class TileEntityScreen extends TileEntity { @@ -167,27 +168,12 @@ public class TileEntityScreen extends TileEntity { } redstoneStatus = new NibbleArray(size.x * size.y); - final BlockPos.MutableBlockPos mbp = new BlockPos.MutableBlockPos(); - final Vector3i vec1 = new Vector3i(start); - final Vector3i vec2 = new Vector3i(); final EnumFacing facing = EnumFacing.VALUES[side.reverse().ordinal()]; + final ScreenIterator it = new ScreenIterator(start, side, size); - for(int y = 0; y < size.y; y++) { - final int base = y * size.x; - vec2.set(vec1); - - for(int x = 0; x < size.x; x++) { - vec2.toBlock(mbp); - - if(world.getBlockState(mbp).getValue(BlockScreen.emitting)) - redstoneStatus.set(base + x, 0); - else - redstoneStatus.set(base + x, world.getRedstonePower(mbp, facing)); - - vec2.add(side.right.x, side.right.y, side.right.z); - } - - vec1.add(side.up.x, side.up.y, side.up.z); + while(it.hasNext()) { + int idx = it.getIndex(); + redstoneStatus.set(idx, world.getRedstonePower(it.next(), facing)); } } @@ -207,6 +193,17 @@ public class TileEntityScreen extends TileEntity { } + public void forEachScreenBlocks(BlockSide side, Consumer func) { + Screen scr = getScreen(side); + + if(scr != null) { + ScreenIterator it = new ScreenIterator(pos, side, scr.size); + + while(it.hasNext()) + func.accept(it.next()); + } + } + private final ArrayList screens = new ArrayList<>(); private AxisAlignedBB renderBB = new AxisAlignedBB(0.0, 0.0, 0.0, 1.0, 1.0, 1.0); private boolean loaded = true; diff --git a/src/main/java/net/montoyo/wd/utilities/ScreenIterator.java b/src/main/java/net/montoyo/wd/utilities/ScreenIterator.java new file mode 100644 index 0000000..c4bcc59 --- /dev/null +++ b/src/main/java/net/montoyo/wd/utilities/ScreenIterator.java @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2018 BARBOTIN Nicolas + */ + +package net.montoyo.wd.utilities; + +import net.minecraft.util.math.BlockPos; + +import java.util.Iterator; + +public final class ScreenIterator implements Iterator { + + private final Vector3i vec1; + private final Vector3i vec2; + private final BlockSide side; + private final Vector2i size; + private final BlockPos.MutableBlockPos blockPos; + private int x = 0; + private int y = 0; + private boolean hasNext = true; + + public ScreenIterator(BlockPos pos, BlockSide side, Vector2i size) { + vec1 = new Vector3i(pos); + vec2 = vec1.clone(); + this.side = side; + this.size = size; + blockPos = new BlockPos.MutableBlockPos(); + } + + @Override + public final boolean hasNext() { + return hasNext; + } + + @Override + public final BlockPos next() { + vec2.toBlock(blockPos); + + if(++x >= size.x) { + if(++y >= size.y) + hasNext = false; + else { + x = 0; + vec2.set(vec1.add(side.up)); + } + } else + vec2.add(side.right); + + return blockPos; + } + + public int getX() { + return x; + } + + public int getY() { + return y; + } + + public int getIndex() { + return y * size.x + x; + } + +} diff --git a/src/main/resources/assets/webdisplays/html/io.html b/src/main/resources/assets/webdisplays/html/io.html index 3c45c4b..5c9cac7 100644 --- a/src/main/resources/assets/webdisplays/html/io.html +++ b/src/main/resources/assets/webdisplays/html/io.html @@ -50,8 +50,6 @@ var screenW = 1; var screenH = 1; var screenData = [ 0 ]; - var gotSize = false; - var gotData = false; var hasRedOutput = false; function generateTable() { @@ -112,30 +110,21 @@ wdGetSize(function(w, h) { screenW = w; screenH = h; - - if(gotData) - generateTable(); - else - gotSize = true; - }); - - wdGetRedstoneArray(function(array) { - screenData = array; - - if(gotSize) - generateTable(); - else - gotData = true; - }); - - wdGetUpgrades(function(upgrades) { - for(i = 0; i < upgrades.length; i++) { - if(upgrades[i] == "webdisplays:redoutput") { - hasRedOutput = true; - wdClearRedstone(); - break; - } - } + + wdGetRedstoneArray(function(array) { + screenData = array; + generateTable(); + + wdGetUpgrades(function(upgrades) { + for(i = 0; i < upgrades.length; i++) { + if(upgrades[i] == "webdisplays:redoutput") { + hasRedOutput = true; + fetchEmissionData(); + break; + } + } + }); + }); }); }); @@ -153,6 +142,22 @@ } } } + + function fetchEmissionData() { + wdGetEmissionArray(function(emission) { + for(y = 0; y < screenH; y++) { + for(x = 0; x < screenW; x++) { + var elem = $("#cell_" + x + "_" + y); + + if(emission[y * screenW + x]) { + if(!elem.hasClass("redstone_override")) + elem.addClass("redstone_override"); + } else if(elem.hasClass("redstone_override")) + elem.removeClass("redstone_override"); + } + } + }); + } diff --git a/src/main/resources/assets/webdisplays/html/wdlib.js b/src/main/resources/assets/webdisplays/html/wdlib.js index 07f050d..b4a6679 100644 --- a/src/main/resources/assets/webdisplays/html/wdlib.js +++ b/src/main/resources/assets/webdisplays/html/wdlib.js @@ -82,6 +82,24 @@ function wdSetRedstoneAt(x, y, state) { wdExecRequest("SetRedstoneAt(" + x + "," + y + "," + istate + ")", function(resp) { /* console.log(resp.status); */ }); } +//Requires upgrade: webdisplays:redoutput +function wdIsEmitting(x, y, callback) { + wdExecRequest("IsEmitting(" + x + "," + y + ")", function(resp) { + callback(resp.emitting); + }); +} + +//Requires upgrade: webdisplays:redoutput +function wdGetEmissionArray(callback) { + wdExecRequest("GetEmissionArray", function(resp) { + var emission = []; + for(i = 0; i < resp.emission.length; i++) + emission.push(resp.emission[i] != 0); + + callback(emission); + }); +} + //Requires upgrade: webdisplays:gps function wdGetLocation(callback) { wdExecRequest("GetLocation", function(resp) {