Multiple blocks and tiles can now be placed

- Different blocks can now be placed
  - Select block with (vertical) mouse wheel scrolling when block
placing is active
  - All blocks except Test:Air are available
- Different tiles can now be placed
  - Select tile with (vertical) mouse wheel scrolling when tile placing
is active
  - Switch between placing blocks and tiles with middle mouse button,
horizontal mouse scrolling or Shift + (vertical) mouse scrolling
- Changed Test GUI text color to white to increase readability on blocks
This commit is contained in:
OLEGSHA 2021-01-06 23:25:05 +03:00
parent 339e11d3ac
commit c919ffc8ce
5 changed files with 202 additions and 13 deletions

View File

@ -2,20 +2,27 @@ package ru.windcorp.progressia.test;
import glm.vec._3.i.Vec3i; import glm.vec._3.i.Vec3i;
import ru.windcorp.progressia.common.comms.controls.ControlData; import ru.windcorp.progressia.common.comms.controls.ControlData;
import ru.windcorp.progressia.common.world.block.BlockData;
public class ControlPlaceBlockData extends ControlData { public class ControlPlaceBlockData extends ControlData {
private BlockData block;
private final Vec3i blockInWorld = new Vec3i(); private final Vec3i blockInWorld = new Vec3i();
public ControlPlaceBlockData(String id) { public ControlPlaceBlockData(String id) {
super(id); super(id);
} }
public BlockData getBlock() {
return block;
}
public Vec3i getBlockInWorld() { public Vec3i getBlockInWorld() {
return blockInWorld; return blockInWorld;
} }
public void setBlockInWorld(Vec3i blockInWorld) { public void set(BlockData block, Vec3i blockInWorld) {
this.block = block;
this.blockInWorld.set(blockInWorld.x, blockInWorld.y, blockInWorld.z); this.blockInWorld.set(blockInWorld.x, blockInWorld.y, blockInWorld.z);
} }

View File

@ -0,0 +1,36 @@
package ru.windcorp.progressia.test;
import glm.vec._3.i.Vec3i;
import ru.windcorp.progressia.common.comms.controls.ControlData;
import ru.windcorp.progressia.common.world.block.BlockFace;
import ru.windcorp.progressia.common.world.tile.TileData;
public class ControlPlaceTileData extends ControlData {
private TileData tile;
private final Vec3i blockInWorld = new Vec3i();
private BlockFace face;
public ControlPlaceTileData(String id) {
super(id);
}
public TileData getTile() {
return tile;
}
public Vec3i getBlockInWorld() {
return blockInWorld;
}
public BlockFace getFace() {
return face;
}
public void set(TileData block, Vec3i blockInWorld, BlockFace face) {
this.tile = block;
this.blockInWorld.set(blockInWorld.x, blockInWorld.y, blockInWorld.z);
this.face = face;
}
}

View File

@ -22,8 +22,10 @@ import java.util.Collection;
import java.util.function.Supplier; import java.util.function.Supplier;
import glm.vec._3.Vec3; import glm.vec._3.Vec3;
import glm.vec._4.Vec4;
import ru.windcorp.progressia.client.Client; import ru.windcorp.progressia.client.Client;
import ru.windcorp.progressia.client.ClientState; import ru.windcorp.progressia.client.ClientState;
import ru.windcorp.progressia.client.graphics.Colors;
import ru.windcorp.progressia.client.graphics.backend.GraphicsInterface; import ru.windcorp.progressia.client.graphics.backend.GraphicsInterface;
import ru.windcorp.progressia.client.graphics.font.Font; import ru.windcorp.progressia.client.graphics.font.Font;
import ru.windcorp.progressia.client.graphics.gui.DynamicLabel; import ru.windcorp.progressia.client.graphics.gui.DynamicLabel;
@ -45,51 +47,75 @@ public class LayerTestGUI extends GUILayer {
Panel panel = new Panel("ControlDisplays", new LayoutVertical(5)); Panel panel = new Panel("ControlDisplays", new LayoutVertical(5));
Collection<Label> labels = new ArrayList<>(); Collection<Label> labels = new ArrayList<>();
Vec4 color = Colors.WHITE;
Font font = new Font().withColor(color).deriveShadow();
panel.addChild(new Label( panel.addChild(new Label(
"IsFlyingDisplay", new Font().withColor(0xFF37A3E6).deriveShadow(), "IsFlyingDisplay", font,
() -> String.format("Flying: %5s (Space bar x2)", TestPlayerControls.getInstance().isFlying()) () -> String.format("Flying: %5s (Space bar x2)", TestPlayerControls.getInstance().isFlying())
)); ));
panel.addChild(new Label( panel.addChild(new Label(
"IsMouseCapturedDisplay", new Font().withColor(0xFF37A3E6).deriveShadow(), "IsMouseCapturedDisplay", font,
() -> String.format("Mouse captured: %5s (esc)", TestPlayerControls.getInstance().isMouseCaptured()) () -> String.format("Mouse captured: %5s (esc)", TestPlayerControls.getInstance().isMouseCaptured())
)); ));
panel.addChild(new Label( panel.addChild(new Label(
"CameraModeDisplay", new Font().withColor(0xFF37A3E6).deriveShadow(), "CameraModeDisplay", font,
() -> String.format("Camera mode: %5d (F5)", ClientState.getInstance().getCamera().getCurrentModeIndex()) () -> String.format("Camera mode: %5d (F5)", ClientState.getInstance().getCamera().getCurrentModeIndex())
)); ));
panel.addChild(new Label( panel.addChild(new Label(
"GravityModeDisplay", new Font().withColor(0xFF37A3E6).deriveShadow(), "GravityModeDisplay", font,
() -> String.format("Gravity: %9s (G)", TestPlayerControls.getInstance().useMinecraftGravity() ? "Minecraft" : "Realistic") () -> String.format("Gravity: %9s (G)", TestPlayerControls.getInstance().useMinecraftGravity() ? "Minecraft" : "Realistic")
)); ));
panel.addChild(new DynamicLabel( panel.addChild(new DynamicLabel(
"FPSDisplay", new Font().withColor(0xFF37A3E6).deriveShadow(), "FPSDisplay", font,
DynamicStrings.builder().add("FPS: ").addDyn(() -> FPS_RECORD.update(GraphicsInterface.getFPS()), 5, 1).buildSupplier(), DynamicStrings.builder().add("FPS: ").addDyn(() -> FPS_RECORD.update(GraphicsInterface.getFPS()), 5, 1).buildSupplier(),
128 128
)); ));
panel.addChild(new DynamicLabel( panel.addChild(new DynamicLabel(
"TPSDisplay", new Font().withColor(0xFF37A3E6).deriveShadow(), "TPSDisplay", font,
LayerTestGUI::getTPS, LayerTestGUI::getTPS,
128 128
)); ));
panel.addChild(new DynamicLabel( panel.addChild(new DynamicLabel(
"ChunkUpdatesDisplay", new Font().withColor(0xFF37A3E6).deriveShadow(), "ChunkUpdatesDisplay", font,
DynamicStrings.builder().addConst("Pending updates: ").addDyn(ClientState.getInstance().getWorld()::getPendingChunkUpdates).buildSupplier(), DynamicStrings.builder().addConst("Pending updates: ").addDyn(ClientState.getInstance().getWorld()::getPendingChunkUpdates).buildSupplier(),
128 128
)); ));
panel.addChild(new DynamicLabel( panel.addChild(new DynamicLabel(
"PosDisplay", new Font().withColor(0xFF37A3E6).deriveShadow(), "PosDisplay", font,
LayerTestGUI::getPos, LayerTestGUI::getPos,
128 128
)); ));
panel.addChild(new Label(
"SelectedBlockDisplay", font,
() -> String.format(
"%s Block: %s",
TestPlayerControls.getInstance().isBlockSelected() ? ">" : " ",
TestPlayerControls.getInstance().getSelectedBlock().getId()
)
));
panel.addChild(new Label(
"SelectedTileDisplay", font,
() -> String.format(
"%s Tile: %s",
TestPlayerControls.getInstance().isBlockSelected() ? " " : ">",
TestPlayerControls.getInstance().getSelectedTile().getId()
)
));
panel.addChild(new Label(
"SelectedTileDisplay", font,
"(Blocks ↔ Tiles: Shift + Mouse Wheel)"
));
panel.getChildren().forEach(c -> { panel.getChildren().forEach(c -> {
if (c instanceof Label) { if (c instanceof Label) {
labels.add((Label) c); labels.add((Label) c);

View File

@ -3,6 +3,11 @@ package ru.windcorp.progressia.test;
import static ru.windcorp.progressia.client.world.block.BlockRenderRegistry.getBlockTexture; import static ru.windcorp.progressia.client.world.block.BlockRenderRegistry.getBlockTexture;
import static ru.windcorp.progressia.client.world.tile.TileRenderRegistry.getTileTexture; import static ru.windcorp.progressia.client.world.tile.TileRenderRegistry.getTileTexture;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Consumer; import java.util.function.Consumer;
import org.lwjgl.glfw.GLFW; import org.lwjgl.glfw.GLFW;
@ -39,6 +44,9 @@ public class TestContent {
public static final long STATIE_ENTITY_ID = 0xDEADBEEF; public static final long STATIE_ENTITY_ID = 0xDEADBEEF;
public static final Vec3 SPAWN = new Vec3(8, 8, 880); public static final Vec3 SPAWN = new Vec3(8, 8, 880);
public static final List<BlockData> PLACEABLE_BLOCKS = new ArrayList<>();
public static final List<TileData> PLACEABLE_TILES = new ArrayList<>();
public static void registerContent() { public static void registerContent() {
registerWorldContent(); registerWorldContent();
regsiterControls(); regsiterControls();
@ -52,6 +60,8 @@ public class TestContent {
} }
private static void registerBlocks() { private static void registerBlocks() {
Set<String> placeableBlacklist = new HashSet<>();
register(new BlockData("Test:Air") { register(new BlockData("Test:Air") {
@Override @Override
public CollisionModel getCollisionModel() { public CollisionModel getCollisionModel() {
@ -60,6 +70,7 @@ public class TestContent {
}); });
register(new BlockRenderNone("Test:Air")); register(new BlockRenderNone("Test:Air"));
register(new TestBlockLogicAir("Test:Air")); register(new TestBlockLogicAir("Test:Air"));
placeableBlacklist.add("Test:Air");
register(new BlockData("Test:Dirt")); register(new BlockData("Test:Dirt"));
register(new BlockRenderOpaqueCube("Test:Dirt", getBlockTexture("dirt"))); register(new BlockRenderOpaqueCube("Test:Dirt", getBlockTexture("dirt")));
@ -76,9 +87,15 @@ public class TestContent {
register(new BlockRenderOpaqueCube(id, getBlockTexture("granite_" + type.toLowerCase()))); register(new BlockRenderOpaqueCube(id, getBlockTexture("granite_" + type.toLowerCase())));
register(new BlockLogic(id)); register(new BlockLogic(id));
} }
BlockDataRegistry.getInstance().values().forEach(PLACEABLE_BLOCKS::add);
PLACEABLE_BLOCKS.removeIf(b -> placeableBlacklist.contains(b.getId()));
PLACEABLE_BLOCKS.sort(Comparator.comparing(BlockData::getId));
} }
private static void registerTiles() { private static void registerTiles() {
Set<String> placeableBlacklist = new HashSet<>();
register(new TileData("Test:Grass")); register(new TileData("Test:Grass"));
register(new TileRenderGrass("Test:Grass", getTileTexture("grass_top"), getTileTexture("grass_side"))); register(new TileRenderGrass("Test:Grass", getTileTexture("grass_top"), getTileTexture("grass_side")));
register(new TestTileLogicGrass("Test:Grass")); register(new TestTileLogicGrass("Test:Grass"));
@ -106,6 +123,10 @@ public class TestContent {
register(new TileData("Test:SnowQuarter")); register(new TileData("Test:SnowQuarter"));
register(new TileRenderSimple("Test:SnowQuarter", getTileTexture("snow_quarter"))); register(new TileRenderSimple("Test:SnowQuarter", getTileTexture("snow_quarter")));
register(new HangingTileLogic("Test:SnowQuarter")); register(new HangingTileLogic("Test:SnowQuarter"));
TileDataRegistry.getInstance().values().forEach(PLACEABLE_TILES::add);
PLACEABLE_TILES.removeIf(b -> placeableBlacklist.contains(b.getId()));
PLACEABLE_TILES.sort(Comparator.comparing(TileData::getId));
} }
private static void registerEntities() { private static void registerEntities() {
@ -140,9 +161,19 @@ public class TestContent {
KeyEvent.class, KeyEvent.class,
TestContent::onBlockPlaceTrigger, TestContent::onBlockPlaceTrigger,
KeyMatcher.of(GLFW.GLFW_MOUSE_BUTTON_RIGHT).matcher(), KeyMatcher.of(GLFW.GLFW_MOUSE_BUTTON_RIGHT).matcher(),
i -> getSelection().exists() i -> getSelection().exists() && TestPlayerControls.getInstance().isBlockSelected()
)); ));
logic.register(ControlLogic.of("Test:PlaceBlock", TestContent::onBlockPlaceReceived)); logic.register(ControlLogic.of("Test:PlaceBlock", TestContent::onBlockPlaceReceived));
data.register("Test:PlaceTile", ControlPlaceTileData::new);
triggers.register(ControlTriggers.of(
"Test:PlaceTile",
KeyEvent.class,
TestContent::onTilePlaceTrigger,
KeyMatcher.of(GLFW.GLFW_MOUSE_BUTTON_RIGHT).matcher(),
i -> getSelection().exists() && !TestPlayerControls.getInstance().isBlockSelected()
));
logic.register(ControlLogic.of("Test:PlaceTile", TestContent::onTilePlaceReceived));
} }
private static void register(BlockData x) { private static void register(BlockData x) {
@ -219,15 +250,37 @@ public class TestContent {
} }
private static void onBlockPlaceTrigger(ControlData control) { private static void onBlockPlaceTrigger(ControlData control) {
((ControlPlaceBlockData) control).setBlockInWorld( ((ControlPlaceBlockData) control).set(
TestPlayerControls.getInstance().getSelectedBlock(),
getSelection().getBlock().add_(getSelection().getSurface().getVector()) getSelection().getBlock().add_(getSelection().getSurface().getVector())
); );
} }
private static void onBlockPlaceReceived(Server server, PacketControl packet, ru.windcorp.progressia.server.comms.Client client) { private static void onBlockPlaceReceived(Server server, PacketControl packet, ru.windcorp.progressia.server.comms.Client client) {
Vec3i blockInWorld = ((ControlPlaceBlockData) packet.getControl()).getBlockInWorld(); ControlPlaceBlockData controlData = ((ControlPlaceBlockData) packet.getControl());
BlockData block = controlData.getBlock();
Vec3i blockInWorld = controlData.getBlockInWorld();
if (server.getWorld().getData().getChunkByBlock(blockInWorld) == null) return; if (server.getWorld().getData().getChunkByBlock(blockInWorld) == null) return;
server.getWorldAccessor().setBlock(blockInWorld, BlockDataRegistry.getInstance().get("Test:Stone")); server.getWorldAccessor().setBlock(blockInWorld, block);
}
private static void onTilePlaceTrigger(ControlData control) {
((ControlPlaceTileData) control).set(
TestPlayerControls.getInstance().getSelectedTile(),
getSelection().getBlock(),
getSelection().getSurface()
);
}
private static void onTilePlaceReceived(Server server, PacketControl packet, ru.windcorp.progressia.server.comms.Client client) {
ControlPlaceTileData controlData = ((ControlPlaceTileData) packet.getControl());
TileData tile = controlData.getTile();
Vec3i blockInWorld = controlData.getBlockInWorld();
BlockFace face = controlData.getFace();
if (server.getWorld().getData().getChunkByBlock(blockInWorld) == null) return;
if (server.getWorld().getData().getTiles(blockInWorld, face).isFull()) return;
server.getWorldAccessor().addTile(blockInWorld, face, tile);
} }
private static void registerMisc() { private static void registerMisc() {

View File

@ -9,14 +9,18 @@ import glm.vec._3.Vec3;
import ru.windcorp.progressia.client.ClientState; import ru.windcorp.progressia.client.ClientState;
import ru.windcorp.progressia.client.graphics.backend.GraphicsBackend; import ru.windcorp.progressia.client.graphics.backend.GraphicsBackend;
import ru.windcorp.progressia.client.graphics.backend.GraphicsInterface; import ru.windcorp.progressia.client.graphics.backend.GraphicsInterface;
import ru.windcorp.progressia.client.graphics.backend.InputTracker;
import ru.windcorp.progressia.client.graphics.input.CursorMoveEvent; import ru.windcorp.progressia.client.graphics.input.CursorMoveEvent;
import ru.windcorp.progressia.client.graphics.input.InputEvent; import ru.windcorp.progressia.client.graphics.input.InputEvent;
import ru.windcorp.progressia.client.graphics.input.KeyEvent; import ru.windcorp.progressia.client.graphics.input.KeyEvent;
import ru.windcorp.progressia.client.graphics.input.WheelScrollEvent;
import ru.windcorp.progressia.client.graphics.input.bus.Input; import ru.windcorp.progressia.client.graphics.input.bus.Input;
import ru.windcorp.progressia.client.graphics.world.LocalPlayer; import ru.windcorp.progressia.client.graphics.world.LocalPlayer;
import ru.windcorp.progressia.common.Units; import ru.windcorp.progressia.common.Units;
import ru.windcorp.progressia.common.util.FloatMathUtils; import ru.windcorp.progressia.common.util.FloatMathUtils;
import ru.windcorp.progressia.common.world.block.BlockData;
import ru.windcorp.progressia.common.world.entity.EntityData; import ru.windcorp.progressia.common.world.entity.EntityData;
import ru.windcorp.progressia.common.world.tile.TileData;
import ru.windcorp.progressia.server.ServerState; import ru.windcorp.progressia.server.ServerState;
public class TestPlayerControls { public class TestPlayerControls {
@ -58,6 +62,10 @@ public class TestPlayerControls {
private boolean captureMouse = true; private boolean captureMouse = true;
private boolean useMinecraftGravity = false; private boolean useMinecraftGravity = false;
private int selectedBlock = 0;
private int selectedTile = 0;
private boolean isBlockSelected = true;
private Runnable updateCallback = null; private Runnable updateCallback = null;
public void applyPlayerControls() { public void applyPlayerControls() {
@ -116,6 +124,9 @@ public class TestPlayerControls {
} else if (event instanceof CursorMoveEvent) { } else if (event instanceof CursorMoveEvent) {
onMouseMoved((CursorMoveEvent) event); onMouseMoved((CursorMoveEvent) event);
input.consume(); input.consume();
} else if (event instanceof WheelScrollEvent) {
onWheelScroll((WheelScrollEvent) event);
input.consume();
} }
} }
@ -159,6 +170,11 @@ public class TestPlayerControls {
handleGravitySwitch(); handleGravitySwitch();
break; break;
case GLFW.GLFW_MOUSE_BUTTON_3:
if (!event.isPress()) return false;
switchPlacingMode();
break;
default: default:
return false; return false;
} }
@ -256,6 +272,45 @@ public class TestPlayerControls {
dir.y, -FloatMathUtils.PI_F/2, +FloatMathUtils.PI_F/2 dir.y, -FloatMathUtils.PI_F/2, +FloatMathUtils.PI_F/2
); );
} }
private void onWheelScroll(WheelScrollEvent event) {
if (event.hasHorizontalMovement()) {
switchPlacingMode();
}
if (InputTracker.isKeyPressed(GLFW.GLFW_KEY_LEFT_SHIFT)) {
switchPlacingMode();
return;
}
if (isBlockSelected) {
selectedBlock += event.isUp() ? +1 : -1;
int size = TestContent.PLACEABLE_BLOCKS.size();
if (selectedBlock < 0) {
selectedBlock = size - 1;
} else if (selectedBlock >= size) {
selectedBlock = 0;
}
} else {
selectedTile += event.isUp() ? +1 : -1;
int size = TestContent.PLACEABLE_TILES.size();
if (selectedTile < 0) {
selectedTile = size - 1;
} else if (selectedTile >= size) {
selectedTile = 0;
}
}
updateGUI();
}
private void switchPlacingMode() {
isBlockSelected = !isBlockSelected;
updateGUI();
}
public EntityData getEntity() { public EntityData getEntity() {
return getPlayer().getEntity(); return getPlayer().getEntity();
@ -287,4 +342,16 @@ public class TestPlayerControls {
return useMinecraftGravity; return useMinecraftGravity;
} }
public BlockData getSelectedBlock() {
return TestContent.PLACEABLE_BLOCKS.get(selectedBlock);
}
public TileData getSelectedTile() {
return TestContent.PLACEABLE_TILES.get(selectedTile);
}
public boolean isBlockSelected() {
return isBlockSelected;
}
} }