return items to inventory when closing crafting window

This commit is contained in:
p2r3
2025-08-17 19:24:31 +03:00
parent d66175d91f
commit d27b085ae5
5 changed files with 63 additions and 17 deletions

View File

@@ -94,7 +94,7 @@ void handlePacket (int client_fd, int length, int packet_id) {
sc_synchronizePlayerPosition(client_fd, spawn_x, spawn_y, spawn_z, spawn_yaw, spawn_pitch);
for (uint8_t i = 0; i < 41; i ++) {
sc_setContainerSlot(client_fd, 0, serverSlotToClientSlot(i), player->inventory_count[i], player->inventory_items[i]);
sc_setContainerSlot(client_fd, 0, serverSlotToClientSlot(0, i), player->inventory_count[i], player->inventory_items[i]);
}
sc_setHeldItem(client_fd, player->hotbar);
@@ -146,6 +146,13 @@ void handlePacket (int client_fd, int length, int packet_id) {
}
break;
case 0x12:
if (state == STATE_PLAY) {
cs_closeContainer(client_fd);
return;
}
break;
case 0x1D:
case 0x1E:
if (state == STATE_PLAY) {

View File

@@ -430,7 +430,11 @@ int cs_playerAction (int client_fd) {
makeBlockChange(x, y, z, 0);
if (item) givePlayerItem(client_fd, item);
if (item) {
PlayerData *player;
if (getPlayerData(client_fd, &player)) return 1;
givePlayerItem(player, item, 1);
}
}
@@ -643,6 +647,26 @@ int sc_setHeldItem (int client_fd, uint8_t slot) {
return 0;
}
// C->S Close Container (serverbound)
int cs_closeContainer (int client_fd) {
uint8_t window_id = readVarInt(client_fd);
PlayerData *player;
if (getPlayerData(client_fd, &player)) return 1;
// return all items in crafting slots to the player
for (uint8_t i = 0; i < 9; i ++) {
givePlayerItem(player, player->craft_items[i], player->craft_count[i]);
player->craft_items[i] = 0;
player->craft_count[i] = 0;
uint8_t client_slot = serverSlotToClientSlot(window_id, 41 + i);
if (client_slot != 255) sc_setContainerSlot(player->client_fd, 0, client_slot, 0, 0);
}
return 0;
}
// S->C Registry Data (multiple packets) and Update Tags (configuration, multiple packets)
int sc_registries (int client_fd) {

View File

@@ -11,6 +11,7 @@ int cs_setPlayerPositionAndRotation (int client_fd, double *x, double *y, double
int cs_setPlayerPosition (int client_fd, double *x, double *y, double *z);
int cs_setHeldItem (int client_fd);
int cs_clickContainer (int client_fd);
int cs_closeContainer (int client_fd);
int sc_loginSuccess (int client_fd, char *name, char *uuid);
int sc_knownPacks (int client_fd);

View File

@@ -194,11 +194,28 @@ void clearPlayerFD (int client_fd) {
}
}
uint8_t serverSlotToClientSlot (uint8_t slot) {
if (slot < 9) return slot + 36;
if (slot >= 9 && slot <= 35) return slot;
if (slot == 40) return 45;
if (slot >= 36 && slot <= 39) return 3 - (slot - 36) + 5;
uint8_t serverSlotToClientSlot (int window_id, uint8_t slot) {
if (window_id == 0) { // player inventory
if (slot < 9) return slot + 36;
if (slot >= 9 && slot <= 35) return slot;
if (slot == 40) return 45;
if (slot >= 36 && slot <= 39) return 3 - (slot - 36) + 5;
if (slot >= 41 && slot <= 44) return slot - 40;
} else if (window_id == 12) { // crafting table
if (slot >= 41 && slot <= 49) return slot - 40;
return serverSlotToClientSlot(0, slot - 1);
} else if (window_id == 14) { // furnace
if (slot >= 41 && slot <= 43) return slot - 41;
return serverSlotToClientSlot(0, slot + 6);
}
return 255;
}
@@ -238,14 +255,11 @@ uint8_t clientSlotToServerSlot (int window_id, uint8_t slot) {
return 255;
}
int givePlayerItem (int client_fd, uint16_t item) {
PlayerData *player;
if (getPlayerData(client_fd, &player)) return 1;
int givePlayerItem (PlayerData *player, uint16_t item, uint8_t count) {
uint8_t slot = 255;
for (int i = 0; i < 41; i ++) {
if (player->inventory_items[i] == item && player->inventory_count[i] < 64) {
if (player->inventory_items[i] == item && player->inventory_count[i] <= 64 - count) {
slot = i;
break;
}
@@ -263,8 +277,8 @@ int givePlayerItem (int client_fd, uint16_t item) {
if (slot == 255) return 1;
player->inventory_items[slot] = item;
player->inventory_count[slot] ++;
sc_setContainerSlot(client_fd, 0, serverSlotToClientSlot(slot), player->inventory_count[slot], item);
player->inventory_count[slot] += count;
sc_setContainerSlot(player->client_fd, 0, serverSlotToClientSlot(0, slot), player->inventory_count[slot], item);
return 0;
@@ -324,7 +338,7 @@ uint16_t getMiningResult (int client_fd, uint8_t block) {
) {
player->inventory_items[player->hotbar] = 0;
player->inventory_count[player->hotbar] = 0;
sc_setContainerSlot(client_fd, 0, serverSlotToClientSlot(player->hotbar), 0, 0);
sc_setContainerSlot(client_fd, 0, serverSlotToClientSlot(0, player->hotbar), 0, 0);
}
switch (block) {

View File

@@ -35,9 +35,9 @@ int getClientIndex (int client_fd);
int reservePlayerData (int client_fd, char *uuid);
int getPlayerData (int client_fd, PlayerData **output);
void clearPlayerFD (int client_fd);
int givePlayerItem (int client_fd, uint16_t item);
int givePlayerItem (PlayerData *player, uint16_t item, uint8_t count);
uint8_t serverSlotToClientSlot (uint8_t slot);
uint8_t serverSlotToClientSlot (int window_id, uint8_t slot);
uint8_t clientSlotToServerSlot (int window_id, uint8_t slot);
uint8_t getBlockChange (short x, short y, short z);