implement crafting tables (crudely)

This commit is contained in:
p2r3
2025-08-12 18:22:37 +03:00
parent 1fc0f75ed7
commit de2228390e
4 changed files with 55 additions and 19 deletions

View File

@@ -315,18 +315,18 @@ int sc_keepAlive (int client_fd) {
}
// S->C Set Container Slot
int sc_setContainerSlot (int client_fd, int container, uint16_t slot, uint8_t count, uint16_t item) {
int sc_setContainerSlot (int client_fd, int window_id, uint16_t slot, uint8_t count, uint16_t item) {
writeVarInt(client_fd,
1 +
sizeVarInt(container) +
sizeVarInt(window_id) +
1 + 2 +
sizeVarInt(count) +
(count > 0 ? sizeVarInt(item) + 2 : 0)
);
writeByte(client_fd, 0x14);
writeVarInt(client_fd, container);
writeVarInt(client_fd, window_id);
writeVarInt(client_fd, 0);
writeUint16(client_fd, slot);
@@ -381,12 +381,27 @@ int cs_playerAction (int client_fd) {
}
// S->C Open Screen
int sc_openScreen (int client_fd, uint8_t window, const char *title, uint16_t length) {
writeVarInt(client_fd, 1 + 2 * sizeVarInt(window) + 1 + 2 + length);
writeByte(client_fd, 0x34);
writeVarInt(client_fd, window);
writeVarInt(client_fd, window);
writeByte(client_fd, 8); // string nbt tag
writeUint16(client_fd, length); // string length
send(client_fd, title, length, 0);
}
// C->S Use Item On
int cs_useItemOn (int client_fd) {
uint8_t hand = readByte(client_fd);
uint64_t pos = readUint64(client_fd);
int64_t pos = readInt64(client_fd);
int x = pos >> 38;
int y = pos << 52 >> 52;
int z = pos << 26 >> 38;
@@ -404,10 +419,17 @@ int cs_useItemOn (int client_fd) {
int sequence = readVarInt(client_fd);
uint8_t target = getBlockAt(x, y, z);
if (target == B_crafting_table) {
sc_openScreen(client_fd, 12, "Crafting", 8);
return 0;
}
PlayerData *player;
if (getPlayerData(client_fd, &player)) return 1;
uint8_t block = I_to_B[player->inventory_items[player->hotbar]];
uint16_t item = player->inventory_items[player->hotbar];
uint8_t block = item == 320 ? B_crafting_table : I_to_B[item]; // hack!!
// if the selected item doesn't correspond to a block, exit
if (block == 0) return 0;
@@ -454,7 +476,8 @@ int cs_clickContainer (int client_fd) {
for (int i = 0; i < changes_count; i ++) {
slot = clientSlotToServerSlot(readUint16(client_fd));
slot = clientSlotToServerSlot(window_id, readUint16(client_fd));
// slots outside of the inventory overflow into the crafting buffer
if (slot > 40) craft = true;
if (!readByte(client_fd)) { // no item?

View File

@@ -22,8 +22,9 @@ int sc_startWaitingForChunks (int client_fd);
int sc_setCenterChunk (int client_fd, int x, int y);
int sc_chunkDataAndUpdateLight (int client_fd, int _x, int _z);
int sc_keepAlive (int client_fd);
int sc_setContainerSlot (int client_fd, int container, uint16_t slot, uint8_t count, uint16_t item);
int sc_setContainerSlot (int client_fd, int window_id, uint16_t slot, uint8_t count, uint16_t item);
int sc_setHeldItem (int client_fd, uint8_t slot);
int sc_openScreen (int client_fd, uint8_t window, const char *title, uint16_t length);
int sc_registries(int client_fd);
#endif

View File

@@ -181,18 +181,30 @@ uint8_t serverSlotToClientSlot (uint8_t slot) {
return 255;
}
uint8_t clientSlotToServerSlot (uint8_t slot) {
if (slot >= 36 && slot <= 44) return slot - 36;
if (slot >= 9 && slot <= 35) return slot;
if (slot == 45) return 40;
if (slot >= 5 && slot <= 8) return 4 - (slot - 5) + 36;
uint8_t clientSlotToServerSlot (int window_id, uint8_t slot) {
// map inventory crafting slots to player data crafting grid (semi-hack)
// this abuses the fact that the buffers are adjacent in player data
if (slot == 1) return 41;
if (slot == 2) return 42;
if (slot == 3) return 44;
if (slot == 4) return 45;
if (window_id == 0) { // player inventory
if (slot >= 36 && slot <= 44) return slot - 36;
if (slot >= 9 && slot <= 35) return slot;
if (slot == 45) return 40;
if (slot >= 5 && slot <= 8) return 4 - (slot - 5) + 36;
// map inventory crafting slots to player data crafting grid (semi-hack)
// this abuses the fact that the buffers are adjacent in player data
if (slot == 1) return 41;
if (slot == 2) return 42;
if (slot == 3) return 44;
if (slot == 4) return 45;
} else if (window_id == 12) { // crafting table
// same crafting offset overflow hack as above
if (slot >= 1 && slot <= 9) return 40 + slot;
// the rest of the slots are identical, just shifted by one
if (slot >= 10 && slot <= 45) return clientSlotToServerSlot(0, slot - 1);
}
return 255;
}

View File

@@ -37,7 +37,7 @@ void clearPlayerFD (int client_fd);
int givePlayerItem (int client_fd, uint16_t item);
uint8_t serverSlotToClientSlot (uint8_t slot);
uint8_t clientSlotToServerSlot (uint8_t slot);
uint8_t clientSlotToServerSlot (int window_id, uint8_t slot);
uint8_t getBlockChange (short x, short y, short z);
void makeBlockChange (short x, short y, short z, uint8_t block);