From 982d260a921e1d32c073d1c8b79ab49c55835245 Mon Sep 17 00:00:00 2001 From: p2r3 Date: Sun, 17 Aug 2025 01:06:35 +0300 Subject: [PATCH] implement furnaces and fix crafting --- build_registries.js | 8 +++++- src/crafting.c | 61 +++++++++++++++++++++++++++++++++++++++++++++ src/crafting.h | 1 + src/globals.h | 1 + src/packets.c | 25 ++++++++++++++++--- src/tools.c | 8 ++++++ 6 files changed, 100 insertions(+), 4 deletions(-) diff --git a/build_registries.js b/build_registries.js index 0ed846a..578c562 100644 --- a/build_registries.js +++ b/build_registries.js @@ -271,7 +271,8 @@ async function convert () { itemsAndBlocks.blockRegistry["gold_ore"], itemsAndBlocks.blockRegistry["redstone_ore"], itemsAndBlocks.blockRegistry["iron_ore"], - itemsAndBlocks.blockRegistry["coal_ore"] + itemsAndBlocks.blockRegistry["coal_ore"], + itemsAndBlocks.blockRegistry["furnace"] ], "mineable/axe": [ itemsAndBlocks.blockRegistry["oak_log"], @@ -282,6 +283,11 @@ async function convert () { itemsAndBlocks.blockRegistry["grass_block"], itemsAndBlocks.blockRegistry["dirt"] ], + }, + "item": { + "planks": [ + itemsAndBlocks.items["oak_planks"] + ] } }); diff --git a/src/crafting.c b/src/crafting.c index 4e8f608..3958036 100644 --- a/src/crafting.c +++ b/src/crafting.c @@ -1,8 +1,10 @@ #include #include +#include #include "globals.h" #include "registries.h" +#include "tools.h" #include "crafting.h" void getCraftingOutput (PlayerData *player, uint8_t *count, uint16_t *item) { @@ -171,6 +173,19 @@ void getCraftingOutput (PlayerData *player, uint8_t *count, uint16_t *item) { } break; + case 8: + switch (first_item) { + case I_cobblestone: + if (player->craft_items[first + 4] == 0) { + *item = I_furnace; + *count = 1; + return; + } + break; + + default: break; + } + default: break; } @@ -179,3 +194,49 @@ void getCraftingOutput (PlayerData *player, uint8_t *count, uint16_t *item) { *item = 0; } + +#define registerSmeltingRecipe(a, b) \ + if (*material == a && (*output_item == b || *output_item == 0)) *output_item = b + +void getSmeltingOutput (PlayerData *player) { + + uint8_t *material_count = &player->craft_count[0]; + uint8_t *fuel_count = &player->craft_count[1]; + + if (*material_count == 0 || *fuel_count == 0) return; + + uint16_t *material = &player->craft_items[0]; + uint16_t *fuel = &player->craft_items[1]; + + uint8_t *output_count = &player->craft_count[2]; + uint16_t *output_item = &player->craft_items[2]; + + uint8_t fuel_value; + if (*fuel == I_coal) fuel_value = 8; + else if (*fuel == I_charcoal) fuel_value = 8; + else if (*fuel == I_oak_planks) fuel_value = 1 + (fast_rand() & 1); + else if (*fuel == I_oak_log) fuel_value = 1 + (fast_rand() & 1); + else return; + + uint8_t exchange = *material_count > fuel_value ? fuel_value : *material_count; + + registerSmeltingRecipe(I_cobblestone, I_stone); + else registerSmeltingRecipe(I_oak_log, I_charcoal); + else registerSmeltingRecipe(I_raw_iron, I_iron_ingot); + else registerSmeltingRecipe(I_raw_gold, I_gold_ingot); + else return; + + *output_count += exchange; + *material_count -= exchange; + + *fuel_count -= 1; + if (*fuel_count == 0) *fuel = 0; + + if (*material_count <= 0) { + *material_count = 0; + *material = 0; + } else return getSmeltingOutput(player); + + return; + +} diff --git a/src/crafting.h b/src/crafting.h index 88d296f..d512ef2 100644 --- a/src/crafting.h +++ b/src/crafting.h @@ -6,5 +6,6 @@ #include "globals.h" void getCraftingOutput (PlayerData *player, uint8_t *count, uint16_t *item); +void getSmeltingOutput (PlayerData *player); #endif diff --git a/src/globals.h b/src/globals.h index addd3a0..aa192df 100644 --- a/src/globals.h +++ b/src/globals.h @@ -53,6 +53,7 @@ typedef struct { uint16_t inventory_items[41]; uint16_t craft_items[9]; uint8_t inventory_count[41]; + uint8_t craft_count[9]; } PlayerData; #pragma pack(pop) diff --git a/src/packets.c b/src/packets.c index 479ef0e..0925b49 100644 --- a/src/packets.c +++ b/src/packets.c @@ -467,6 +467,9 @@ int cs_useItemOn (int client_fd) { if (target == B_crafting_table) { sc_openScreen(client_fd, 12, "Crafting", 8); return 0; + } else if (target == B_furnace) { + sc_openScreen(client_fd, 14, "Furnace", 7); + return 0; } PlayerData *player; @@ -527,7 +530,7 @@ int cs_clickContainer (int client_fd) { if (!readByte(client_fd)) { // no item? if (slot != 255) { player->inventory_items[slot] = 0; - if (slot <= 40) player->inventory_count[slot] = 0; + player->inventory_count[slot] = 0; } continue; } @@ -543,14 +546,30 @@ int cs_clickContainer (int client_fd) { if (count > 0) { player->inventory_items[slot] = item; - if (slot <= 40) player->inventory_count[slot] = count; + player->inventory_count[slot] = count; } } - if (craft) { + // window 0 is player inventory, window 12 is crafting table + if (craft && (window_id == 0 || window_id == 12)) { getCraftingOutput(player, &count, &item); sc_setContainerSlot(client_fd, window_id, 0, count, item); + } else if (window_id == 14) { // furnace + getSmeltingOutput(player); + for (int i = 0; i < 3; i ++) { + sc_setContainerSlot(client_fd, window_id, i, player->craft_count[i], player->craft_items[i]); + } + } + + // read but ignore carried item slot (for now) + if (readByte(client_fd)) { + readVarInt(client_fd); + readVarInt(client_fd); + tmp = readVarInt(client_fd); + recv(client_fd, recv_buffer, tmp, MSG_WAITALL); + tmp = readVarInt(client_fd); + recv(client_fd, recv_buffer, tmp, MSG_WAITALL); } return 0; diff --git a/src/tools.c b/src/tools.c index f1e8a9d..38ecd9b 100644 --- a/src/tools.c +++ b/src/tools.c @@ -225,6 +225,14 @@ uint8_t clientSlotToServerSlot (int window_id, uint8_t slot) { // the rest of the slots are identical, just shifted by one if (slot >= 10 && slot <= 45) return clientSlotToServerSlot(0, slot - 1); + } else if (window_id == 14) { // furnace + + // move furnace items to the player's crafting grid + // this lets us put them back in the inventory once the window closes + if (slot >= 0 && slot <= 2) return 41 + slot; + // the rest of the slots are identical, just shifted by 6 + if (slot >= 3 && slot <= 38) return clientSlotToServerSlot(0, slot + 6); + } return 255;