mirror of
https://github.com/Minestom/Minestom.git
synced 2024-12-26 02:57:37 +01:00
Update
This commit is contained in:
parent
2da2823cbd
commit
57def5aaac
@ -16,6 +16,7 @@ public class EntityManager {
|
||||
|
||||
public void update() {
|
||||
for (Instance instance : instanceManager.getInstances()) {
|
||||
// TODO loop chunks and entities on it instead of individual (to have more non-blocking operation)
|
||||
|
||||
// Creatures
|
||||
for (EntityCreature creature : instance.getCreatures()) {
|
||||
|
@ -6,6 +6,7 @@ import fr.themode.minestom.inventory.PlayerInventory;
|
||||
import fr.themode.minestom.item.ItemStack;
|
||||
import fr.themode.minestom.net.packet.server.play.*;
|
||||
import fr.themode.minestom.net.player.PlayerConnection;
|
||||
import fr.themode.minestom.utils.Position;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@ -24,6 +25,9 @@ public class Player extends LivingEntity {
|
||||
private short heldSlot;
|
||||
private Inventory openInventory;
|
||||
|
||||
private Position targetBlockPosition;
|
||||
private long targetBlockTime;
|
||||
|
||||
// TODO set proper UUID
|
||||
public Player(UUID uuid, String username, PlayerConnection playerConnection) {
|
||||
this.uuid = uuid;
|
||||
@ -35,7 +39,26 @@ public class Player extends LivingEntity {
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
// System.out.println("Je suis l'update");
|
||||
|
||||
// Target block stage
|
||||
if (instance != null && targetBlockPosition != null) {
|
||||
int timeBreak = 750; // In ms
|
||||
int animationCount = 10;
|
||||
long since = System.currentTimeMillis() - targetBlockTime;
|
||||
byte stage = (byte) (since / (timeBreak / animationCount));
|
||||
BlockBreakAnimationPacket breakAnimationPacket = new BlockBreakAnimationPacket();
|
||||
breakAnimationPacket.entityId = getEntityId() + 1;
|
||||
breakAnimationPacket.blockPosition = targetBlockPosition;
|
||||
breakAnimationPacket.destroyStage = stage;
|
||||
if (stage > 9) {
|
||||
instance.setBlock(targetBlockPosition.getX(), targetBlockPosition.getY(), targetBlockPosition.getZ(), (short) 0);
|
||||
refreshTargetBlock(null);
|
||||
}
|
||||
playerConnection.sendPacket(breakAnimationPacket); // TODO send to all online players
|
||||
}
|
||||
|
||||
|
||||
// Multiplayer sync
|
||||
EntityTeleportPacket entityTeleportPacket = new EntityTeleportPacket();
|
||||
entityTeleportPacket.entityId = getEntityId();
|
||||
entityTeleportPacket.x = x;
|
||||
@ -51,6 +74,11 @@ public class Player extends LivingEntity {
|
||||
playerConnection.sendPacket(new UpdateViewPositionPacket(Math.floorDiv((int) x, 16), Math.floorDiv((int) z, 16)));
|
||||
}
|
||||
|
||||
public void sendMessage(String message) {
|
||||
ChatMessagePacket chatMessagePacket = new ChatMessagePacket("{\"text\": \"" + message + "\"}", ChatMessagePacket.Position.CHAT);
|
||||
playerConnection.sendPacket(chatMessagePacket);
|
||||
}
|
||||
|
||||
public void teleport(double x, double y, double z) {
|
||||
PlayerPositionAndLookPacket positionAndLookPacket = new PlayerPositionAndLookPacket();
|
||||
positionAndLookPacket.x = x;
|
||||
@ -172,6 +200,11 @@ public class Player extends LivingEntity {
|
||||
this.openInventory = openInventory;
|
||||
}
|
||||
|
||||
public void refreshTargetBlock(Position targetBlockPosition) {
|
||||
this.targetBlockPosition = targetBlockPosition;
|
||||
this.targetBlockTime = targetBlockPosition == null ? 0 : System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public long getLastKeepAlive() {
|
||||
return lastKeepAlive;
|
||||
}
|
||||
|
@ -2,36 +2,22 @@ package fr.themode.minestom.instance;
|
||||
|
||||
public class Block {
|
||||
|
||||
private short typeAndDamage;
|
||||
private short type;
|
||||
|
||||
public Block(int type) {
|
||||
this.typeAndDamage = (short) (type & 0x0FFF);
|
||||
this.typeAndDamage |= (0 << 12) & 0xF000;
|
||||
public Block(short type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public Block(int type, int damage) {
|
||||
this.typeAndDamage = (short) (type & 0x0FFF);
|
||||
this.typeAndDamage |= (damage << 12) & 0xF000;
|
||||
public short getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public int getType() {
|
||||
return typeAndDamage & 0x0FFF;
|
||||
}
|
||||
|
||||
public void setType(int type) {
|
||||
this.typeAndDamage |= type & 0x0FFF;
|
||||
}
|
||||
|
||||
public int getDamage() {
|
||||
return (typeAndDamage & 0xF000) >>> 12;
|
||||
}
|
||||
|
||||
public void setDamage(int damage) {
|
||||
this.typeAndDamage |= (damage << 12) & 0xF000;
|
||||
public void setType(short type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("CustomBlock{type=%s, damage=%s}", getType(), getDamage());
|
||||
return String.format("CustomBlock{type=%s}", type);
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ public class BlockBatch {
|
||||
this.instance = instance;
|
||||
}
|
||||
|
||||
public synchronized void setBlock(int x, int y, int z, Block block) {
|
||||
public synchronized void setBlock(int x, int y, int z, short blockId) {
|
||||
final int chunkX = Math.floorDiv(x, 16);
|
||||
final int chunkZ = Math.floorDiv(z, 16);
|
||||
Chunk chunk = this.instance.getChunk(chunkX, chunkZ);
|
||||
@ -31,7 +31,7 @@ public class BlockBatch {
|
||||
data.x = x % 16;
|
||||
data.y = y;
|
||||
data.z = z % 16;
|
||||
data.block = block;
|
||||
data.blockId = blockId;
|
||||
|
||||
blockData.add(data);
|
||||
|
||||
@ -56,10 +56,10 @@ public class BlockBatch {
|
||||
private class BlockData {
|
||||
|
||||
private int x, y, z;
|
||||
private Block block;
|
||||
private short blockId;
|
||||
|
||||
public void apply(Chunk chunk) {
|
||||
chunk.setBlock(x, y, z, block);
|
||||
chunk.setBlock(x, y, z, blockId);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ public class Chunk {
|
||||
protected Set<Player> players = new CopyOnWriteArraySet<>();
|
||||
private int chunkX, chunkZ;
|
||||
private Biome biome;
|
||||
private HashMap<Short, Block> blocks = new HashMap<>();
|
||||
private HashMap<Short, Short> blocks = new HashMap<>(); // Index/BlockID
|
||||
|
||||
public Chunk(Biome biome, int chunkX, int chunkZ) {
|
||||
this.biome = biome;
|
||||
@ -23,18 +23,18 @@ public class Chunk {
|
||||
this.chunkZ = chunkZ;
|
||||
}
|
||||
|
||||
protected void setBlock(int x, int y, int z, Block block) {
|
||||
protected void setBlock(int x, int y, int z, short blockId) {
|
||||
short index = (short) (x & 0x000F);
|
||||
index |= (y << 4) & 0x0FF0;
|
||||
index |= (z << 12) & 0xF000;
|
||||
this.blocks.put(index, block);
|
||||
this.blocks.put(index, blockId);
|
||||
}
|
||||
|
||||
public Block getBlock(int x, int y, int z) {
|
||||
public short getBlockId(int x, int y, int z) {
|
||||
short index = (short) (x & 0x000F);
|
||||
index |= (y << 4) & 0x0FF0;
|
||||
index |= (z << 12) & 0xF000;
|
||||
return this.blocks.getOrDefault(index, new Block(0));
|
||||
return this.blocks.getOrDefault(index, (short) 0);
|
||||
}
|
||||
|
||||
public void addEntity(Entity entity) {
|
||||
@ -65,7 +65,7 @@ public class Chunk {
|
||||
}
|
||||
}
|
||||
|
||||
public HashMap<Short, Block> getBlocks() {
|
||||
public HashMap<Short, Short> getBlocks() {
|
||||
return blocks;
|
||||
}
|
||||
|
||||
|
@ -26,7 +26,7 @@ public class Instance {
|
||||
}
|
||||
|
||||
// TODO BlockBatch with pool
|
||||
public synchronized void setBlock(int x, int y, int z, Block block) {
|
||||
public synchronized void setBlock(int x, int y, int z, short blockId) {
|
||||
final int chunkX = Math.floorDiv(x, 16);
|
||||
final int chunkZ = Math.floorDiv(z, 16);
|
||||
Chunk chunk = getChunk(chunkX, chunkZ);
|
||||
@ -34,7 +34,7 @@ public class Instance {
|
||||
chunk = createChunk(Biome.VOID, chunkX, chunkZ);
|
||||
}
|
||||
synchronized (chunk) {
|
||||
chunk.setBlock(x % 16, y, z % 16, block);
|
||||
chunk.setBlock(x % 16, y, z % 16, blockId);
|
||||
sendChunkUpdate(chunk);
|
||||
}
|
||||
}
|
||||
|
@ -8,10 +8,14 @@ import fr.themode.minestom.net.player.PlayerConnection;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class PlayerInventory implements InventoryModifier {
|
||||
public class PlayerInventory implements InventoryModifier, InventoryClickHandler {
|
||||
|
||||
public static final int INVENTORY_SIZE = 46;
|
||||
|
||||
private static final byte ITEM_MAX_SIZE = 127;
|
||||
|
||||
private static final int OFFSET = 9;
|
||||
|
||||
private static final int CRAFT_SLOT_1 = 36;
|
||||
private static final int CRAFT_SLOT_2 = 37;
|
||||
private static final int CRAFT_SLOT_3 = 38;
|
||||
@ -25,6 +29,7 @@ public class PlayerInventory implements InventoryModifier {
|
||||
|
||||
private Player player;
|
||||
private ItemStack[] items = new ItemStack[INVENTORY_SIZE];
|
||||
private ItemStack cursorItem = ItemStack.AIR_ITEM;
|
||||
|
||||
public PlayerInventory(Player player) {
|
||||
this.player = player;
|
||||
@ -56,15 +61,14 @@ public class PlayerInventory implements InventoryModifier {
|
||||
setItemStack(i, itemStack);
|
||||
return true;
|
||||
} else if (itemStack.isSimilar(item)) {
|
||||
// TODO check max stack size
|
||||
int itemAmount = item.getAmount();
|
||||
if (itemAmount == 64)
|
||||
if (itemAmount == ITEM_MAX_SIZE)
|
||||
continue;
|
||||
int totalAmount = itemStack.getAmount() + itemAmount;
|
||||
if (totalAmount > 64) {
|
||||
item.setAmount((byte) 64);
|
||||
if (totalAmount > ITEM_MAX_SIZE) {
|
||||
item.setAmount((byte) ITEM_MAX_SIZE);
|
||||
sendSlotRefresh((short) convertToPacketSlot(i), item);
|
||||
itemStack.setAmount((byte) (totalAmount - 64));
|
||||
itemStack.setAmount((byte) (totalAmount - ITEM_MAX_SIZE));
|
||||
} else {
|
||||
item.setAmount((byte) totalAmount);
|
||||
sendSlotRefresh((short) convertToPacketSlot(i), item);
|
||||
@ -105,12 +109,25 @@ public class PlayerInventory implements InventoryModifier {
|
||||
playerConnection.sendPacket(createWindowItemsPacket());
|
||||
}
|
||||
|
||||
public void refreshSlot(int slot) {
|
||||
sendSlotRefresh((short) convertToPacketSlot(slot), getItemStack(slot));
|
||||
}
|
||||
|
||||
public ItemStack getCursorItem() {
|
||||
return cursorItem;
|
||||
}
|
||||
|
||||
public void setCursorItem(ItemStack cursorItem) {
|
||||
this.cursorItem = cursorItem;
|
||||
}
|
||||
|
||||
private void safeItemInsert(int slot, ItemStack itemStack) {
|
||||
synchronized (this) {
|
||||
itemStack = itemStack == null ? ItemStack.AIR_ITEM : itemStack;
|
||||
this.items[slot] = itemStack;
|
||||
System.out.println("INSERT: " + slot);
|
||||
sendSlotRefresh((short) slot, itemStack);
|
||||
// System.out.println("INSERT: " + slot);
|
||||
//sendSlotRefresh((short) slot, itemStack);
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
@ -126,6 +143,17 @@ public class PlayerInventory implements InventoryModifier {
|
||||
|
||||
|
||||
protected int convertSlot(int slot, int offset) {
|
||||
switch (slot) {
|
||||
case 1:
|
||||
return CRAFT_SLOT_1 + 1;
|
||||
case 2:
|
||||
return CRAFT_SLOT_2 + 1;
|
||||
case 3:
|
||||
return CRAFT_SLOT_3 + 1;
|
||||
case 4:
|
||||
return CRAFT_SLOT_4 + 1;
|
||||
}
|
||||
//System.out.println("ENTRY: " + slot + " | " + offset);
|
||||
final int rowSize = 9;
|
||||
slot -= offset;
|
||||
if (slot >= rowSize * 3 && slot < rowSize * 4) {
|
||||
@ -133,6 +161,7 @@ public class PlayerInventory implements InventoryModifier {
|
||||
} else {
|
||||
slot = slot + rowSize;
|
||||
}
|
||||
//System.out.println("CONVERT: " + slot);
|
||||
return slot;
|
||||
}
|
||||
|
||||
@ -161,7 +190,6 @@ public class PlayerInventory implements InventoryModifier {
|
||||
|
||||
private WindowItemsPacket createWindowItemsPacket() {
|
||||
ItemStack[] convertedSlots = new ItemStack[INVENTORY_SIZE];
|
||||
Arrays.fill(convertedSlots, ItemStack.AIR_ITEM); // TODO armor and craft
|
||||
|
||||
for (int i = 0; i < items.length; i++) {
|
||||
int slot = convertToPacketSlot(i);
|
||||
@ -175,4 +203,220 @@ public class PlayerInventory implements InventoryModifier {
|
||||
return windowItemsPacket;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void leftClick(Player player, int slot) {
|
||||
ItemStack cursorItem = getCursorItem();
|
||||
ItemStack clicked = getItemStack(convertSlot(slot, OFFSET));
|
||||
|
||||
if (!cursorItem.isAir()) {
|
||||
if (slot == 0 || slot == 6 || slot == 7 || slot == 8) {
|
||||
return; // Disable putting item on CRAFTING_RESULT and chestplate/leggings/boots slots
|
||||
}
|
||||
}
|
||||
|
||||
if (cursorItem.isAir() && clicked.isAir())
|
||||
return;
|
||||
|
||||
ItemStack resultCursor;
|
||||
ItemStack resultClicked;
|
||||
|
||||
if (cursorItem.isSimilar(clicked)) {
|
||||
resultCursor = cursorItem.clone();
|
||||
resultClicked = clicked.clone();
|
||||
int totalAmount = cursorItem.getAmount() + clicked.getAmount();
|
||||
if (totalAmount > ITEM_MAX_SIZE) {
|
||||
resultCursor.setAmount((byte) (totalAmount - ITEM_MAX_SIZE));
|
||||
resultClicked.setAmount((byte) ITEM_MAX_SIZE);
|
||||
} else {
|
||||
resultCursor = ItemStack.AIR_ITEM;
|
||||
resultClicked.setAmount((byte) totalAmount);
|
||||
}
|
||||
} else {
|
||||
resultCursor = clicked.clone();
|
||||
resultClicked = cursorItem.clone();
|
||||
}
|
||||
|
||||
setItemStack(slot, OFFSET, resultClicked);
|
||||
setCursorItem(resultCursor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void rightClick(Player player, int slot) {
|
||||
ItemStack cursorItem = getCursorItem();
|
||||
ItemStack clicked = getItemStack(slot, OFFSET);
|
||||
|
||||
if (!cursorItem.isAir()) {
|
||||
if (slot == 0 || slot == 6 || slot == 7 || slot == 8) {
|
||||
return; // Disable putting item on CRAFTING_RESULT and chestplate/leggings/boots slots
|
||||
}
|
||||
}
|
||||
|
||||
if (cursorItem.isAir() && clicked.isAir())
|
||||
return;
|
||||
|
||||
ItemStack resultCursor;
|
||||
ItemStack resultClicked;
|
||||
|
||||
if (cursorItem.isSimilar(clicked)) {
|
||||
resultClicked = clicked.clone();
|
||||
int amount = clicked.getAmount() + 1;
|
||||
if (amount > ITEM_MAX_SIZE) {
|
||||
return;
|
||||
} else {
|
||||
resultCursor = cursorItem.clone();
|
||||
resultCursor.setAmount((byte) (resultCursor.getAmount() - 1));
|
||||
if (resultCursor.getAmount() < 1)
|
||||
resultCursor = ItemStack.AIR_ITEM;
|
||||
resultClicked.setAmount((byte) amount);
|
||||
}
|
||||
} else {
|
||||
if (cursorItem.isAir()) {
|
||||
int amount = (int) Math.ceil((double) clicked.getAmount() / 2d);
|
||||
resultCursor = clicked.clone();
|
||||
resultCursor.setAmount((byte) amount);
|
||||
resultClicked = clicked.clone();
|
||||
resultClicked.setAmount((byte) (clicked.getAmount() / 2));
|
||||
} else {
|
||||
if (clicked.isAir()) {
|
||||
int amount = cursorItem.getAmount();
|
||||
resultCursor = cursorItem.clone();
|
||||
resultCursor.setAmount((byte) (amount - 1));
|
||||
if (resultCursor.getAmount() < 1)
|
||||
resultCursor = ItemStack.AIR_ITEM;
|
||||
resultClicked = cursorItem.clone();
|
||||
resultClicked.setAmount((byte) 1);
|
||||
} else {
|
||||
resultCursor = clicked.clone();
|
||||
resultClicked = cursorItem.clone();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setItemStack(slot, OFFSET, resultClicked);
|
||||
setCursorItem(resultCursor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shiftClick(Player player, int slot) {
|
||||
ItemStack clicked = getItemStack(slot, OFFSET);
|
||||
|
||||
if (clicked.isAir())
|
||||
return;
|
||||
|
||||
ItemStack resultClicked = clicked.clone();
|
||||
boolean filled = false;
|
||||
for (int i = 0; i < items.length; i++) {
|
||||
int index = i < 9 ? i + 9 : i - 9;
|
||||
ItemStack item = items[index];
|
||||
if (item.isSimilar(clicked)) {
|
||||
int amount = item.getAmount();
|
||||
if (amount == ITEM_MAX_SIZE)
|
||||
continue;
|
||||
int totalAmount = resultClicked.getAmount() + amount;
|
||||
if (totalAmount > ITEM_MAX_SIZE) {
|
||||
item.setAmount((byte) ITEM_MAX_SIZE);
|
||||
setItemStack(index, item);
|
||||
resultClicked.setAmount((byte) (totalAmount - ITEM_MAX_SIZE));
|
||||
filled = false;
|
||||
continue;
|
||||
} else {
|
||||
resultClicked.setAmount((byte) totalAmount);
|
||||
setItemStack(index, resultClicked);
|
||||
setItemStack(slot, OFFSET, ItemStack.AIR_ITEM);
|
||||
filled = true;
|
||||
break;
|
||||
}
|
||||
} else if (item.isAir()) {
|
||||
// Switch
|
||||
setItemStack(index, resultClicked);
|
||||
setItemStack(slot, OFFSET, ItemStack.AIR_ITEM);
|
||||
filled = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!filled) {
|
||||
setItemStack(slot, OFFSET, resultClicked);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void changeHeld(Player player, int slot, int key) {
|
||||
if (!getCursorItem().isAir())
|
||||
return;
|
||||
|
||||
ItemStack heldItem = getItemStack(key);
|
||||
ItemStack clicked = getItemStack(slot, OFFSET);
|
||||
|
||||
ItemStack resultClicked;
|
||||
ItemStack resultHeld;
|
||||
|
||||
if (clicked.isAir()) {
|
||||
// Set held item [key] to slot
|
||||
resultClicked = ItemStack.AIR_ITEM;
|
||||
resultHeld = clicked.clone();
|
||||
} else {
|
||||
if (heldItem.isAir()) {
|
||||
// if held item [key] is air then set clicked to held
|
||||
resultClicked = ItemStack.AIR_ITEM;
|
||||
resultHeld = clicked.clone();
|
||||
} else {
|
||||
// Otherwise replace held item and held
|
||||
resultClicked = heldItem.clone();
|
||||
resultHeld = clicked.clone();
|
||||
}
|
||||
}
|
||||
|
||||
setItemStack(slot, OFFSET, resultClicked);
|
||||
setItemStack(key, resultHeld);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void middleClick(Player player, int slot) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dropOne(Player player, int slot) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dropItemStack(Player player, int slot) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doubleClick(Player player, int slot) {
|
||||
ItemStack cursorItem = getCursorItem().clone();
|
||||
if (cursorItem.isAir())
|
||||
return;
|
||||
|
||||
int amount = cursorItem.getAmount();
|
||||
|
||||
if (amount == ITEM_MAX_SIZE)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < items.length; i++) {
|
||||
int index = i < 9 ? i + 9 : i - 9;
|
||||
if (index == slot)
|
||||
continue;
|
||||
if (amount == ITEM_MAX_SIZE)
|
||||
break;
|
||||
ItemStack item = items[index];
|
||||
if (cursorItem.isSimilar(item)) {
|
||||
int totalAmount = amount + item.getAmount();
|
||||
if (totalAmount > ITEM_MAX_SIZE) {
|
||||
cursorItem.setAmount((byte) ITEM_MAX_SIZE);
|
||||
item.setAmount((byte) (totalAmount - ITEM_MAX_SIZE));
|
||||
setItemStack(index, item);
|
||||
} else {
|
||||
cursorItem.setAmount((byte) totalAmount);
|
||||
setItemStack(index, ItemStack.AIR_ITEM);
|
||||
}
|
||||
amount = cursorItem.getAmount();
|
||||
}
|
||||
}
|
||||
|
||||
setCursorItem(cursorItem);
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,6 @@ import fr.themode.minestom.Main;
|
||||
import fr.themode.minestom.entity.GameMode;
|
||||
import fr.themode.minestom.entity.Player;
|
||||
import fr.themode.minestom.entity.demo.ChickenCreature;
|
||||
import fr.themode.minestom.instance.Block;
|
||||
import fr.themode.minestom.instance.Instance;
|
||||
import fr.themode.minestom.inventory.Inventory;
|
||||
import fr.themode.minestom.inventory.InventoryType;
|
||||
@ -16,10 +15,7 @@ import fr.themode.minestom.net.ConnectionState;
|
||||
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.LoginSuccessPacket;
|
||||
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.packet.server.play.*;
|
||||
import fr.themode.minestom.net.player.PlayerConnection;
|
||||
import fr.themode.minestom.utils.Utils;
|
||||
import fr.themode.minestom.world.Dimension;
|
||||
@ -38,7 +34,7 @@ public class LoginStartPacket implements ClientPreplayPacket {
|
||||
instance = Main.getInstanceManager().createInstance();
|
||||
for (int x = -64; x < 64; x++)
|
||||
for (int z = -64; z < 64; z++) {
|
||||
instance.setBlock(x, 4, z, new Block(10));
|
||||
instance.setBlock(x, 4, z, (short) 10);
|
||||
}
|
||||
}
|
||||
|
||||
@ -153,6 +149,14 @@ public class LoginStartPacket implements ClientPreplayPacket {
|
||||
inv.setItemStack(1, new ItemStack(1, (byte) 2));
|
||||
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
|
||||
|
@ -4,7 +4,6 @@ import fr.adamaq01.ozao.net.Buffer;
|
||||
import fr.themode.minestom.Main;
|
||||
import fr.themode.minestom.entity.Player;
|
||||
import fr.themode.minestom.net.packet.client.ClientPlayPacket;
|
||||
import fr.themode.minestom.net.packet.server.play.ChatMessagePacket;
|
||||
import fr.themode.minestom.utils.Utils;
|
||||
|
||||
public class ClientChatMessagePacket implements ClientPlayPacket {
|
||||
@ -13,8 +12,7 @@ public class ClientChatMessagePacket implements ClientPlayPacket {
|
||||
|
||||
@Override
|
||||
public void process(Player player) {
|
||||
ChatMessagePacket chatMessagePacket = new ChatMessagePacket(String.format("{\"text\": \"<%s> %s\"}", player.getUsername(), message), ChatMessagePacket.Position.CHAT);
|
||||
Main.getConnectionManager().getOnlinePlayers().forEach(player1 -> player1.getPlayerConnection().sendPacket(chatMessagePacket));
|
||||
Main.getConnectionManager().getOnlinePlayers().forEach(p -> p.sendMessage(String.format("<%s> %s", player.getUsername(), message)));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -3,6 +3,8 @@ package fr.themode.minestom.net.packet.client.play;
|
||||
import fr.adamaq01.ozao.net.Buffer;
|
||||
import fr.themode.minestom.entity.Player;
|
||||
import fr.themode.minestom.inventory.Inventory;
|
||||
import fr.themode.minestom.inventory.InventoryClickHandler;
|
||||
import fr.themode.minestom.inventory.PlayerInventory;
|
||||
import fr.themode.minestom.item.ItemStack;
|
||||
import fr.themode.minestom.net.packet.client.ClientPlayPacket;
|
||||
import fr.themode.minestom.net.packet.server.play.ConfirmTransactionPacket;
|
||||
@ -20,7 +22,10 @@ public class ClientClickWindowPacket implements ClientPlayPacket {
|
||||
|
||||
@Override
|
||||
public void process(Player player) {
|
||||
Inventory inventory = player.getOpenInventory();
|
||||
InventoryClickHandler clickHandler = player.getOpenInventory();
|
||||
if (clickHandler == null) {
|
||||
clickHandler = player.getInventory();
|
||||
}
|
||||
System.out.println("Window id: " + windowId + " | slot: " + slot + " | button: " + button + " | mode: " + mode);
|
||||
|
||||
ConfirmTransactionPacket confirmTransactionPacket = new ConfirmTransactionPacket();
|
||||
@ -33,19 +38,19 @@ public class ClientClickWindowPacket implements ClientPlayPacket {
|
||||
switch (button) {
|
||||
case 0:
|
||||
// Left click
|
||||
inventory.leftClick(player, slot);
|
||||
clickHandler.leftClick(player, slot);
|
||||
break;
|
||||
case 1:
|
||||
// Right click
|
||||
inventory.rightClick(player, slot);
|
||||
clickHandler.rightClick(player, slot);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
inventory.shiftClick(player, slot); // Shift + left/right have identical behavior
|
||||
clickHandler.shiftClick(player, slot); // Shift + left/right have identical behavior
|
||||
break;
|
||||
case 2:
|
||||
inventory.changeHeld(player, slot, button);
|
||||
clickHandler.changeHeld(player, slot, button);
|
||||
break;
|
||||
case 3:
|
||||
// Middle click (only creative players in non-player inventories)
|
||||
@ -57,11 +62,11 @@ public class ClientClickWindowPacket implements ClientPlayPacket {
|
||||
// Dragging
|
||||
break;
|
||||
case 6:
|
||||
inventory.doubleClick(player, slot);
|
||||
clickHandler.doubleClick(player, slot);
|
||||
break;
|
||||
}
|
||||
|
||||
ItemStack cursorItem = inventory.getCursorItem(player);
|
||||
ItemStack cursorItem = clickHandler instanceof Inventory ? ((Inventory) clickHandler).getCursorItem(player) : ((PlayerInventory) clickHandler).getCursorItem();
|
||||
SetSlotPacket setSlotPacket = new SetSlotPacket();
|
||||
setSlotPacket.windowId = -1;
|
||||
setSlotPacket.slot = -1;
|
||||
|
@ -2,7 +2,6 @@ package fr.themode.minestom.net.packet.client.play;
|
||||
|
||||
import fr.adamaq01.ozao.net.Buffer;
|
||||
import fr.themode.minestom.entity.Player;
|
||||
import fr.themode.minestom.inventory.Inventory;
|
||||
import fr.themode.minestom.net.packet.client.ClientPlayPacket;
|
||||
import fr.themode.minestom.utils.Utils;
|
||||
|
||||
@ -12,10 +11,8 @@ public class ClientCloseWindow implements ClientPlayPacket {
|
||||
|
||||
@Override
|
||||
public void process(Player player) {
|
||||
Inventory openInventory = player.getOpenInventory();
|
||||
// if windowId == 0 then it is player's inventory, meaning that they hadn't been any open inventory packet
|
||||
if (openInventory != null)
|
||||
player.closeInventory();
|
||||
player.closeInventory();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -17,6 +17,6 @@ public class ClientHeldItemChangePacket implements ClientPlayPacket {
|
||||
|
||||
@Override
|
||||
public void read(Buffer buffer) {
|
||||
buffer.getShort();
|
||||
this.slot = buffer.getShort();
|
||||
}
|
||||
}
|
||||
|
@ -2,15 +2,11 @@ package fr.themode.minestom.net.packet.client.play;
|
||||
|
||||
import fr.adamaq01.ozao.net.Buffer;
|
||||
import fr.themode.minestom.entity.Player;
|
||||
import fr.themode.minestom.instance.Block;
|
||||
import fr.themode.minestom.instance.BlockBatch;
|
||||
import fr.themode.minestom.instance.Instance;
|
||||
import fr.themode.minestom.net.packet.client.ClientPlayPacket;
|
||||
import fr.themode.minestom.utils.Position;
|
||||
import fr.themode.minestom.utils.Utils;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class ClientPlayerBlockPlacementPacket implements ClientPlayPacket {
|
||||
|
||||
public Hand hand;
|
||||
@ -25,14 +21,21 @@ public class ClientPlayerBlockPlacementPacket implements ClientPlayPacket {
|
||||
if (instance == null)
|
||||
return;
|
||||
|
||||
Random random = new Random();
|
||||
int offsetX = blockFace == ClientPlayerDiggingPacket.BlockFace.WEST ? -1 : blockFace == ClientPlayerDiggingPacket.BlockFace.EAST ? 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;
|
||||
|
||||
instance.setBlock(position.getX() + offsetX, position.getY() + offsetY, position.getZ() + offsetZ, (short) 1);
|
||||
player.getInventory().refreshSlot(player.getHeldSlot());
|
||||
// TODO consume block in hand for survival players
|
||||
/*Random random = new Random();
|
||||
BlockBatch blockBatch = instance.createBlockBatch();
|
||||
for (int x = -64; x < 64; x++)
|
||||
for (int z = -64; z < 64; z++) {
|
||||
if (random.nextInt(100) > 75)
|
||||
blockBatch.setBlock(x, position.getY() + 1, z, new Block(1));
|
||||
}
|
||||
blockBatch.flush();
|
||||
blockBatch.flush();*/
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -3,7 +3,6 @@ package fr.themode.minestom.net.packet.client.play;
|
||||
import fr.adamaq01.ozao.net.Buffer;
|
||||
import fr.themode.minestom.entity.GameMode;
|
||||
import fr.themode.minestom.entity.Player;
|
||||
import fr.themode.minestom.instance.Block;
|
||||
import fr.themode.minestom.instance.Instance;
|
||||
import fr.themode.minestom.net.packet.client.ClientPlayPacket;
|
||||
import fr.themode.minestom.utils.Position;
|
||||
@ -22,10 +21,19 @@ public class ClientPlayerDiggingPacket implements ClientPlayPacket {
|
||||
if (player.getGameMode() == GameMode.CREATIVE) {
|
||||
Instance instance = player.getInstance();
|
||||
if (instance != null) {
|
||||
instance.setBlock(position.getX(), position.getY(), position.getZ(), new Block(0));
|
||||
instance.setBlock(position.getX(), position.getY(), position.getZ(), (short) 0);
|
||||
}
|
||||
} else if (player.getGameMode() == GameMode.SURVIVAL) {
|
||||
player.refreshTargetBlock(position);
|
||||
// TODO survival mining
|
||||
}
|
||||
break;
|
||||
case CANCELLED_DIGGING:
|
||||
player.refreshTargetBlock(null);
|
||||
break;
|
||||
case FINISHED_DIGGING:
|
||||
player.refreshTargetBlock(null);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,28 @@
|
||||
package fr.themode.minestom.net.packet.server.play;
|
||||
|
||||
import fr.adamaq01.ozao.net.Buffer;
|
||||
import fr.themode.minestom.net.packet.client.play.ClientPlayerDiggingPacket;
|
||||
import fr.themode.minestom.net.packet.server.ServerPacket;
|
||||
import fr.themode.minestom.utils.Position;
|
||||
import fr.themode.minestom.utils.Utils;
|
||||
|
||||
public class AcknowledgePlayerDiggingPacket implements ServerPacket {
|
||||
|
||||
public Position position;
|
||||
public int blockStateId;
|
||||
public ClientPlayerDiggingPacket.Status status;
|
||||
public boolean successful;
|
||||
|
||||
@Override
|
||||
public void write(Buffer buffer) {
|
||||
Utils.writePosition(buffer, position);
|
||||
Utils.writeVarInt(buffer, blockStateId);
|
||||
Utils.writeVarInt(buffer, status.ordinal());
|
||||
buffer.putBoolean(successful);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x5c;
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
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.Position;
|
||||
import fr.themode.minestom.utils.Utils;
|
||||
|
||||
public class BlockBreakAnimationPacket implements ServerPacket {
|
||||
|
||||
public int entityId;
|
||||
public Position blockPosition;
|
||||
public byte destroyStage;
|
||||
|
||||
@Override
|
||||
public void write(Buffer buffer) {
|
||||
Utils.writeVarInt(buffer, entityId);
|
||||
Utils.writePosition(buffer, blockPosition);
|
||||
buffer.putByte(destroyStage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x08;
|
||||
}
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
package fr.themode.minestom.net.packet.server.play;
|
||||
|
||||
import fr.adamaq01.ozao.net.Buffer;
|
||||
import fr.themode.minestom.instance.Block;
|
||||
import fr.themode.minestom.instance.Chunk;
|
||||
import fr.themode.minestom.net.packet.server.ServerPacket;
|
||||
import fr.themode.minestom.utils.Utils;
|
||||
@ -30,7 +29,7 @@ public class ChunkDataPacket implements ServerPacket {
|
||||
for (int i = 0; i < 16; i++) {
|
||||
// TODO if fullchunk is false then only send changed sections
|
||||
mask |= 1 << i;
|
||||
Block[] section = getSection(chunk, i);
|
||||
Short[] section = getSection(chunk, i);
|
||||
Utils.writeBlocks(blocks, section, 14);
|
||||
}
|
||||
// Biome data
|
||||
@ -73,13 +72,13 @@ public class ChunkDataPacket implements ServerPacket {
|
||||
Utils.writeVarInt(buffer, 0);
|
||||
}
|
||||
|
||||
private Block[] getSection(Chunk chunk, int section) {
|
||||
Block[] blocks = new Block[16 * 16 * 16];
|
||||
private Short[] getSection(Chunk chunk, int section) {
|
||||
Short[] blocks = new Short[16 * 16 * 16];
|
||||
for (int y = 0; y < 16; y++) {
|
||||
for (int x = 0; x < 16; x++) {
|
||||
for (int z = 0; z < 16; z++) {
|
||||
int index = (((y * 16) + x) * 16) + z;
|
||||
blocks[index] = chunk.getBlock(x, y + 16 * section, z);
|
||||
blocks[index] = chunk.getBlockId(x, y + 16 * section, z);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,28 @@
|
||||
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 EntityEffectPacket implements ServerPacket {
|
||||
|
||||
public int entityId;
|
||||
public byte effectId;
|
||||
public byte amplifier;
|
||||
public int duration;
|
||||
public byte flags;
|
||||
|
||||
@Override
|
||||
public void write(Buffer buffer) {
|
||||
Utils.writeVarInt(buffer, entityId);
|
||||
buffer.putByte(effectId);
|
||||
buffer.putByte(amplifier);
|
||||
Utils.writeVarInt(buffer, duration);
|
||||
buffer.putByte(flags);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x59;
|
||||
}
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
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 RemoveEntityEffectPacket implements ServerPacket {
|
||||
|
||||
public int entityId;
|
||||
public byte effectId;
|
||||
|
||||
@Override
|
||||
public void write(Buffer buffer) {
|
||||
Utils.writeVarInt(buffer, entityId);
|
||||
buffer.putByte(effectId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
return 0x38;
|
||||
}
|
||||
}
|
@ -33,4 +33,9 @@ public class Position {
|
||||
public void setZ(int z) {
|
||||
this.z = z;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Position[" + x + ":" + y + ":" + z + "]";
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
package fr.themode.minestom.utils;
|
||||
|
||||
import fr.adamaq01.ozao.net.Buffer;
|
||||
import fr.themode.minestom.instance.Block;
|
||||
import fr.themode.minestom.item.ItemStack;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
@ -122,7 +121,11 @@ public class Utils {
|
||||
}
|
||||
|
||||
public static void writePosition(Buffer buffer, int x, int y, int z) {
|
||||
buffer.putLong(((x & 0x3FFFFFF) << 38) | ((z & 0x3FFFFFF) << 12) | (y & 0xFFF));
|
||||
buffer.putLong((((long) x & 0x3FFFFFF) << 38) | (((long) z & 0x3FFFFFF) << 12) | ((long) y & 0xFFF));
|
||||
}
|
||||
|
||||
public static void writePosition(Buffer buffer, Position position) {
|
||||
writePosition(buffer, position.getX(), position.getY(), position.getZ());
|
||||
}
|
||||
|
||||
public static Position readPosition(Buffer buffer) {
|
||||
@ -144,8 +147,8 @@ public class Utils {
|
||||
}
|
||||
}
|
||||
|
||||
public static void writeBlocks(Buffer buffer, Block[] blocks, int bitsPerEntry) {
|
||||
buffer.putShort((short) Arrays.stream(blocks).filter(customBlock -> customBlock.getType() != 0).collect(Collectors.toList()).size());
|
||||
public static void writeBlocks(Buffer buffer, Short[] blocksId, int bitsPerEntry) {
|
||||
buffer.putShort((short) Arrays.stream(blocksId).filter(customBlock -> customBlock != 0).collect(Collectors.toList()).size());
|
||||
buffer.putByte((byte) bitsPerEntry);
|
||||
int[] blocksData = new int[16 * 16 * 16];
|
||||
for (int y = 0; y < 16; y++) {
|
||||
@ -153,7 +156,7 @@ public class Utils {
|
||||
for (int z = 0; z < 16; z++) {
|
||||
int sectionIndex = (((y * 16) + x) * 16) + z;
|
||||
int index = y << 8 | z << 4 | x;
|
||||
blocksData[index] = blocks[sectionIndex].getType();
|
||||
blocksData[index] = blocksId[sectionIndex];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user