work on placing blocks
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit
Some checks failed
studiorailgun/Renderer/pipeline/head There was a failure building this commit
This commit is contained in:
parent
34959ae83e
commit
bb886bcf12
@ -131,6 +131,14 @@ public class BlockChunkData {
|
||||
return rVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocates the arrays in a given homogenous data chunk
|
||||
*/
|
||||
private void allocateFromHomogenous(){
|
||||
this.setType(new short[CHUNK_DATA_WIDTH * CHUNK_DATA_WIDTH * CHUNK_DATA_WIDTH]);
|
||||
this.setMetadata(new short[CHUNK_DATA_WIDTH * CHUNK_DATA_WIDTH * CHUNK_DATA_WIDTH]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the type data for the chunk
|
||||
* @return The type data
|
||||
@ -179,6 +187,9 @@ public class BlockChunkData {
|
||||
* @return The type at that position
|
||||
*/
|
||||
public short getType(int x, int y, int z){
|
||||
if(this.type == null){
|
||||
this.allocateFromHomogenous();
|
||||
}
|
||||
return this.type[x * CHUNK_DATA_WIDTH * CHUNK_DATA_WIDTH + z * CHUNK_DATA_WIDTH + y];
|
||||
}
|
||||
|
||||
@ -190,6 +201,9 @@ public class BlockChunkData {
|
||||
* @param type The type
|
||||
*/
|
||||
public void setType(int x, int y, int z, short type){
|
||||
if(this.type == null){
|
||||
this.allocateFromHomogenous();
|
||||
}
|
||||
this.type[x * CHUNK_DATA_WIDTH * CHUNK_DATA_WIDTH + z * CHUNK_DATA_WIDTH + y] = type;
|
||||
}
|
||||
|
||||
@ -201,9 +215,40 @@ public class BlockChunkData {
|
||||
* @param type The type
|
||||
*/
|
||||
public void setType(int x, int y, int z, int type){
|
||||
if(this.type == null){
|
||||
this.allocateFromHomogenous();
|
||||
}
|
||||
this.type[x * CHUNK_DATA_WIDTH * CHUNK_DATA_WIDTH + z * CHUNK_DATA_WIDTH + y] = (short)type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a specific block's metadata
|
||||
* @param x The x position
|
||||
* @param y The y position
|
||||
* @param z The z position
|
||||
* @param metadata The metadata
|
||||
*/
|
||||
public void setMetadata(int x, int y, int z, short metadata){
|
||||
if(this.metadata == null){
|
||||
this.allocateFromHomogenous();
|
||||
}
|
||||
this.metadata[x * CHUNK_DATA_WIDTH * CHUNK_DATA_WIDTH + z * CHUNK_DATA_WIDTH + y] = metadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a specific block's metadata
|
||||
* @param x The x position
|
||||
* @param y The y position
|
||||
* @param z The z position
|
||||
* @param metadata The metadata
|
||||
*/
|
||||
public void setMetadata(int x, int y, int z, int metadata){
|
||||
if(this.metadata == null){
|
||||
this.allocateFromHomogenous();
|
||||
}
|
||||
this.metadata[x * CHUNK_DATA_WIDTH * CHUNK_DATA_WIDTH + z * CHUNK_DATA_WIDTH + y] = (short)metadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the metadata at a given position
|
||||
* @param x The x position
|
||||
@ -212,6 +257,9 @@ public class BlockChunkData {
|
||||
* @return The metadata at that position
|
||||
*/
|
||||
public short getMetadata(int x, int y, int z){
|
||||
if(this.metadata == null){
|
||||
this.allocateFromHomogenous();
|
||||
}
|
||||
return this.metadata[x * CHUNK_DATA_WIDTH * CHUNK_DATA_WIDTH + z * CHUNK_DATA_WIDTH + y];
|
||||
}
|
||||
|
||||
|
||||
@ -684,6 +684,18 @@ public class ClientBlockCellManager {
|
||||
drawCell.setHasRequested(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Marks a draw cell as homogenous or not
|
||||
* @param worldX The world x position
|
||||
* @param worldY The world y position
|
||||
* @param worldZ The world z position
|
||||
*/
|
||||
public void markHomogenous(int worldX, int worldY, int worldZ, boolean homogenous){
|
||||
BlockDrawCell drawCell = this.getDrawCell(worldX, worldY, worldZ);
|
||||
drawCell.ejectChunkData();
|
||||
drawCell.setHomogenous(homogenous);
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests all chunks for a given draw cell
|
||||
* @param cell The cell
|
||||
|
||||
@ -131,6 +131,18 @@ public class ServerToolbarState implements BehaviorTree {
|
||||
if(targetPoint.getEquipClassWhitelist() != null && !targetPoint.getEquipClassWhitelist().contains(equipItemClass)){
|
||||
targetPoint = equipInventoryState.getEquipPointFromSlot(toolbarData.getCombinedSlot());
|
||||
}
|
||||
|
||||
if(targetPoint == null){
|
||||
EquipPoint discoveredPoint = equipInventoryState.getEquipPointFromSlot(toolbarData.getPrimarySlot());
|
||||
String message =
|
||||
"Failed to visually equip item slot!\n" +
|
||||
"Primary Slot: " + toolbarData.getPrimarySlot() + "\n" +
|
||||
"Discovered point: " + discoveredPoint.getBone() + "\n" +
|
||||
"Item Class Whitelist: " + discoveredPoint.getEquipClassWhitelist() + "\n" +
|
||||
"Equipped item class: " + equipItemClass
|
||||
;
|
||||
throw new Error(message);
|
||||
}
|
||||
|
||||
//
|
||||
//Visual transforms
|
||||
|
||||
@ -138,6 +138,10 @@ public class Item extends CommonEntityType {
|
||||
meshUniformMap.put(RenderUtils.MESH_NAME_BLOCK_SINGLE,uniforms);
|
||||
modelData.setUniforms(meshUniformMap);
|
||||
|
||||
//set item class
|
||||
rVal.equipData = new EquipData();
|
||||
rVal.equipData.equipClass = "tool";
|
||||
|
||||
|
||||
//set usage
|
||||
ItemUsage usage = new ItemUsage();
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package electrosphere.game.server.world;
|
||||
|
||||
import electrosphere.client.block.BlockChunkData;
|
||||
import electrosphere.server.block.manager.ServerBlockManager;
|
||||
import electrosphere.server.fluid.generation.DefaultFluidGenerator;
|
||||
import electrosphere.server.fluid.manager.ServerFluidManager;
|
||||
@ -208,6 +209,15 @@ public class ServerWorldData {
|
||||
return chunk * ServerTerrainChunk.CHUNK_DIMENSION;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a real position to a local block grid position
|
||||
* @param real The real position
|
||||
* @return The local block grid position
|
||||
*/
|
||||
public int convertRealToLocalBlockSpace(double real){
|
||||
return (int)Math.floor(real * BlockChunkData.BLOCKS_PER_UNIT_DISTANCE % BlockChunkData.CHUNK_DATA_WIDTH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a chunk space coordinate to a real space coordinate
|
||||
* @param chunk The position within the chunk
|
||||
@ -277,6 +287,19 @@ public class ServerWorldData {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a real coordinate to a local block grid space coordinate
|
||||
* @param position The real coordinate
|
||||
* @return The local block grid space coordinate
|
||||
*/
|
||||
public Vector3i convertRealToLocalBlockSpace(Vector3d position){
|
||||
return new Vector3i(
|
||||
convertRealToLocalBlockSpace(position.x),
|
||||
convertRealToLocalBlockSpace(position.y),
|
||||
convertRealToLocalBlockSpace(position.z)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a world coordinate to a macro scale coordinate
|
||||
* @param worldPos The world position
|
||||
|
||||
@ -7,6 +7,7 @@ import java.util.List;
|
||||
import org.joml.Vector3f;
|
||||
import org.joml.Vector3i;
|
||||
|
||||
import electrosphere.client.block.BlockChunkData;
|
||||
import electrosphere.client.scene.ClientWorldData;
|
||||
import electrosphere.client.terrain.cache.ChunkData;
|
||||
import electrosphere.collision.CollisionWorldData;
|
||||
@ -172,6 +173,65 @@ public class TerrainProtocol implements ClientProtocolTemplate<TerrainMessage> {
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case UPDATEBLOCK: {
|
||||
//
|
||||
//find what all drawcells might be updated by this voxel update
|
||||
Vector3i worldPos = new Vector3i(message.getworldX(), message.getworldY(), message.getworldZ());
|
||||
List<Vector3i> positionsToUpdate = new LinkedList<Vector3i>();
|
||||
positionsToUpdate.add(worldPos);
|
||||
if(message.getvoxelX() < 1){
|
||||
positionsToUpdate.add(new Vector3i(worldPos).sub(1,0,0));
|
||||
if(message.getvoxelY() < 1){
|
||||
positionsToUpdate.add(new Vector3i(worldPos).sub(1,1,0));
|
||||
if(message.getvoxelZ() < 1){
|
||||
positionsToUpdate.add(new Vector3i(worldPos).sub(1,1,1));
|
||||
}
|
||||
} else {
|
||||
if(message.getvoxelZ() < 1){
|
||||
positionsToUpdate.add(new Vector3i(worldPos).sub(1,0,1));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(message.getvoxelY() < 1){
|
||||
positionsToUpdate.add(new Vector3i(worldPos).sub(0,1,0));
|
||||
if(message.getvoxelZ() < 1){
|
||||
positionsToUpdate.add(new Vector3i(worldPos).sub(0,1,1));
|
||||
}
|
||||
} else {
|
||||
if(message.getvoxelZ() < 1){
|
||||
positionsToUpdate.add(new Vector3i(worldPos).sub(0,0,1));
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
//update the block cache
|
||||
if(Globals.clientBlockManager.containsChunkDataAtWorldPoint(worldPos.x, worldPos.y, worldPos.z, ChunkData.NO_STRIDE)){
|
||||
BlockChunkData data = Globals.clientBlockManager.getChunkDataAtWorldPoint(worldPos.x, worldPos.y, worldPos.z, ChunkData.NO_STRIDE);
|
||||
if(data != null){
|
||||
data.setType(
|
||||
message.getvoxelX(),
|
||||
message.getvoxelY(),
|
||||
message.getvoxelZ(),
|
||||
message.getblockType()
|
||||
);
|
||||
data.setHomogenousValue(BlockChunkData.NOT_HOMOGENOUS);
|
||||
}
|
||||
}
|
||||
//
|
||||
//mark all relevant drawcells as updateable
|
||||
for(Vector3i worldPosToUpdate : positionsToUpdate){
|
||||
if(
|
||||
worldPosToUpdate.x >= 0 && worldPosToUpdate.x < Globals.clientWorldData.getWorldDiscreteSize() &&
|
||||
worldPosToUpdate.y >= 0 && worldPosToUpdate.y < Globals.clientWorldData.getWorldDiscreteSize() &&
|
||||
worldPosToUpdate.z >= 0 && worldPosToUpdate.z < Globals.clientWorldData.getWorldDiscreteSize()
|
||||
){
|
||||
//
|
||||
//mark terrain chunk for update
|
||||
Globals.clientBlockCellManager.markUpdateable(worldPosToUpdate.x, worldPosToUpdate.y, worldPosToUpdate.z);
|
||||
Globals.clientBlockCellManager.markHomogenous(worldPosToUpdate.x, worldPosToUpdate.y, worldPosToUpdate.z, false);
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case SENDFLUIDDATA: {
|
||||
Globals.clientFluidManager.attachFluidMessage(message);
|
||||
} break;
|
||||
|
||||
@ -214,6 +214,11 @@ public abstract class NetworkMessage {
|
||||
rVal = TerrainMessage.parseSendReducedBlockDataMessage(byteBuffer);
|
||||
}
|
||||
break;
|
||||
case TypeBytes.TERRAIN_MESSAGE_TYPE_UPDATEBLOCK:
|
||||
if(TerrainMessage.canParseMessage(byteBuffer,secondByte)){
|
||||
rVal = TerrainMessage.parseUpdateBlockMessage(byteBuffer);
|
||||
}
|
||||
break;
|
||||
case TypeBytes.TERRAIN_MESSAGE_TYPE_REQUESTFLUIDDATA:
|
||||
if(TerrainMessage.canParseMessage(byteBuffer,secondByte)){
|
||||
rVal = TerrainMessage.parseRequestFluidDataMessage(byteBuffer);
|
||||
|
||||
@ -23,6 +23,7 @@ public class TerrainMessage extends NetworkMessage {
|
||||
SENDREDUCEDCHUNKDATA,
|
||||
REQUESTREDUCEDBLOCKDATA,
|
||||
SENDREDUCEDBLOCKDATA,
|
||||
UPDATEBLOCK,
|
||||
REQUESTFLUIDDATA,
|
||||
SENDFLUIDDATA,
|
||||
UPDATEFLUIDDATA,
|
||||
@ -56,6 +57,8 @@ public class TerrainMessage extends NetworkMessage {
|
||||
int chunkResolution;
|
||||
float terrainWeight;
|
||||
int terrainValue;
|
||||
int blockType;
|
||||
int blockMetadata;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
@ -406,6 +409,34 @@ public class TerrainMessage extends NetworkMessage {
|
||||
this.terrainValue = terrainValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets blockType
|
||||
*/
|
||||
public int getblockType() {
|
||||
return blockType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets blockType
|
||||
*/
|
||||
public void setblockType(int blockType) {
|
||||
this.blockType = blockType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets blockMetadata
|
||||
*/
|
||||
public int getblockMetadata() {
|
||||
return blockMetadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets blockMetadata
|
||||
*/
|
||||
public void setblockMetadata(int blockMetadata) {
|
||||
this.blockMetadata = blockMetadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the packet header from the buffer
|
||||
* @param byteBuffer The buffer
|
||||
@ -482,6 +513,12 @@ public class TerrainMessage extends NetworkMessage {
|
||||
}
|
||||
case TypeBytes.TERRAIN_MESSAGE_TYPE_SENDREDUCEDBLOCKDATA:
|
||||
return TerrainMessage.canParseSendReducedBlockDataMessage(byteBuffer);
|
||||
case TypeBytes.TERRAIN_MESSAGE_TYPE_UPDATEBLOCK:
|
||||
if(byteBuffer.getRemaining() >= TypeBytes.TERRAIN_MESSAGE_TYPE_UPDATEBLOCK_SIZE){
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
case TypeBytes.TERRAIN_MESSAGE_TYPE_REQUESTFLUIDDATA:
|
||||
if(byteBuffer.getRemaining() >= TypeBytes.TERRAIN_MESSAGE_TYPE_REQUESTFLUIDDATA_SIZE){
|
||||
return true;
|
||||
@ -935,6 +972,40 @@ public class TerrainMessage extends NetworkMessage {
|
||||
return rVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a message of type UpdateBlock
|
||||
*/
|
||||
public static TerrainMessage parseUpdateBlockMessage(CircularByteBuffer byteBuffer){
|
||||
TerrainMessage rVal = new TerrainMessage(TerrainMessageType.UPDATEBLOCK);
|
||||
stripPacketHeader(byteBuffer);
|
||||
rVal.setworldX(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
rVal.setworldY(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
rVal.setworldZ(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
rVal.setvoxelX(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
rVal.setvoxelY(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
rVal.setvoxelZ(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
rVal.setblockType(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
rVal.setblockMetadata(ByteStreamUtils.popIntFromByteQueue(byteBuffer));
|
||||
return rVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a message of type UpdateBlock
|
||||
*/
|
||||
public static TerrainMessage constructUpdateBlockMessage(int worldX,int worldY,int worldZ,int voxelX,int voxelY,int voxelZ,int blockType,int blockMetadata){
|
||||
TerrainMessage rVal = new TerrainMessage(TerrainMessageType.UPDATEBLOCK);
|
||||
rVal.setworldX(worldX);
|
||||
rVal.setworldY(worldY);
|
||||
rVal.setworldZ(worldZ);
|
||||
rVal.setvoxelX(voxelX);
|
||||
rVal.setvoxelY(voxelY);
|
||||
rVal.setvoxelZ(voxelZ);
|
||||
rVal.setblockType(blockType);
|
||||
rVal.setblockMetadata(blockMetadata);
|
||||
rVal.serialize();
|
||||
return rVal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a message of type RequestFluidData
|
||||
*/
|
||||
@ -1402,6 +1473,45 @@ public class TerrainMessage extends NetworkMessage {
|
||||
rawBytes[26+i] = chunkData[i];
|
||||
}
|
||||
break;
|
||||
case UPDATEBLOCK:
|
||||
rawBytes = new byte[2+4+4+4+4+4+4+4+4];
|
||||
//message header
|
||||
rawBytes[0] = TypeBytes.MESSAGE_TYPE_TERRAIN;
|
||||
//entity messaage header
|
||||
rawBytes[1] = TypeBytes.TERRAIN_MESSAGE_TYPE_UPDATEBLOCK;
|
||||
intValues = ByteStreamUtils.serializeIntToBytes(worldX);
|
||||
for(int i = 0; i < 4; i++){
|
||||
rawBytes[2+i] = intValues[i];
|
||||
}
|
||||
intValues = ByteStreamUtils.serializeIntToBytes(worldY);
|
||||
for(int i = 0; i < 4; i++){
|
||||
rawBytes[6+i] = intValues[i];
|
||||
}
|
||||
intValues = ByteStreamUtils.serializeIntToBytes(worldZ);
|
||||
for(int i = 0; i < 4; i++){
|
||||
rawBytes[10+i] = intValues[i];
|
||||
}
|
||||
intValues = ByteStreamUtils.serializeIntToBytes(voxelX);
|
||||
for(int i = 0; i < 4; i++){
|
||||
rawBytes[14+i] = intValues[i];
|
||||
}
|
||||
intValues = ByteStreamUtils.serializeIntToBytes(voxelY);
|
||||
for(int i = 0; i < 4; i++){
|
||||
rawBytes[18+i] = intValues[i];
|
||||
}
|
||||
intValues = ByteStreamUtils.serializeIntToBytes(voxelZ);
|
||||
for(int i = 0; i < 4; i++){
|
||||
rawBytes[22+i] = intValues[i];
|
||||
}
|
||||
intValues = ByteStreamUtils.serializeIntToBytes(blockType);
|
||||
for(int i = 0; i < 4; i++){
|
||||
rawBytes[26+i] = intValues[i];
|
||||
}
|
||||
intValues = ByteStreamUtils.serializeIntToBytes(blockMetadata);
|
||||
for(int i = 0; i < 4; i++){
|
||||
rawBytes[30+i] = intValues[i];
|
||||
}
|
||||
break;
|
||||
case REQUESTFLUIDDATA:
|
||||
rawBytes = new byte[2+4+4+4];
|
||||
//message header
|
||||
|
||||
@ -78,9 +78,10 @@ public class TypeBytes {
|
||||
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_REQUESTFLUIDDATA = 12;
|
||||
public static final byte TERRAIN_MESSAGE_TYPE_SENDFLUIDDATA = 13;
|
||||
public static final byte TERRAIN_MESSAGE_TYPE_UPDATEFLUIDDATA = 14;
|
||||
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;
|
||||
/*
|
||||
Terrain packet sizes
|
||||
*/
|
||||
@ -93,6 +94,7 @@ public class TypeBytes {
|
||||
public static final byte TERRAIN_MESSAGE_TYPE_REQUESTCHUNKDATA_SIZE = 14;
|
||||
public static final byte TERRAIN_MESSAGE_TYPE_REQUESTREDUCEDCHUNKDATA_SIZE = 18;
|
||||
public static final byte TERRAIN_MESSAGE_TYPE_REQUESTREDUCEDBLOCKDATA_SIZE = 18;
|
||||
public static final byte TERRAIN_MESSAGE_TYPE_UPDATEBLOCK_SIZE = 34;
|
||||
public static final byte TERRAIN_MESSAGE_TYPE_REQUESTFLUIDDATA_SIZE = 14;
|
||||
|
||||
/*
|
||||
|
||||
@ -82,6 +82,7 @@ public class TerrainProtocol implements ServerProtocolTemplate<TerrainMessage> {
|
||||
case RESPONSEMETADATA:
|
||||
case SPAWNPOSITION:
|
||||
case UPDATEVOXEL:
|
||||
case UPDATEBLOCK:
|
||||
case SENDCHUNKDATA:
|
||||
case SENDFLUIDDATA:
|
||||
case REQUESTREDUCEDCHUNKDATA:
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
package electrosphere.server.block.editing;
|
||||
|
||||
import org.joml.Vector3d;
|
||||
import org.joml.Vector3i;
|
||||
|
||||
import electrosphere.client.block.BlockChunkData;
|
||||
import electrosphere.server.datacell.Realm;
|
||||
import electrosphere.server.datacell.interfaces.VoxelCellManager;
|
||||
|
||||
/**
|
||||
* Provides utilities for editing block (particularly brushes, etc)
|
||||
@ -23,8 +24,24 @@ public class ServerBlockEditing {
|
||||
* @param type The new type of block
|
||||
* @param metadata The new metadata for the block
|
||||
*/
|
||||
public static void editBlockChunk(Realm realm, Vector3d worldPos, Vector3i voxelPos, short type, short metadata){
|
||||
throw new UnsupportedOperationException("Unimplemented");
|
||||
public static void editBlockChunk(Realm realm, Vector3i worldPos, Vector3i voxelPos, short type, short metadata){
|
||||
if(realm != null && realm.getDataCellManager() instanceof VoxelCellManager){
|
||||
VoxelCellManager voxelCellManager = (VoxelCellManager) realm.getDataCellManager();
|
||||
|
||||
BlockChunkData data;
|
||||
if(
|
||||
voxelPos.x < BlockChunkData.CHUNK_DATA_WIDTH &&
|
||||
voxelPos.y < BlockChunkData.CHUNK_DATA_WIDTH &&
|
||||
voxelPos.z < BlockChunkData.CHUNK_DATA_WIDTH &&
|
||||
voxelPos.x >= 0 &&
|
||||
voxelPos.y >= 0 &&
|
||||
voxelPos.z >= 0 &&
|
||||
(data = voxelCellManager.getBlocksAtPosition(worldPos)) != null
|
||||
){
|
||||
data.setType(voxelPos.x, voxelPos.y, voxelPos.z, type);
|
||||
voxelCellManager.editBlock(worldPos, voxelPos, type, metadata);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -174,7 +174,8 @@ public class ServerBlockManager {
|
||||
if(chunkCache.containsChunk(worldPos.x,worldPos.y,worldPos.z,BlockChunkData.LOD_FULL_RES)){
|
||||
BlockChunkData chunk = chunkCache.get(worldPos.x,worldPos.y,worldPos.z, BlockChunkData.LOD_FULL_RES);
|
||||
chunk.setType(voxelPos.x, voxelPos.y, voxelPos.z, type);
|
||||
chunk.setType(voxelPos.x, voxelPos.y, voxelPos.z, metadata);
|
||||
chunk.setMetadata(voxelPos.x, voxelPos.y, voxelPos.z, metadata);
|
||||
chunk.setHomogenousValue(BlockChunkData.NOT_HOMOGENOUS);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -30,6 +30,7 @@ import electrosphere.net.parser.net.message.EntityMessage;
|
||||
import electrosphere.net.parser.net.message.TerrainMessage;
|
||||
import electrosphere.net.server.player.Player;
|
||||
import electrosphere.net.server.protocol.TerrainProtocol;
|
||||
import electrosphere.server.block.manager.ServerBlockManager;
|
||||
import electrosphere.server.content.ServerContentManager;
|
||||
import electrosphere.server.datacell.interfaces.DataCellManager;
|
||||
import electrosphere.server.datacell.interfaces.VoxelCellManager;
|
||||
@ -872,4 +873,49 @@ public class GriddedDataCellManager implements DataCellManager, VoxelCellManager
|
||||
generationService.shutdownNow();
|
||||
}
|
||||
|
||||
@Override
|
||||
/**
|
||||
* Gets the block chunk data at a given world position
|
||||
*/
|
||||
public BlockChunkData getBlocksAtPosition(Vector3i worldPosition) {
|
||||
return this.serverWorldData.getServerBlockManager().getChunk(worldPosition.x, worldPosition.y, worldPosition.z);
|
||||
}
|
||||
|
||||
@Override
|
||||
/**
|
||||
* Edits a block chunk in the world
|
||||
*/
|
||||
public void editBlock(Vector3i worldPosition, Vector3i voxelPosition, short type, short metadata) {
|
||||
terrainEditLock.acquireUninterruptibly();
|
||||
if(
|
||||
worldPosition.x >= 0 && worldPosition.x < this.serverWorldData.getWorldSizeDiscrete() &&
|
||||
worldPosition.y >= 0 && worldPosition.y < this.serverWorldData.getWorldSizeDiscrete() &&
|
||||
worldPosition.z >= 0 && worldPosition.z < this.serverWorldData.getWorldSizeDiscrete()
|
||||
){
|
||||
ServerBlockManager serverBlockManager = this.serverWorldData.getServerBlockManager();
|
||||
//update terrain
|
||||
int localVoxelX = voxelPosition.x;
|
||||
int localVoxelY = voxelPosition.y;
|
||||
int localVoxelZ = voxelPosition.z;
|
||||
serverBlockManager.editBlockAtLocationToValue(worldPosition, voxelPosition, type, metadata);
|
||||
|
||||
//update anything loaded
|
||||
this.loadedCellsLock.lock();
|
||||
ServerDataCell cell = groundDataCells.get(this.getServerDataCellKey(worldPosition));
|
||||
if(cell != null){
|
||||
//update physics
|
||||
this.createTerrainPhysicsEntities(worldPosition);
|
||||
|
||||
//broadcast update
|
||||
cell.broadcastNetworkMessage(TerrainMessage.constructUpdateBlockMessage(
|
||||
worldPosition.x, worldPosition.y, worldPosition.z,
|
||||
localVoxelX, localVoxelY, localVoxelZ,
|
||||
type, metadata
|
||||
));
|
||||
}
|
||||
this.loadedCellsLock.unlock();
|
||||
}
|
||||
terrainEditLock.release();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@ package electrosphere.server.datacell.interfaces;
|
||||
|
||||
import org.joml.Vector3i;
|
||||
|
||||
import electrosphere.client.block.BlockChunkData;
|
||||
import electrosphere.server.fluid.manager.ServerFluidChunk;
|
||||
import electrosphere.server.terrain.manager.ServerTerrainChunk;
|
||||
|
||||
@ -42,6 +43,22 @@ public interface VoxelCellManager {
|
||||
*/
|
||||
public void editChunk(Vector3i worldPosition, Vector3i voxelPosition, float weight, int type);
|
||||
|
||||
/**
|
||||
* Gets the block data at a given world position
|
||||
* @param worldPosition The position in world coordinates
|
||||
* @return The BlockChunkData of data at that position, or null if it is out of bounds or otherwise doesn't exist
|
||||
*/
|
||||
public BlockChunkData getBlocksAtPosition(Vector3i worldPosition);
|
||||
|
||||
/**
|
||||
* Edits a single block voxel
|
||||
* @param worldPosition The world position of the block to edit
|
||||
* @param voxelPosition The local block grid position of the block to edit
|
||||
* @param type The type of block to set the position to
|
||||
* @param metadata The metadata associated with the block type
|
||||
*/
|
||||
public void editBlock(Vector3i worldPosition, Vector3i voxelPosition, short type, short metadata);
|
||||
|
||||
|
||||
/**
|
||||
* Gets the fluid chunk at a given world position
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package electrosphere.server.player;
|
||||
|
||||
import org.joml.Vector3d;
|
||||
import org.joml.Vector3i;
|
||||
|
||||
import electrosphere.client.item.ItemActions;
|
||||
import electrosphere.engine.Globals;
|
||||
@ -13,9 +14,11 @@ import electrosphere.game.data.creature.type.CreatureData;
|
||||
import electrosphere.game.data.creature.type.block.BlockVariant;
|
||||
import electrosphere.game.data.item.Item;
|
||||
import electrosphere.game.data.item.ItemUsage;
|
||||
import electrosphere.game.server.world.ServerWorldData;
|
||||
import electrosphere.logger.LoggerInterface;
|
||||
import electrosphere.net.parser.net.message.InventoryMessage;
|
||||
import electrosphere.net.server.ServerConnectionHandler;
|
||||
import electrosphere.server.block.editing.ServerBlockEditing;
|
||||
import electrosphere.server.datacell.Realm;
|
||||
import electrosphere.server.datacell.utils.EntityLookupUtils;
|
||||
|
||||
@ -83,16 +86,27 @@ public class PlayerActions {
|
||||
private static void secondaryUsage(Entity playerEntity, Item item, InventoryMessage message){
|
||||
ItemUsage secondaryUsage = item.getSecondaryUsage();
|
||||
Realm playerRealm = Globals.realmManager.getEntityRealm(playerEntity);
|
||||
|
||||
//entity spawning
|
||||
if(secondaryUsage.getSpawnEntityId() != null){
|
||||
Vector3d spawnPos = new Vector3d(message.getviewTargetX(),message.getviewTargetY(),message.getviewTargetZ());
|
||||
CommonEntityUtils.serverSpawnBasicObject(playerRealm, spawnPos, secondaryUsage.getSpawnEntityId());
|
||||
}
|
||||
|
||||
//voxel block editing
|
||||
if(secondaryUsage.getBlockId() != null){
|
||||
Vector3d spawnPos = new Vector3d(message.getviewTargetX(),message.getviewTargetY(),message.getviewTargetZ());
|
||||
LoggerInterface.loggerEngine.WARNING("Spawn block type " + secondaryUsage.getBlockId() + " at " + spawnPos);
|
||||
ServerWorldData serverWorldData = playerRealm.getServerWorldData();
|
||||
|
||||
//clamp the placement pos to the block grid..
|
||||
Vector3d placementPos = new Vector3d(message.getviewTargetX(),message.getviewTargetY(),message.getviewTargetZ());
|
||||
Vector3i worldPos = serverWorldData.convertRealToWorldSpace(placementPos);
|
||||
Vector3i blockPos = serverWorldData.convertRealToLocalBlockSpace(placementPos);
|
||||
|
||||
|
||||
//actually edit
|
||||
ServerBlockEditing.editBlockChunk(playerRealm, worldPos, blockPos, (short)(int)secondaryUsage.getBlockId(), (short)0);
|
||||
LoggerInterface.loggerEngine.DEBUG("Place block type " + secondaryUsage.getBlockId() + " at " + placementPos + " -> " + worldPos + " " + blockPos);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -115,6 +115,15 @@
|
||||
{
|
||||
"name" : "terrainValue",
|
||||
"type" : "FIXED_INT"
|
||||
},
|
||||
|
||||
{
|
||||
"name" : "blockType",
|
||||
"type" : "FIXED_INT"
|
||||
},
|
||||
{
|
||||
"name" : "blockMetadata",
|
||||
"type" : "FIXED_INT"
|
||||
}
|
||||
],
|
||||
"messageTypes" : [
|
||||
@ -249,6 +258,20 @@
|
||||
"chunkData"
|
||||
]
|
||||
},
|
||||
{
|
||||
"messageName" : "UpdateBlock",
|
||||
"description" : "Tells the client to update a voxel's value",
|
||||
"data" : [
|
||||
"worldX",
|
||||
"worldY",
|
||||
"worldZ",
|
||||
"voxelX",
|
||||
"voxelY",
|
||||
"voxelZ",
|
||||
"blockType",
|
||||
"blockMetadata"
|
||||
]
|
||||
},
|
||||
{
|
||||
"messageName" : "RequestFluidData",
|
||||
"description" : "Requests a fluid data from the server",
|
||||
|
||||
Loading…
Reference in New Issue
Block a user