From 01595f3228b861f3132ba3173ee7225de5575a64 Mon Sep 17 00:00:00 2001 From: austin Date: Tue, 15 Apr 2025 21:06:07 -0400 Subject: [PATCH] fix shovel + dig script function --- assets/Scripts/client/clienthooks.ts | 2 +- docs/src/progress/renderertodo.md | 2 + .../client/interact/ItemActions.java | 21 +++++-- .../client/script/ScriptClientVoxelUtils.java | 13 ++-- .../terrain/editing/TerrainEditing.java | 5 +- .../parser/net/message/NetworkMessage.java | 5 ++ .../parser/net/message/TerrainMessage.java | 61 +++++++++++++++++++ .../net/parser/net/message/TypeBytes.java | 24 ++++---- .../net/server/protocol/TerrainProtocol.java | 15 +++++ .../terrain/editing/TerrainEditing.java | 59 ++++++++++++++++++ src/net/terrain.json | 11 ++++ 11 files changed, 194 insertions(+), 24 deletions(-) diff --git a/assets/Scripts/client/clienthooks.ts b/assets/Scripts/client/clienthooks.ts index 00b3241e..9ebe39af 100644 --- a/assets/Scripts/client/clienthooks.ts +++ b/assets/Scripts/client/clienthooks.ts @@ -44,7 +44,7 @@ export const clientHooks: Hook[] = [ { signal: "DIG", callback: (engine: Engine) => { - engine.classes.voxelUtils.static.applyEdit() + engine.classes.voxelUtils.static.dig() } } ] \ No newline at end of file diff --git a/docs/src/progress/renderertodo.md b/docs/src/progress/renderertodo.md index b7e6f5cb..c55ae7fb 100644 --- a/docs/src/progress/renderertodo.md +++ b/docs/src/progress/renderertodo.md @@ -1501,6 +1501,8 @@ Clarify content serialization pipelines for character vs non-character entities Server send disconnect packet on disconnection Associate each server connection with a character ID Code cleanup +Fix dig script function +Fix shovel functionality diff --git a/src/main/java/electrosphere/client/interact/ItemActions.java b/src/main/java/electrosphere/client/interact/ItemActions.java index 3ecbfc91..f4cdb43f 100644 --- a/src/main/java/electrosphere/client/interact/ItemActions.java +++ b/src/main/java/electrosphere/client/interact/ItemActions.java @@ -19,18 +19,29 @@ import electrosphere.net.parser.net.message.InventoryMessage; */ public class ItemActions { - //the item action code for left clicking + /** + * the item action code for left clicking + */ public static final int ITEM_ACTION_CODE_PRIMARY = 0; - //the item action code for right clicking + + /** + * the item action code for right clicking + */ public static final int ITEM_ACTION_CODE_SECONDARY = 1; - //the state for performing the item action code + /** + * the state for performing the item action code + */ public static final int ITEM_ACTION_CODE_STATE_ON = 1; - //the state for releasing the item action code + /** + * the state for releasing the item action code + */ public static final int ITEM_ACTION_CODE_STATE_OFF = 0; - //the state for performing the item action code + /** + * the state for performing the item action code + */ public static final int ITEM_ACTION_CODE_STATE_REPEAT = 2; /** diff --git a/src/main/java/electrosphere/client/script/ScriptClientVoxelUtils.java b/src/main/java/electrosphere/client/script/ScriptClientVoxelUtils.java index b72122ab..e2217a05 100644 --- a/src/main/java/electrosphere/client/script/ScriptClientVoxelUtils.java +++ b/src/main/java/electrosphere/client/script/ScriptClientVoxelUtils.java @@ -21,7 +21,14 @@ public class ScriptClientVoxelUtils { */ static final float EDIT_INCREMENT = 0.1f; - //vertical offset from cursor position to spawn things at + /** + * Increment to remove terrain by + */ + static final float REMOVE_INCREMENT = -0.1f; + + /** + * vertical offset from cursor position to spawn things at + */ static final Vector3d cursorVerticalOffset = new Vector3d(0,0.05,0); /** @@ -100,9 +107,7 @@ public class ScriptClientVoxelUtils { if(cursorPos == null){ cursorPos = new Vector3d(centerPos).add(new Vector3d(eyePos).mul(-CollisionEngine.DEFAULT_INTERACT_DISTANCE)); } - if(Globals.clientSelectedVoxelType != null){ - TerrainEditing.removeTerrainGated(cursorPos, 1.1f, Globals.clientSelectedVoxelType.getId(), EDIT_INCREMENT); - } + TerrainEditing.removeTerrainGated(cursorPos, 1.1f, REMOVE_INCREMENT); } } diff --git a/src/main/java/electrosphere/client/terrain/editing/TerrainEditing.java b/src/main/java/electrosphere/client/terrain/editing/TerrainEditing.java index 09f3db11..b40b8b21 100644 --- a/src/main/java/electrosphere/client/terrain/editing/TerrainEditing.java +++ b/src/main/java/electrosphere/client/terrain/editing/TerrainEditing.java @@ -70,12 +70,11 @@ public class TerrainEditing { * Tries to remove terrain with proper game logic checks applied * @param position The position to perform the edit * @param editMagnitude The magnitude of the edit to perform - * @param type The type of block to make all edited blocks * @param weight The weight of the sphere to apply the edit to */ - public static void removeTerrainGated(Vector3d position, float editMagnitude, int type, float weight){ + public static void removeTerrainGated(Vector3d position, float editMagnitude, float weight){ if(position != null){ - Globals.clientConnection.queueOutgoingMessage(TerrainMessage.constructRequestUseTerrainPaletteMessage(position.x, position.y, position.z, editMagnitude, weight, type)); + Globals.clientConnection.queueOutgoingMessage(TerrainMessage.constructRequestDestroyTerrainMessage(position.x, position.y, position.z, editMagnitude, weight)); } } diff --git a/src/main/java/electrosphere/net/parser/net/message/NetworkMessage.java b/src/main/java/electrosphere/net/parser/net/message/NetworkMessage.java index 5d39887f..73d354b7 100644 --- a/src/main/java/electrosphere/net/parser/net/message/NetworkMessage.java +++ b/src/main/java/electrosphere/net/parser/net/message/NetworkMessage.java @@ -185,6 +185,11 @@ public abstract class NetworkMessage { rVal = TerrainMessage.parseRequestUseTerrainPaletteMessage(byteBuffer,pool); } break; + case TypeBytes.TERRAIN_MESSAGE_TYPE_REQUESTDESTROYTERRAIN: + if(TerrainMessage.canParseMessage(byteBuffer,secondByte)){ + rVal = TerrainMessage.parseRequestDestroyTerrainMessage(byteBuffer,pool); + } + break; case TypeBytes.TERRAIN_MESSAGE_TYPE_SPAWNPOSITION: if(TerrainMessage.canParseMessage(byteBuffer,secondByte)){ rVal = TerrainMessage.parseSpawnPositionMessage(byteBuffer,pool); diff --git a/src/main/java/electrosphere/net/parser/net/message/TerrainMessage.java b/src/main/java/electrosphere/net/parser/net/message/TerrainMessage.java index b59628a1..8f9cbfdb 100644 --- a/src/main/java/electrosphere/net/parser/net/message/TerrainMessage.java +++ b/src/main/java/electrosphere/net/parser/net/message/TerrainMessage.java @@ -16,6 +16,7 @@ public class TerrainMessage extends NetworkMessage { REQUESTEDITVOXEL, UPDATEVOXEL, REQUESTUSETERRAINPALETTE, + REQUESTDESTROYTERRAIN, SPAWNPOSITION, REQUESTCHUNKDATA, SENDCHUNKDATA, @@ -490,6 +491,12 @@ public class TerrainMessage extends NetworkMessage { } else { return false; } + case TypeBytes.TERRAIN_MESSAGE_TYPE_REQUESTDESTROYTERRAIN: + if(byteBuffer.getRemaining() >= TypeBytes.TERRAIN_MESSAGE_TYPE_REQUESTDESTROYTERRAIN_SIZE){ + return true; + } else { + return false; + } case TypeBytes.TERRAIN_MESSAGE_TYPE_SPAWNPOSITION: if(byteBuffer.getRemaining() >= TypeBytes.TERRAIN_MESSAGE_TYPE_SPAWNPOSITION_SIZE){ return true; @@ -693,6 +700,35 @@ public class TerrainMessage extends NetworkMessage { return rVal; } + /** + * Parses a message of type RequestDestroyTerrain + */ + public static TerrainMessage parseRequestDestroyTerrainMessage(CircularByteBuffer byteBuffer, MessagePool pool){ + TerrainMessage rVal = (TerrainMessage)pool.get(MessageType.TERRAIN_MESSAGE); + rVal.messageType = TerrainMessageType.REQUESTDESTROYTERRAIN; + TerrainMessage.stripPacketHeader(byteBuffer); + rVal.setrealLocationX(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer)); + rVal.setrealLocationY(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer)); + rVal.setrealLocationZ(ByteStreamUtils.popDoubleFromByteQueue(byteBuffer)); + rVal.setvalue(ByteStreamUtils.popFloatFromByteQueue(byteBuffer)); + rVal.setterrainWeight(ByteStreamUtils.popFloatFromByteQueue(byteBuffer)); + return rVal; + } + + /** + * Constructs a message of type RequestDestroyTerrain + */ + public static TerrainMessage constructRequestDestroyTerrainMessage(double realLocationX,double realLocationY,double realLocationZ,float value,float terrainWeight){ + TerrainMessage rVal = new TerrainMessage(TerrainMessageType.REQUESTDESTROYTERRAIN); + rVal.setrealLocationX(realLocationX); + rVal.setrealLocationY(realLocationY); + rVal.setrealLocationZ(realLocationZ); + rVal.setvalue(value); + rVal.setterrainWeight(terrainWeight); + rVal.serialize(); + return rVal; + } + /** * Parses a message of type SpawnPosition */ @@ -1318,6 +1354,31 @@ public class TerrainMessage extends NetworkMessage { rawBytes[34+i] = intValues[i]; } break; + case REQUESTDESTROYTERRAIN: + rawBytes = new byte[2+8+8+8+4+4]; + //message header + rawBytes[0] = TypeBytes.MESSAGE_TYPE_TERRAIN; + //entity messaage header + rawBytes[1] = TypeBytes.TERRAIN_MESSAGE_TYPE_REQUESTDESTROYTERRAIN; + intValues = ByteStreamUtils.serializeDoubleToBytes(realLocationX); + for(int i = 0; i < 8; i++){ + rawBytes[2+i] = intValues[i]; + } + intValues = ByteStreamUtils.serializeDoubleToBytes(realLocationY); + for(int i = 0; i < 8; i++){ + rawBytes[10+i] = intValues[i]; + } + intValues = ByteStreamUtils.serializeDoubleToBytes(realLocationZ); + for(int i = 0; i < 8; i++){ + rawBytes[18+i] = intValues[i]; + } + intValues = ByteStreamUtils.serializeFloatToBytes(value); + for(int i = 0; i < 4; i++){ + rawBytes[26+i] = intValues[i]; + } intValues = ByteStreamUtils.serializeFloatToBytes(terrainWeight); + for(int i = 0; i < 4; i++){ + rawBytes[30+i] = intValues[i]; + } break; case SPAWNPOSITION: rawBytes = new byte[2+8+8+8]; //message header diff --git a/src/main/java/electrosphere/net/parser/net/message/TypeBytes.java b/src/main/java/electrosphere/net/parser/net/message/TypeBytes.java index 4d320ab2..1b695b12 100644 --- a/src/main/java/electrosphere/net/parser/net/message/TypeBytes.java +++ b/src/main/java/electrosphere/net/parser/net/message/TypeBytes.java @@ -72,17 +72,18 @@ public class TypeBytes { public static final byte TERRAIN_MESSAGE_TYPE_REQUESTEDITVOXEL = 2; public static final byte TERRAIN_MESSAGE_TYPE_UPDATEVOXEL = 3; public static final byte TERRAIN_MESSAGE_TYPE_REQUESTUSETERRAINPALETTE = 4; - public static final byte TERRAIN_MESSAGE_TYPE_SPAWNPOSITION = 5; - public static final byte TERRAIN_MESSAGE_TYPE_REQUESTCHUNKDATA = 6; - public static final byte TERRAIN_MESSAGE_TYPE_SENDCHUNKDATA = 7; - public static final byte TERRAIN_MESSAGE_TYPE_REQUESTREDUCEDCHUNKDATA = 8; - public static final byte TERRAIN_MESSAGE_TYPE_SENDREDUCEDCHUNKDATA = 9; - public static final byte TERRAIN_MESSAGE_TYPE_REQUESTREDUCEDBLOCKDATA = 10; - public static final byte TERRAIN_MESSAGE_TYPE_SENDREDUCEDBLOCKDATA = 11; - public static final byte TERRAIN_MESSAGE_TYPE_UPDATEBLOCK = 12; - public static final byte TERRAIN_MESSAGE_TYPE_REQUESTFLUIDDATA = 13; - public static final byte TERRAIN_MESSAGE_TYPE_SENDFLUIDDATA = 14; - public static final byte TERRAIN_MESSAGE_TYPE_UPDATEFLUIDDATA = 15; + public static final byte TERRAIN_MESSAGE_TYPE_REQUESTDESTROYTERRAIN = 5; + public static final byte TERRAIN_MESSAGE_TYPE_SPAWNPOSITION = 6; + public static final byte TERRAIN_MESSAGE_TYPE_REQUESTCHUNKDATA = 7; + public static final byte TERRAIN_MESSAGE_TYPE_SENDCHUNKDATA = 8; + public static final byte TERRAIN_MESSAGE_TYPE_REQUESTREDUCEDCHUNKDATA = 9; + public static final byte TERRAIN_MESSAGE_TYPE_SENDREDUCEDCHUNKDATA = 10; + public static final byte TERRAIN_MESSAGE_TYPE_REQUESTREDUCEDBLOCKDATA = 11; + public static final byte TERRAIN_MESSAGE_TYPE_SENDREDUCEDBLOCKDATA = 12; + public static final byte TERRAIN_MESSAGE_TYPE_UPDATEBLOCK = 13; + public static final byte TERRAIN_MESSAGE_TYPE_REQUESTFLUIDDATA = 14; + public static final byte TERRAIN_MESSAGE_TYPE_SENDFLUIDDATA = 15; + public static final byte TERRAIN_MESSAGE_TYPE_UPDATEFLUIDDATA = 16; /* Terrain packet sizes */ @@ -91,6 +92,7 @@ public class TypeBytes { public static final byte TERRAIN_MESSAGE_TYPE_REQUESTEDITVOXEL_SIZE = 34; public static final byte TERRAIN_MESSAGE_TYPE_UPDATEVOXEL_SIZE = 34; public static final byte TERRAIN_MESSAGE_TYPE_REQUESTUSETERRAINPALETTE_SIZE = 38; + public static final byte TERRAIN_MESSAGE_TYPE_REQUESTDESTROYTERRAIN_SIZE = 34; public static final byte TERRAIN_MESSAGE_TYPE_SPAWNPOSITION_SIZE = 26; public static final byte TERRAIN_MESSAGE_TYPE_REQUESTCHUNKDATA_SIZE = 14; public static final byte TERRAIN_MESSAGE_TYPE_REQUESTREDUCEDCHUNKDATA_SIZE = 18; diff --git a/src/main/java/electrosphere/net/server/protocol/TerrainProtocol.java b/src/main/java/electrosphere/net/server/protocol/TerrainProtocol.java index 3b33980a..a2e7f324 100644 --- a/src/main/java/electrosphere/net/server/protocol/TerrainProtocol.java +++ b/src/main/java/electrosphere/net/server/protocol/TerrainProtocol.java @@ -70,6 +70,9 @@ public class TerrainProtocol implements ServerProtocolTemplate { case REQUESTUSETERRAINPALETTE: { TerrainProtocol.attemptUseTerrainEditPalette(connectionHandler, message); } break; + case REQUESTDESTROYTERRAIN: { + TerrainProtocol.attemptDestroyTerrain(connectionHandler, message); + } break; case REQUESTFLUIDDATA: { LoggerInterface.loggerNetworking.DEBUG("(Server) Received request for fluid " + message.getworldX() + " " + message.getworldY() + " " + message.getworldZ()); // System.out.println("Received request for fluid " + message.getworldX() + " " + message.getworldY() + " " + message.getworldZ()); @@ -424,6 +427,18 @@ public class TerrainProtocol implements ServerProtocolTemplate { TerrainEditing.editTerrain(realm, location, message.getvalue(), message.getterrainValue(), message.getterrainWeight()); } + /** + * Attempts to destroy terrain + * @param connectionHandler The connection handler + * @param message The message that contains the request to use an edit palette + */ + static void attemptDestroyTerrain(ServerConnectionHandler connectionHandler, TerrainMessage message){ + Player player = Globals.playerManager.getPlayerFromId(connectionHandler.getPlayerId()); + Realm realm = Globals.realmManager.getPlayerRealm(player); + Vector3d location = new Vector3d(message.getrealLocationX(), message.getrealLocationY(), message.getrealLocationZ()); + TerrainEditing.destroyTerrain(realm, location, message.getvalue(), message.getterrainWeight()); + } + /** * Constructs a buffer to send a fluid chunk to the client * @param chunk The chunk to send diff --git a/src/main/java/electrosphere/server/terrain/editing/TerrainEditing.java b/src/main/java/electrosphere/server/terrain/editing/TerrainEditing.java index f8235f92..553c3299 100644 --- a/src/main/java/electrosphere/server/terrain/editing/TerrainEditing.java +++ b/src/main/java/electrosphere/server/terrain/editing/TerrainEditing.java @@ -74,4 +74,63 @@ public class TerrainEditing { } } + /** + * Performs a terrain chunk edit. Basically has a sphere around the provided position that it attempts to remove value from. + * @param position The position to perform the edit + * @param editMagnitude The magnitude of the edit to perform + * @param weight The weight of the sphere to apply the edit to + */ + public static void destroyTerrain(Realm realm, Vector3d position, float editMagnitude, float weight){ + if(position != null && realm != null && realm.getDataCellManager() instanceof VoxelCellManager){ + VoxelCellManager voxelCellManager = (VoxelCellManager) realm.getDataCellManager(); + //calculate kernel size + int numPlacesToCheck = (int)((editMagnitude * 2 + 1) * (editMagnitude * 2 + 1) * (editMagnitude * 2 + 1)); + //create and fill in kernel of positions to check + int[] xOffsetSet = new int[numPlacesToCheck]; + int[] yOffsetSet = new int[numPlacesToCheck]; + int[] zOffsetSet = new int[numPlacesToCheck]; + int i = 0; + for(int x = -(int)editMagnitude; x <= (int)editMagnitude; x++){ + for(int y = -(int)editMagnitude; y <= (int)editMagnitude; y++){ + for(int z = -(int)editMagnitude; z <= (int)editMagnitude; z++){ + xOffsetSet[i] = x; + yOffsetSet[i] = y; + zOffsetSet[i] = z; + i++; + } + } + } + for(i = 0; i < numPlacesToCheck; i++){ + //calculate position of edit + Vector3d offsetPos = new Vector3d(position).add(xOffsetSet[i],yOffsetSet[i],zOffsetSet[i]); + Vector3i chunkPos = realm.getServerWorldData().convertRealToWorldSpace(offsetPos); + Vector3i voxelPos = realm.getServerWorldData().convertRealToVoxelSpace(offsetPos); + //get distance from true center point of sphere to current voxel position in world space + float distance = (float)new Vector3d(Math.floor(offsetPos.x),Math.floor(offsetPos.y),Math.floor(offsetPos.z)).distance(position); + float currentPositionMagnitude = editMagnitude - distance; + + ServerTerrainChunk data; + if( + voxelPos.x < ServerTerrainChunk.CHUNK_DIMENSION && + voxelPos.y < ServerTerrainChunk.CHUNK_DIMENSION && + voxelPos.z < ServerTerrainChunk.CHUNK_DIMENSION && + voxelPos.x >= 0 && + voxelPos.y >= 0 && + voxelPos.z >= 0 && + currentPositionMagnitude > 0 && + (data = voxelCellManager.getChunkAtPosition(chunkPos)) != null + ){ + float current = data.getWeights()[voxelPos.x][voxelPos.y][voxelPos.z]; + //hard clamp so it doesn't go over 1 + float finalValue = Math.max(Math.min(current + weight / distance,1),-1); + if(finalValue < MINIMUM_FULL_VALUE && current > MINIMUM_FULL_VALUE){ + finalValue = -1; + } + int typeAtPos = voxelCellManager.getVoxelTypeAtLocalPosition(chunkPos, voxelPos); + voxelCellManager.editChunk(chunkPos, voxelPos, finalValue, typeAtPos); + } + } + } + } + } diff --git a/src/net/terrain.json b/src/net/terrain.json index 6e4e1c77..e7950be1 100644 --- a/src/net/terrain.json +++ b/src/net/terrain.json @@ -185,6 +185,17 @@ "terrainValue" ] }, + { + "messageName" : "RequestDestroyTerrain", + "description" : "Requests that the current player entity destroys voxels in a radius around a position using a given weight", + "data" : [ + "realLocationX", + "realLocationY", + "realLocationZ", + "value", + "terrainWeight" + ] + }, { "messageName" : "SpawnPosition", "description" : "Sets the spawn position of the client",