mirror of https://github.com/Minestom/Minestom.git
custom block with custom hardness
This commit is contained in:
parent
57def5aaac
commit
0d40be1552
|
@ -7,7 +7,9 @@ import fr.adamaq01.ozao.net.server.ServerHandler;
|
||||||
import fr.adamaq01.ozao.net.server.backend.tcp.TCPServer;
|
import fr.adamaq01.ozao.net.server.backend.tcp.TCPServer;
|
||||||
import fr.themode.minestom.entity.EntityManager;
|
import fr.themode.minestom.entity.EntityManager;
|
||||||
import fr.themode.minestom.entity.Player;
|
import fr.themode.minestom.entity.Player;
|
||||||
|
import fr.themode.minestom.instance.BlockManager;
|
||||||
import fr.themode.minestom.instance.InstanceManager;
|
import fr.themode.minestom.instance.InstanceManager;
|
||||||
|
import fr.themode.minestom.instance.demo.StoneBlock;
|
||||||
import fr.themode.minestom.net.ConnectionManager;
|
import fr.themode.minestom.net.ConnectionManager;
|
||||||
import fr.themode.minestom.net.PacketProcessor;
|
import fr.themode.minestom.net.PacketProcessor;
|
||||||
import fr.themode.minestom.net.packet.server.play.DestroyEntitiesPacket;
|
import fr.themode.minestom.net.packet.server.play.DestroyEntitiesPacket;
|
||||||
|
@ -26,6 +28,7 @@ public class Main {
|
||||||
|
|
||||||
// In-Game Manager
|
// In-Game Manager
|
||||||
private static InstanceManager instanceManager;
|
private static InstanceManager instanceManager;
|
||||||
|
private static BlockManager blockManager;
|
||||||
private static EntityManager entityManager;
|
private static EntityManager entityManager;
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
|
@ -33,8 +36,11 @@ public class Main {
|
||||||
packetProcessor = new PacketProcessor();
|
packetProcessor = new PacketProcessor();
|
||||||
|
|
||||||
instanceManager = new InstanceManager();
|
instanceManager = new InstanceManager();
|
||||||
|
blockManager = new BlockManager();
|
||||||
entityManager = new EntityManager();
|
entityManager = new EntityManager();
|
||||||
|
|
||||||
|
blockManager.registerBlock("stone", StoneBlock::new);
|
||||||
|
|
||||||
server = new TCPServer(new MinecraftProtocol()).addHandler(new ServerHandler() {
|
server = new TCPServer(new MinecraftProtocol()).addHandler(new ServerHandler() {
|
||||||
@Override
|
@Override
|
||||||
public void onConnect(Server server, Connection connection) {
|
public void onConnect(Server server, Connection connection) {
|
||||||
|
@ -123,6 +129,10 @@ public class Main {
|
||||||
return instanceManager;
|
return instanceManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static BlockManager getBlockManager() {
|
||||||
|
return blockManager;
|
||||||
|
}
|
||||||
|
|
||||||
public static EntityManager getEntityManager() {
|
public static EntityManager getEntityManager() {
|
||||||
return entityManager;
|
return entityManager;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package fr.themode.minestom.entity;
|
package fr.themode.minestom.entity;
|
||||||
|
|
||||||
import fr.themode.minestom.Main;
|
import fr.themode.minestom.Main;
|
||||||
|
import fr.themode.minestom.instance.CustomBlock;
|
||||||
import fr.themode.minestom.inventory.Inventory;
|
import fr.themode.minestom.inventory.Inventory;
|
||||||
import fr.themode.minestom.inventory.PlayerInventory;
|
import fr.themode.minestom.inventory.PlayerInventory;
|
||||||
import fr.themode.minestom.item.ItemStack;
|
import fr.themode.minestom.item.ItemStack;
|
||||||
|
@ -25,6 +26,7 @@ public class Player extends LivingEntity {
|
||||||
private short heldSlot;
|
private short heldSlot;
|
||||||
private Inventory openInventory;
|
private Inventory openInventory;
|
||||||
|
|
||||||
|
private CustomBlock targetCustomBlock;
|
||||||
private Position targetBlockPosition;
|
private Position targetBlockPosition;
|
||||||
private long targetBlockTime;
|
private long targetBlockTime;
|
||||||
|
|
||||||
|
@ -41,20 +43,17 @@ public class Player extends LivingEntity {
|
||||||
public void update() {
|
public void update() {
|
||||||
|
|
||||||
// Target block stage
|
// Target block stage
|
||||||
if (instance != null && targetBlockPosition != null) {
|
if (instance != null && targetCustomBlock != null) {
|
||||||
int timeBreak = 750; // In ms
|
int timeBreak = targetCustomBlock.getBreakDelay(this);
|
||||||
int animationCount = 10;
|
int animationCount = 10;
|
||||||
long since = System.currentTimeMillis() - targetBlockTime;
|
long since = System.currentTimeMillis() - targetBlockTime;
|
||||||
byte stage = (byte) (since / (timeBreak / animationCount));
|
byte stage = (byte) (since / (timeBreak / animationCount));
|
||||||
BlockBreakAnimationPacket breakAnimationPacket = new BlockBreakAnimationPacket();
|
sendBlockBreakAnimation(targetBlockPosition, stage);// TODO send to all near players
|
||||||
breakAnimationPacket.entityId = getEntityId() + 1;
|
|
||||||
breakAnimationPacket.blockPosition = targetBlockPosition;
|
|
||||||
breakAnimationPacket.destroyStage = stage;
|
|
||||||
if (stage > 9) {
|
if (stage > 9) {
|
||||||
instance.setBlock(targetBlockPosition.getX(), targetBlockPosition.getY(), targetBlockPosition.getZ(), (short) 0);
|
instance.setBlock(targetBlockPosition.getX(), targetBlockPosition.getY(), targetBlockPosition.getZ(), (short) 0);
|
||||||
refreshTargetBlock(null);
|
testParticle(targetBlockPosition.getX() + 0.5f, targetBlockPosition.getY(), targetBlockPosition.getZ() + 0.5f);
|
||||||
|
resetTargetBlock();
|
||||||
}
|
}
|
||||||
playerConnection.sendPacket(breakAnimationPacket); // TODO send to all online players
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -74,6 +73,29 @@ public class Player extends LivingEntity {
|
||||||
playerConnection.sendPacket(new UpdateViewPositionPacket(Math.floorDiv((int) x, 16), Math.floorDiv((int) z, 16)));
|
playerConnection.sendPacket(new UpdateViewPositionPacket(Math.floorDiv((int) x, 16), Math.floorDiv((int) z, 16)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void sendBlockBreakAnimation(Position blockPosition, byte destroyStage) {
|
||||||
|
BlockBreakAnimationPacket breakAnimationPacket = new BlockBreakAnimationPacket();
|
||||||
|
breakAnimationPacket.entityId = getEntityId() + 1;
|
||||||
|
breakAnimationPacket.blockPosition = blockPosition;
|
||||||
|
breakAnimationPacket.destroyStage = destroyStage;
|
||||||
|
playerConnection.sendPacket(breakAnimationPacket);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void testParticle(float x, float y, float z) {
|
||||||
|
ParticlePacket particlePacket = new ParticlePacket();
|
||||||
|
particlePacket.particleId = 3; // Block particle
|
||||||
|
particlePacket.longDistance = false;
|
||||||
|
particlePacket.x = x;
|
||||||
|
particlePacket.y = y;
|
||||||
|
particlePacket.z = z;
|
||||||
|
particlePacket.offsetX = 0.55f;
|
||||||
|
particlePacket.offsetY = 0.75f;
|
||||||
|
particlePacket.offsetZ = 0.55f;
|
||||||
|
particlePacket.particleData = 0.25f;
|
||||||
|
particlePacket.particleCount = 100;
|
||||||
|
playerConnection.sendPacket(particlePacket);
|
||||||
|
}
|
||||||
|
|
||||||
public void sendMessage(String message) {
|
public void sendMessage(String message) {
|
||||||
ChatMessagePacket chatMessagePacket = new ChatMessagePacket("{\"text\": \"" + message + "\"}", ChatMessagePacket.Position.CHAT);
|
ChatMessagePacket chatMessagePacket = new ChatMessagePacket("{\"text\": \"" + message + "\"}", ChatMessagePacket.Position.CHAT);
|
||||||
playerConnection.sendPacket(chatMessagePacket);
|
playerConnection.sendPacket(chatMessagePacket);
|
||||||
|
@ -136,6 +158,10 @@ public class Player extends LivingEntity {
|
||||||
return openInventory;
|
return openInventory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CustomBlock getCustomBlockTarget() {
|
||||||
|
return targetCustomBlock;
|
||||||
|
}
|
||||||
|
|
||||||
public void openInventory(Inventory inventory) {
|
public void openInventory(Inventory inventory) {
|
||||||
if (inventory == null)
|
if (inventory == null)
|
||||||
throw new IllegalArgumentException("Inventory cannot be null, use Player#closeInventory() to close current");
|
throw new IllegalArgumentException("Inventory cannot be null, use Player#closeInventory() to close current");
|
||||||
|
@ -200,11 +226,18 @@ public class Player extends LivingEntity {
|
||||||
this.openInventory = openInventory;
|
this.openInventory = openInventory;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void refreshTargetBlock(Position targetBlockPosition) {
|
public void refreshTargetBlock(CustomBlock targetCustomBlock, Position targetBlockPosition) {
|
||||||
|
this.targetCustomBlock = targetCustomBlock;
|
||||||
this.targetBlockPosition = targetBlockPosition;
|
this.targetBlockPosition = targetBlockPosition;
|
||||||
this.targetBlockTime = targetBlockPosition == null ? 0 : System.currentTimeMillis();
|
this.targetBlockTime = targetBlockPosition == null ? 0 : System.currentTimeMillis();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void resetTargetBlock() {
|
||||||
|
this.targetCustomBlock = null;
|
||||||
|
this.targetBlockPosition = null;
|
||||||
|
this.targetBlockTime = 0;
|
||||||
|
}
|
||||||
|
|
||||||
public long getLastKeepAlive() {
|
public long getLastKeepAlive() {
|
||||||
return lastKeepAlive;
|
return lastKeepAlive;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
package fr.themode.minestom.instance;
|
|
||||||
|
|
||||||
public class Block {
|
|
||||||
|
|
||||||
private short type;
|
|
||||||
|
|
||||||
public Block(short type) {
|
|
||||||
this.type = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public short getType() {
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setType(short type) {
|
|
||||||
this.type = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return String.format("CustomBlock{type=%s}", type);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -59,7 +59,7 @@ public class BlockBatch {
|
||||||
private short blockId;
|
private short blockId;
|
||||||
|
|
||||||
public void apply(Chunk chunk) {
|
public void apply(Chunk chunk) {
|
||||||
chunk.setBlock(x, y, z, blockId);
|
chunk.setBlock((byte) x, (byte) y, (byte) z, blockId);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
package fr.themode.minestom.instance;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
public class BlockManager {
|
||||||
|
|
||||||
|
private Map<String, CustomBlock> blocks = new HashMap<>();
|
||||||
|
|
||||||
|
public void registerBlock(String id, Supplier<CustomBlock> blocks) {
|
||||||
|
this.blocks.put(id, blocks.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
public CustomBlock getBlock(String id) {
|
||||||
|
return this.blocks.get(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,21 +1,24 @@
|
||||||
package fr.themode.minestom.instance;
|
package fr.themode.minestom.instance;
|
||||||
|
|
||||||
|
import fr.themode.minestom.Main;
|
||||||
import fr.themode.minestom.entity.Entity;
|
import fr.themode.minestom.entity.Entity;
|
||||||
import fr.themode.minestom.entity.EntityCreature;
|
import fr.themode.minestom.entity.EntityCreature;
|
||||||
import fr.themode.minestom.entity.Player;
|
import fr.themode.minestom.entity.Player;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.CopyOnWriteArraySet;
|
import java.util.concurrent.CopyOnWriteArraySet;
|
||||||
|
|
||||||
public class Chunk {
|
public class Chunk {
|
||||||
|
|
||||||
|
private static final int CHUNK_SIZE = 16 * 256 * 16;
|
||||||
|
|
||||||
protected Set<EntityCreature> creatures = new CopyOnWriteArraySet<>();
|
protected Set<EntityCreature> creatures = new CopyOnWriteArraySet<>();
|
||||||
protected Set<Player> players = new CopyOnWriteArraySet<>();
|
protected Set<Player> players = new CopyOnWriteArraySet<>();
|
||||||
private int chunkX, chunkZ;
|
private int chunkX, chunkZ;
|
||||||
private Biome biome;
|
private Biome biome;
|
||||||
private HashMap<Short, Short> blocks = new HashMap<>(); // Index/BlockID
|
private short[] blocksId = new short[CHUNK_SIZE];
|
||||||
|
private String[] customBlocks = new String[CHUNK_SIZE];
|
||||||
|
|
||||||
public Chunk(Biome biome, int chunkX, int chunkZ) {
|
public Chunk(Biome biome, int chunkX, int chunkZ) {
|
||||||
this.biome = biome;
|
this.biome = biome;
|
||||||
|
@ -23,18 +26,27 @@ public class Chunk {
|
||||||
this.chunkZ = chunkZ;
|
this.chunkZ = chunkZ;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setBlock(int x, int y, int z, short blockId) {
|
protected void setBlock(byte x, byte y, byte z, short blockId) {
|
||||||
short index = (short) (x & 0x000F);
|
int index = getIndex(x, y, z);
|
||||||
index |= (y << 4) & 0x0FF0;
|
this.blocksId[index] = blockId;
|
||||||
index |= (z << 12) & 0xF000;
|
if (blockId == 0) {
|
||||||
this.blocks.put(index, blockId);
|
this.customBlocks[index] = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public short getBlockId(int x, int y, int z) {
|
protected void setBlock(byte x, byte y, byte z, String blockId) {
|
||||||
short index = (short) (x & 0x000F);
|
int index = getIndex(x, y, z);
|
||||||
index |= (y << 4) & 0x0FF0;
|
CustomBlock customBlock = Main.getBlockManager().getBlock(blockId);
|
||||||
index |= (z << 12) & 0xF000;
|
this.blocksId[index] = customBlock.getType();
|
||||||
return this.blocks.getOrDefault(index, (short) 0);
|
this.customBlocks[index] = blockId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public short getBlockId(byte x, byte y, byte z) {
|
||||||
|
return this.blocksId[getIndex(x, y, z)];
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCustomBlockId(byte x, byte y, byte z) {
|
||||||
|
return this.customBlocks[getIndex(x, y, z)];
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addEntity(Entity entity) {
|
public void addEntity(Entity entity) {
|
||||||
|
@ -65,8 +77,8 @@ public class Chunk {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public HashMap<Short, Short> getBlocks() {
|
public short[] getBlocksId() {
|
||||||
return blocks;
|
return blocksId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Biome getBiome() {
|
public Biome getBiome() {
|
||||||
|
@ -88,4 +100,11 @@ public class Chunk {
|
||||||
public Set<Player> getPlayers() {
|
public Set<Player> getPlayers() {
|
||||||
return Collections.unmodifiableSet(players);
|
return Collections.unmodifiableSet(players);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int getIndex(byte x, byte y, byte z) {
|
||||||
|
short index = (short) (x & 0x000F);
|
||||||
|
index |= (y << 4) & 0x0FF0;
|
||||||
|
index |= (z << 12) & 0xF000;
|
||||||
|
return index & 0xffff;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
package fr.themode.minestom.instance;
|
||||||
|
|
||||||
|
import fr.themode.minestom.entity.Player;
|
||||||
|
|
||||||
|
public abstract class CustomBlock {
|
||||||
|
|
||||||
|
private short type;
|
||||||
|
|
||||||
|
public CustomBlock(short type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Time in ms
|
||||||
|
*/
|
||||||
|
public abstract int getBreakDelay(Player player);
|
||||||
|
|
||||||
|
public short getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
}
|
|
@ -25,20 +25,32 @@ public class Instance {
|
||||||
this.uniqueId = uniqueId;
|
this.uniqueId = uniqueId;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO BlockBatch with pool
|
|
||||||
public synchronized void setBlock(int x, int y, int z, short blockId) {
|
public synchronized void setBlock(int x, int y, int z, short blockId) {
|
||||||
final int chunkX = Math.floorDiv(x, 16);
|
Chunk chunk = getChunkAt(x, z);
|
||||||
final int chunkZ = Math.floorDiv(z, 16);
|
|
||||||
Chunk chunk = getChunk(chunkX, chunkZ);
|
|
||||||
if (chunk == null) {
|
|
||||||
chunk = createChunk(Biome.VOID, chunkX, chunkZ);
|
|
||||||
}
|
|
||||||
synchronized (chunk) {
|
synchronized (chunk) {
|
||||||
chunk.setBlock(x % 16, y, z % 16, blockId);
|
chunk.setBlock((byte) (x % 16), (byte) y, (byte) (z % 16), blockId);
|
||||||
sendChunkUpdate(chunk);
|
sendChunkUpdate(chunk);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public synchronized void setBlock(int x, int y, int z, String blockId) {
|
||||||
|
Chunk chunk = getChunkAt(x, z);
|
||||||
|
synchronized (chunk) {
|
||||||
|
chunk.setBlock((byte) (x % 16), (byte) y, (byte) (z % 16), blockId);
|
||||||
|
sendChunkUpdate(chunk);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public short getBlockId(int x, int y, int z) {
|
||||||
|
Chunk chunk = getChunkAt(x, z);
|
||||||
|
return chunk.getBlockId((byte) (x % 16), (byte) y, (byte) (z % 16));
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCustomBlockId(int x, int y, int z) {
|
||||||
|
Chunk chunk = getChunkAt(x, z);
|
||||||
|
return chunk.getCustomBlockId((byte) (x % 16), (byte) y, (byte) (z % 16));
|
||||||
|
}
|
||||||
|
|
||||||
public BlockBatch createBlockBatch() {
|
public BlockBatch createBlockBatch() {
|
||||||
return new BlockBatch(this);
|
return new BlockBatch(this);
|
||||||
}
|
}
|
||||||
|
@ -48,7 +60,7 @@ public class Instance {
|
||||||
if (chunk.getChunkX() == chunkX && chunk.getChunkZ() == chunkZ)
|
if (chunk.getChunkX() == chunkX && chunk.getChunkZ() == chunkZ)
|
||||||
return chunk;
|
return chunk;
|
||||||
}
|
}
|
||||||
return null;
|
return createChunk(Biome.VOID, chunkX, chunkZ); // TODO generation API
|
||||||
}
|
}
|
||||||
|
|
||||||
public Chunk getChunkAt(double x, double z) {
|
public Chunk getChunkAt(double x, double z) {
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
package fr.themode.minestom.instance.demo;
|
||||||
|
|
||||||
|
import fr.themode.minestom.entity.Player;
|
||||||
|
import fr.themode.minestom.instance.CustomBlock;
|
||||||
|
|
||||||
|
public class StoneBlock extends CustomBlock {
|
||||||
|
|
||||||
|
public StoneBlock() {
|
||||||
|
super((short) 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getBreakDelay(Player player) {
|
||||||
|
return 750;
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,7 +15,10 @@ import fr.themode.minestom.net.ConnectionState;
|
||||||
import fr.themode.minestom.net.packet.client.ClientPreplayPacket;
|
import fr.themode.minestom.net.packet.client.ClientPreplayPacket;
|
||||||
import fr.themode.minestom.net.packet.server.login.JoinGamePacket;
|
import fr.themode.minestom.net.packet.server.login.JoinGamePacket;
|
||||||
import fr.themode.minestom.net.packet.server.login.LoginSuccessPacket;
|
import fr.themode.minestom.net.packet.server.login.LoginSuccessPacket;
|
||||||
import fr.themode.minestom.net.packet.server.play.*;
|
import fr.themode.minestom.net.packet.server.play.PlayerInfoPacket;
|
||||||
|
import fr.themode.minestom.net.packet.server.play.PlayerPositionAndLookPacket;
|
||||||
|
import fr.themode.minestom.net.packet.server.play.SpawnPlayerPacket;
|
||||||
|
import fr.themode.minestom.net.packet.server.play.SpawnPositionPacket;
|
||||||
import fr.themode.minestom.net.player.PlayerConnection;
|
import fr.themode.minestom.net.player.PlayerConnection;
|
||||||
import fr.themode.minestom.utils.Utils;
|
import fr.themode.minestom.utils.Utils;
|
||||||
import fr.themode.minestom.world.Dimension;
|
import fr.themode.minestom.world.Dimension;
|
||||||
|
@ -148,15 +151,6 @@ public class LoginStartPacket implements ClientPreplayPacket {
|
||||||
player.openInventory(inv);
|
player.openInventory(inv);
|
||||||
inv.setItemStack(1, new ItemStack(1, (byte) 2));
|
inv.setItemStack(1, new ItemStack(1, (byte) 2));
|
||||||
inv.updateItems();
|
inv.updateItems();
|
||||||
|
|
||||||
|
|
||||||
EntityEffectPacket entityEffectPacket = new EntityEffectPacket();
|
|
||||||
entityEffectPacket.entityId = player.getEntityId();
|
|
||||||
entityEffectPacket.effectId = 4;
|
|
||||||
entityEffectPacket.amplifier = -1;
|
|
||||||
entityEffectPacket.duration = 3600;
|
|
||||||
entityEffectPacket.flags = 0;
|
|
||||||
connection.sendPacket(entityEffectPacket);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -25,7 +25,7 @@ public class ClientPlayerBlockPlacementPacket implements ClientPlayPacket {
|
||||||
int offsetY = blockFace == ClientPlayerDiggingPacket.BlockFace.BOTTOM ? -1 : blockFace == ClientPlayerDiggingPacket.BlockFace.TOP ? 1 : 0;
|
int offsetY = blockFace == ClientPlayerDiggingPacket.BlockFace.BOTTOM ? -1 : blockFace == ClientPlayerDiggingPacket.BlockFace.TOP ? 1 : 0;
|
||||||
int offsetZ = blockFace == ClientPlayerDiggingPacket.BlockFace.NORTH ? -1 : blockFace == ClientPlayerDiggingPacket.BlockFace.SOUTH ? 1 : 0;
|
int offsetZ = blockFace == ClientPlayerDiggingPacket.BlockFace.NORTH ? -1 : blockFace == ClientPlayerDiggingPacket.BlockFace.SOUTH ? 1 : 0;
|
||||||
|
|
||||||
instance.setBlock(position.getX() + offsetX, position.getY() + offsetY, position.getZ() + offsetZ, (short) 1);
|
instance.setBlock(position.getX() + offsetX, position.getY() + offsetY, position.getZ() + offsetZ, "stone");
|
||||||
player.getInventory().refreshSlot(player.getHeldSlot());
|
player.getInventory().refreshSlot(player.getHeldSlot());
|
||||||
// TODO consume block in hand for survival players
|
// TODO consume block in hand for survival players
|
||||||
/*Random random = new Random();
|
/*Random random = new Random();
|
||||||
|
|
|
@ -1,10 +1,14 @@
|
||||||
package fr.themode.minestom.net.packet.client.play;
|
package fr.themode.minestom.net.packet.client.play;
|
||||||
|
|
||||||
import fr.adamaq01.ozao.net.Buffer;
|
import fr.adamaq01.ozao.net.Buffer;
|
||||||
|
import fr.themode.minestom.Main;
|
||||||
import fr.themode.minestom.entity.GameMode;
|
import fr.themode.minestom.entity.GameMode;
|
||||||
import fr.themode.minestom.entity.Player;
|
import fr.themode.minestom.entity.Player;
|
||||||
|
import fr.themode.minestom.instance.CustomBlock;
|
||||||
import fr.themode.minestom.instance.Instance;
|
import fr.themode.minestom.instance.Instance;
|
||||||
import fr.themode.minestom.net.packet.client.ClientPlayPacket;
|
import fr.themode.minestom.net.packet.client.ClientPlayPacket;
|
||||||
|
import fr.themode.minestom.net.packet.server.play.EntityEffectPacket;
|
||||||
|
import fr.themode.minestom.net.packet.server.play.RemoveEntityEffectPacket;
|
||||||
import fr.themode.minestom.utils.Position;
|
import fr.themode.minestom.utils.Position;
|
||||||
import fr.themode.minestom.utils.Utils;
|
import fr.themode.minestom.utils.Utils;
|
||||||
|
|
||||||
|
@ -24,19 +28,56 @@ public class ClientPlayerDiggingPacket implements ClientPlayPacket {
|
||||||
instance.setBlock(position.getX(), position.getY(), position.getZ(), (short) 0);
|
instance.setBlock(position.getX(), position.getY(), position.getZ(), (short) 0);
|
||||||
}
|
}
|
||||||
} else if (player.getGameMode() == GameMode.SURVIVAL) {
|
} else if (player.getGameMode() == GameMode.SURVIVAL) {
|
||||||
player.refreshTargetBlock(position);
|
Instance instance = player.getInstance();
|
||||||
// TODO survival mining
|
if (instance != null) {
|
||||||
|
String customBlockId = instance.getCustomBlockId(position.getX(), position.getY(), position.getZ());
|
||||||
|
if (customBlockId != null) {
|
||||||
|
CustomBlock customBlock = Main.getBlockManager().getBlock(customBlockId);
|
||||||
|
player.refreshTargetBlock(customBlock, position);
|
||||||
|
addEffect(player);
|
||||||
|
} else {
|
||||||
|
player.resetTargetBlock();
|
||||||
|
removeEffect(player);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CANCELLED_DIGGING:
|
case CANCELLED_DIGGING:
|
||||||
player.refreshTargetBlock(null);
|
player.sendBlockBreakAnimation(position, (byte) -1);
|
||||||
|
player.resetTargetBlock();
|
||||||
|
removeEffect(player);
|
||||||
break;
|
break;
|
||||||
case FINISHED_DIGGING:
|
case FINISHED_DIGGING:
|
||||||
player.refreshTargetBlock(null);
|
if (player.getCustomBlockTarget() != null) {
|
||||||
|
player.resetTargetBlock();
|
||||||
|
removeEffect(player);
|
||||||
|
} else {
|
||||||
|
Instance instance = player.getInstance();
|
||||||
|
if (instance != null) {
|
||||||
|
instance.setBlock(position.getX(), position.getY(), position.getZ(), (short) 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void addEffect(Player player) {
|
||||||
|
EntityEffectPacket entityEffectPacket = new EntityEffectPacket();
|
||||||
|
entityEffectPacket.entityId = player.getEntityId();
|
||||||
|
entityEffectPacket.effectId = 4;
|
||||||
|
entityEffectPacket.amplifier = -1;
|
||||||
|
entityEffectPacket.duration = 0;
|
||||||
|
entityEffectPacket.flags = 0;
|
||||||
|
player.getPlayerConnection().sendPacket(entityEffectPacket);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeEffect(Player player) {
|
||||||
|
RemoveEntityEffectPacket removeEntityEffectPacket = new RemoveEntityEffectPacket();
|
||||||
|
removeEntityEffectPacket.entityId = player.getEntityId();
|
||||||
|
removeEntityEffectPacket.effectId = 4;
|
||||||
|
player.getPlayerConnection().sendPacket(removeEntityEffectPacket);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void read(Buffer buffer) {
|
public void read(Buffer buffer) {
|
||||||
this.status = Status.values()[Utils.readVarInt(buffer)];
|
this.status = Status.values()[Utils.readVarInt(buffer)];
|
||||||
|
|
|
@ -74,11 +74,11 @@ public class ChunkDataPacket implements ServerPacket {
|
||||||
|
|
||||||
private Short[] getSection(Chunk chunk, int section) {
|
private Short[] getSection(Chunk chunk, int section) {
|
||||||
Short[] blocks = new Short[16 * 16 * 16];
|
Short[] blocks = new Short[16 * 16 * 16];
|
||||||
for (int y = 0; y < 16; y++) {
|
for (byte y = 0; y < 16; y++) {
|
||||||
for (int x = 0; x < 16; x++) {
|
for (byte x = 0; x < 16; x++) {
|
||||||
for (int z = 0; z < 16; z++) {
|
for (byte z = 0; z < 16; z++) {
|
||||||
int index = (((y * 16) + x) * 16) + z;
|
int index = (((y * 16) + x) * 16) + z;
|
||||||
blocks[index] = chunk.getBlockId(x, y + 16 * section, z);
|
blocks[index] = chunk.getBlockId(x, (byte) (y + 16 * section), z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
package fr.themode.minestom.net.packet.server.play;
|
||||||
|
|
||||||
|
import fr.adamaq01.ozao.net.Buffer;
|
||||||
|
import fr.themode.minestom.net.packet.server.ServerPacket;
|
||||||
|
import fr.themode.minestom.utils.Utils;
|
||||||
|
|
||||||
|
public class ParticlePacket implements ServerPacket {
|
||||||
|
|
||||||
|
public int particleId;
|
||||||
|
public boolean longDistance;
|
||||||
|
public float x, y, z;
|
||||||
|
public float offsetX, offsetY, offsetZ;
|
||||||
|
public float particleData;
|
||||||
|
public int particleCount;
|
||||||
|
// TODO data
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(Buffer buffer) {
|
||||||
|
buffer.putInt(particleId);
|
||||||
|
buffer.putBoolean(longDistance);
|
||||||
|
buffer.putFloat(x);
|
||||||
|
buffer.putFloat(y);
|
||||||
|
buffer.putFloat(z);
|
||||||
|
buffer.putFloat(offsetX);
|
||||||
|
buffer.putFloat(offsetY);
|
||||||
|
buffer.putFloat(offsetZ);
|
||||||
|
buffer.putFloat(particleData);
|
||||||
|
buffer.putInt(particleCount);
|
||||||
|
Utils.writeVarInt(buffer, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getId() {
|
||||||
|
return 0x23;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue