From a7cad496e3624e72ec698fd35ffc9a697ed843e2 Mon Sep 17 00:00:00 2001 From: Fireblade <72758695+Firebladedoge229@users.noreply.github.com> Date: Sun, 3 May 2026 01:43:43 -0400 Subject: [PATCH] fix: tutorial items actually appear now yay item frames though... --- .../Windows64Media/loc/itemId.json | 482 ++++++++++++++++++ Minecraft.World/ChestTileEntity.cpp | 16 +- Minecraft.World/ItemEntity.cpp | 2 + Minecraft.World/ItemInstance.cpp | 248 ++++++++- Minecraft.World/LiquidTileDynamic.cpp | 9 +- Minecraft.World/PathFinder.cpp | 1 + Minecraft.World/PathNavigation.cpp | 8 +- 7 files changed, 759 insertions(+), 7 deletions(-) create mode 100644 Minecraft.Client/Windows64Media/loc/itemId.json diff --git a/Minecraft.Client/Windows64Media/loc/itemId.json b/Minecraft.Client/Windows64Media/loc/itemId.json new file mode 100644 index 00000000..f6224f5c --- /dev/null +++ b/Minecraft.Client/Windows64Media/loc/itemId.json @@ -0,0 +1,482 @@ +{ + "minecraft:stone": 1, + "minecraft:grass": 2, + "minecraft:dirt": 3, + "minecraft:cobblestone": 4, + "minecraft:planks": 5, + "minecraft:sapling": 6, + "minecraft:bedrock": 7, + "minecraft:flowing_water": 8, + "minecraft:water": 9, + "minecraft:flowing_lava": 10, + "minecraft:lava": 11, + "minecraft:sand": 12, + "minecraft:gravel": 13, + "minecraft:gold_ore": 14, + "minecraft:iron_ore": 15, + "minecraft:coal_ore": 16, + "minecraft:log": 17, + "minecraft:leaves": 18, + "minecraft:sponge": 19, + "minecraft:glass": 20, + "minecraft:lapis_ore": 21, + "minecraft:lapis_block": 22, + "minecraft:dispenser": 23, + "minecraft:sandstone": 24, + "minecraft:noteblock": 25, + "minecraft:bed": 26, + "minecraft:golden_rail": 27, + "minecraft:detector_rail": 28, + "minecraft:sticky_piston": 29, + "minecraft:web": 30, + "minecraft:tallgrass": 31, + "minecraft:deadbush": 32, + "minecraft:piston": 33, + "minecraft:piston_head": 34, + "minecraft:wool": 35, + "minecraft:piston_extension": 36, + "minecraft:yellow_flower": 37, + "minecraft:red_flower": 38, + "minecraft:brown_mushroom": 39, + "minecraft:red_mushroom": 40, + "minecraft:gold_block": 41, + "minecraft:iron_block": 42, + "minecraft:double_stone_slab": 43, + "minecraft:stone_slab": 44, + "minecraft:brick_block": 45, + "minecraft:tnt": 46, + "minecraft:bookshelf": 47, + "minecraft:mossy_cobblestone": 48, + "minecraft:obsidian": 49, + "minecraft:torch": 50, + "minecraft:fire": 51, + "minecraft:mob_spawner": 52, + "minecraft:oak_stairs": 53, + "minecraft:chest": 54, + "minecraft:redstone_wire": 55, + "minecraft:diamond_ore": 56, + "minecraft:diamond_block": 57, + "minecraft:crafting_table": 58, + "minecraft:wheat": 59, + "minecraft:farmland": 60, + "minecraft:furnace": 61, + "minecraft:lit_furnace": 62, + "minecraft:standing_sign": 63, + "minecraft:wooden_door": 64, + "minecraft:ladder": 65, + "minecraft:rail": 66, + "minecraft:stone_stairs": 67, + "minecraft:wall_sign": 68, + "minecraft:lever": 69, + "minecraft:stone_pressure_plate": 70, + "minecraft:iron_door": 71, + "minecraft:wooden_pressure_plate": 72, + "minecraft:redstone_ore": 73, + "minecraft:lit_redstone_ore": 74, + "minecraft:unlit_redstone_torch": 75, + "minecraft:redstone_torch": 76, + "minecraft:stone_button": 77, + "minecraft:snow_layer": 78, + "minecraft:ice": 79, + "minecraft:snow": 80, + "minecraft:cactus": 81, + "minecraft:clay": 82, + "minecraft:reeds": 83, + "minecraft:jukebox": 84, + "minecraft:fence": 85, + "minecraft:pumpkin": 86, + "minecraft:netherrack": 87, + "minecraft:soul_sand": 88, + "minecraft:glowstone": 89, + "minecraft:portal": 90, + "minecraft:lit_pumpkin": 91, + "minecraft:cake": 92, + "minecraft:unpowered_repeater": 93, + "minecraft:powered_repeater": 94, + "minecraft:stained_glass": 95, + "minecraft:trapdoor": 96, + "minecraft:monster_egg": 97, + "minecraft:stonebrick": 98, + "minecraft:brown_mushroom_block": 99, + "minecraft:red_mushroom_block": 100, + "minecraft:iron_bars": 101, + "minecraft:glass_pane": 102, + "minecraft:melon_block": 103, + "minecraft:pumpkin_stem": 104, + "minecraft:melon_stem": 105, + "minecraft:vine": 106, + "minecraft:fence_gate": 107, + "minecraft:brick_stairs": 108, + "minecraft:stone_brick_stairs": 109, + "minecraft:mycelium": 110, + "minecraft:waterlily": 111, + "minecraft:nether_brick": 112, + "minecraft:nether_brick_fence": 113, + "minecraft:nether_brick_stairs": 114, + "minecraft:nether_wart": 115, + "minecraft:enchanting_table": 116, + "minecraft:brewing_stand": 117, + "minecraft:cauldron": 118, + "minecraft:end_portal": 119, + "minecraft:end_portal_frame": 120, + "minecraft:end_stone": 121, + "minecraft:dragon_egg": 122, + "minecraft:redstone_lamp": 123, + "minecraft:lit_redstone_lamp": 124, + "minecraft:double_wooden_slab": 125, + "minecraft:wooden_slab": 126, + "minecraft:cocoa": 127, + "minecraft:sandstone_stairs": 128, + "minecraft:emerald_ore": 129, + "minecraft:ender_chest": 130, + "minecraft:tripwire_hook": 131, + "minecraft:tripwire": 132, + "minecraft:emerald_block": 133, + "minecraft:spruce_stairs": 134, + "minecraft:birch_stairs": 135, + "minecraft:jungle_stairs": 136, + "minecraft:beacon": 138, + "minecraft:cobblestone_wall": 139, + "minecraft:flower_pot": 140, + "minecraft:carrots": 141, + "minecraft:potatoes": 142, + "minecraft:wooden_button": 143, + "minecraft:skull": 144, + "minecraft:anvil": 145, + "minecraft:trapped_chest": 146, + "minecraft:light_weighted_pressure_plate": 147, + "minecraft:heavy_weighted_pressure_plate": 148, + "minecraft:unpowered_comparator": 149, + "minecraft:powered_comparator": 150, + "minecraft:daylight_detector": 151, + "minecraft:redstone_block": 152, + "minecraft:quartz_ore": 153, + "minecraft:hopper": 154, + "minecraft:quartz_block": 155, + "minecraft:quartz_stairs": 156, + "minecraft:activator_rail": 157, + "minecraft:dropper": 158, + "minecraft:stained_hardened_clay": 159, + "minecraft:stained_glass_pane": 160, + "minecraft:leaves2": 161, + "minecraft:log2": 162, + "minecraft:acacia_stairs": 163, + "minecraft:dark_oak_stairs": 164, + "minecraft:slime": 165, + "minecraft:barrier": 166, + "minecraft:iron_trapdoor": 167, + "minecraft:prismarine": 168, + "minecraft:sea_lantern": 169, + "minecraft:hay_block": 170, + "minecraft:carpet": 171, + "minecraft:hardened_clay": 172, + "minecraft:coal_block": 173, + "minecraft:packed_ice": 174, + "minecraft:double_plant": 175, + "minecraft:standing_banner": 176, + "minecraft:wall_banner": 177, + "minecraft:daylight_detector_inverted": 178, + "minecraft:red_sandstone": 179, + "minecraft:red_sandstone_stairs": 180, + "minecraft:double_stone_slab2": 181, + "minecraft:stone_slab2": 182, + "minecraft:spruce_fence_gate": 183, + "minecraft:birch_fence_gate": 184, + "minecraft:jungle_fence_gate": 185, + "minecraft:dark_oak_fence_gate": 186, + "minecraft:acacia_fence_gate": 187, + "minecraft:spruce_fence": 188, + "minecraft:birch_fence": 189, + "minecraft:jungle_fence": 190, + "minecraft:dark_oak_fence": 191, + "minecraft:acacia_fence": 192, + "minecraft:spruce_door": 193, + "minecraft:birch_door": 194, + "minecraft:jungle_door": 195, + "minecraft:acacia_door": 196, + "minecraft:dark_oak_door": 197, + "minecraft:end_rod": 198, + "minecraft:chorus_plant": 199, + "minecraft:chorus_flower": 200, + "minecraft:purpur_block": 201, + "minecraft:purpur_pillar": 202, + "minecraft:purpur_stairs": 203, + "minecraft:purpur_double_slab": 204, + "minecraft:purpur_slab": 205, + "minecraft:end_bricks": 206, + "minecraft:beetroots": 207, + "minecraft:grass_path": 208, + "minecraft:end_gateway": 209, + "minecraft:frosted_ice": 212, + "minecraft:magma": 213, + "minecraft:nether_wart_block": 214, + "minecraft:red_nether_brick": 215, + "minecraft:bone_block": 216, + "minecraft:structure_void": 217, + "minecraft:observer": 218, + "minecraft:white_shulker_box": 219, + "minecraft:orange_shulker_box": 220, + "minecraft:magenta_shulker_box": 221, + "minecraft:light_blue_shulker_box": 222, + "minecraft:yellow_shulker_box": 223, + "minecraft:lime_shulker_box": 224, + "minecraft:pink_shulker_box": 225, + "minecraft:gray_shulker_box": 226, + "minecraft:silver_shulker_box": 227, + "minecraft:cyan_shulker_box": 228, + "minecraft:purple_shulker_box": 229, + "minecraft:blue_shulker_box": 230, + "minecraft:brown_shulker_box": 231, + "minecraft:green_shulker_box": 232, + "minecraft:red_shulker_box": 233, + "minecraft:black_shulker_box": 234, + "minecraft:white_glazed_terracotta": 235, + "minecraft:orange_glazed_terracotta": 236, + "minecraft:magenta_glazed_terracotta": 237, + "minecraft:light_blue_glazed_terracotta": 238, + "minecraft:yellow_glazed_terracotta": 239, + "minecraft:lime_glazed_terracotta": 240, + "minecraft:pink_glazed_terracotta": 241, + "minecraft:gray_glazed_terracotta": 242, + "minecraft:silver_glazed_terracotta": 243, + "minecraft:cyan_glazed_terracotta": 244, + "minecraft:purple_glazed_terracotta": 245, + "minecraft:blue_glazed_terracotta": 246, + "minecraft:brown_glazed_terracotta": 247, + "minecraft:green_glazed_terracotta": 248, + "minecraft:red_glazed_terracotta": 249, + "minecraft:black_glazed_terracotta": 250, + "minecraft:concrete": 251, + "minecraft:concrete_powder": 252, + "minecraft:structure_block": 255, + "minecraft:iron_shovel": 256, + "minecraft:iron_pickaxe": 257, + "minecraft:iron_axe": 258, + "minecraft:flint_and_steel": 259, + "minecraft:apple": 260, + "minecraft:bow": 261, + "minecraft:arrow": 262, + "minecraft:coal": 263, + "minecraft:diamond": 264, + "minecraft:iron_ingot": 265, + "minecraft:gold_ingot": 266, + "minecraft:iron_sword": 267, + "minecraft:wooden_sword": 268, + "minecraft:wooden_shovel": 269, + "minecraft:wooden_pickaxe": 270, + "minecraft:wooden_axe": 271, + "minecraft:stone_sword": 272, + "minecraft:stone_shovel": 273, + "minecraft:stone_pickaxe": 274, + "minecraft:stone_axe": 275, + "minecraft:diamond_sword": 276, + "minecraft:diamond_shovel": 277, + "minecraft:diamond_pickaxe": 278, + "minecraft:diamond_axe": 279, + "minecraft:stick": 280, + "minecraft:bowl": 281, + "minecraft:mushroom_stew": 282, + "minecraft:golden_sword": 283, + "minecraft:golden_shovel": 284, + "minecraft:golden_pickaxe": 285, + "minecraft:golden_axe": 286, + "minecraft:string": 287, + "minecraft:feather": 288, + "minecraft:gunpowder": 289, + "minecraft:wooden_hoe": 290, + "minecraft:stone_hoe": 291, + "minecraft:iron_hoe": 292, + "minecraft:diamond_hoe": 293, + "minecraft:golden_hoe": 294, + "minecraft:wheat_seeds": 295, + "minecraft:wheat": 296, + "minecraft:bread": 297, + "minecraft:leather_helmet": 298, + "minecraft:leather_chestplate": 299, + "minecraft:leather_leggings": 300, + "minecraft:leather_boots": 301, + "minecraft:chainmail_helmet": 302, + "minecraft:chainmail_chestplate": 303, + "minecraft:chainmail_leggings": 304, + "minecraft:chainmail_boots": 305, + "minecraft:iron_helmet": 306, + "minecraft:iron_chestplate": 307, + "minecraft:iron_leggings": 308, + "minecraft:iron_boots": 309, + "minecraft:diamond_helmet": 310, + "minecraft:diamond_chestplate": 311, + "minecraft:diamond_leggings": 312, + "minecraft:diamond_boots": 313, + "minecraft:golden_helmet": 314, + "minecraft:golden_chestplate": 315, + "minecraft:golden_leggings": 316, + "minecraft:golden_boots": 317, + "minecraft:flint": 318, + "minecraft:porkchop": 319, + "minecraft:cooked_porkchop": 320, + "minecraft:painting": 321, + "minecraft:golden_apple": 322, + "minecraft:sign": 323, + "minecraft:wooden_door": 324, + "minecraft:bucket": 325, + "minecraft:water_bucket": 326, + "minecraft:lava_bucket": 327, + "minecraft:minecart": 328, + "minecraft:saddle": 329, + "minecraft:iron_door": 330, + "minecraft:redstone": 331, + "minecraft:snowball": 332, + "minecraft:boat": 333, + "minecraft:leather": 334, + "minecraft:milk_bucket": 335, + "minecraft:brick": 336, + "minecraft:clay_ball": 337, + "minecraft:reeds": 338, + "minecraft:paper": 339, + "minecraft:book": 340, + "minecraft:slime_ball": 341, + "minecraft:chest_minecart": 342, + "minecraft:furnace_minecart": 343, + "minecraft:egg": 344, + "minecraft:compass": 345, + "minecraft:fishing_rod": 346, + "minecraft:clock": 347, + "minecraft:glowstone_dust": 348, + "minecraft:fish": 349, + "minecraft:cooked_fish": 350, + "minecraft:dye": 351, + "minecraft:bone": 352, + "minecraft:sugar": 353, + "minecraft:cake": 354, + "minecraft:bed": 355, + "minecraft:repeater": 356, + "minecraft:cookie": 357, + "minecraft:filled_map": 358, + "minecraft:shears": 359, + "minecraft:melon": 360, + "minecraft:pumpkin_seeds": 361, + "minecraft:melon_seeds": 362, + "minecraft:beef": 363, + "minecraft:cooked_beef": 364, + "minecraft:chicken": 365, + "minecraft:cooked_chicken": 366, + "minecraft:rotten_flesh": 367, + "minecraft:ender_pearl": 368, + "minecraft:blaze_rod": 369, + "minecraft:ghast_tear": 370, + "minecraft:gold_nugget": 371, + "minecraft:nether_wart": 372, + "minecraft:potion": 373, + "minecraft:glass_bottle": 374, + "minecraft:spider_eye": 375, + "minecraft:fermented_spider_eye": 376, + "minecraft:blaze_powder": 377, + "minecraft:magma_cream": 378, + "minecraft:brewing_stand": 379, + "minecraft:cauldron": 380, + "minecraft:ender_eye": 381, + "minecraft:speckled_melon": 382, + "minecraft:spawn_egg": 383, + "minecraft:experience_bottle": 384, + "minecraft:fire_charge": 385, + "minecraft:writable_book": 386, + "minecraft:written_book": 387, + "minecraft:emerald": 388, + "minecraft:item_frame": 389, + "minecraft:flower_pot": 390, + "minecraft:carrot": 391, + "minecraft:potato": 392, + "minecraft:baked_potato": 393, + "minecraft:poisonous_potato": 394, + "minecraft:map": 395, + "minecraft:golden_carrot": 396, + "minecraft:skull": 397, + "minecraft:carrot_on_a_stick": 398, + "minecraft:nether_star": 399, + "minecraft:pumpkin_pie": 400, + "minecraft:fireworks": 401, + "minecraft:firework_charge": 402, + "minecraft:enchanted_book": 403, + "minecraft:comparator": 404, + "minecraft:netherbrick": 405, + "minecraft:quartz": 406, + "minecraft:tnt_minecart": 407, + "minecraft:hopper_minecart": 408, + "minecraft:prismarine_shard": 409, + "minecraft:prismarine_crystals": 410, + "minecraft:rabbit": 411, + "minecraft:cooked_rabbit": 412, + "minecraft:rabbit_stew": 413, + "minecraft:rabbit_foot": 414, + "minecraft:rabbit_hide": 415, + "minecraft:armor_stand": 416, + "minecraft:iron_horse_armor": 417, + "minecraft:golden_horse_armor": 418, + "minecraft:diamond_horse_armor": 419, + "minecraft:lead": 420, + "minecraft:name_tag": 421, + "minecraft:command_block_minecart": 422, + "minecraft:mutton": 423, + "minecraft:cooked_mutton": 424, + "minecraft:banner": 425, + "minecraft:end_crystal": 426, + "minecraft:spruce_door": 427, + "minecraft:birch_door": 428, + "minecraft:jungle_door": 429, + "minecraft:acacia_door": 430, + "minecraft:dark_oak_door": 431, + "minecraft:chorus_fruit": 432, + "minecraft:chorus_fruit_popped": 433, + "minecraft:beetroot": 434, + "minecraft:beetroot_seeds": 435, + "minecraft:beetroot_soup": 436, + "minecraft:dragon_breath": 437, + "minecraft:splash_potion": 438, + "minecraft:spectral_arrow": 439, + "minecraft:tipped_arrow": 440, + "minecraft:lingering_potion": 441, + "minecraft:shield": 442, + "minecraft:elytra": 443, + "minecraft:spruce_boat": 444, + "minecraft:birch_boat": 445, + "minecraft:jungle_boat": 446, + "minecraft:acacia_boat": 447, + "minecraft:dark_oak_boat": 448, + "minecraft:totem_of_undying": 449, + "minecraft:shulker_shell": 450, + "minecraft:iron_nugget": 452, + "minecraft:leather_horse_armor": 453, + "minecraft:trident": 454, + "minecraft:turtle_shell_piece": 455, + "minecraft:turtle_helmet": 456, + "minecraft:kelp": 457, + "minecraft:dried_kelp": 458, + "minecraft:fish_bucket": 459, + "minecraft:salmon_bucket": 460, + "minecraft:puffer_bucket": 461, + "minecraft:tropical_bucket": 462, + "minecraft:nautilus_core": 463, + "minecraft:nautilus": 464, + "minecraft:phantom_membrane": 465, + "minecraft:sign_spruce": 466, + "minecraft:sign_birch": 467, + "minecraft:sign_acacia": 468, + "minecraft:sign_jungle": 469, + "minecraft:sign_dark_oak": 470, + "minecraft:crossbow": 471, + "minecraft:banner_pattern": 472, + "minecraft:sweet_berries": 473, + "minecraft:debug_fourj_item": 2255, + "minecraft:record_13": 2256, + "minecraft:record_cat": 2257, + "minecraft:record_blocks": 2258, + "minecraft:record_chirp": 2259, + "minecraft:record_far": 2260, + "minecraft:record_mall": 2261, + "minecraft:record_mellohi": 2262, + "minecraft:record_stal": 2263, + "minecraft:record_strad": 2264, + "minecraft:record_ward": 2265, + "minecraft:record_11": 2266, + "minecraft:record_wait": 2267 +} diff --git a/Minecraft.World/ChestTileEntity.cpp b/Minecraft.World/ChestTileEntity.cpp index d702be59..142013ae 100644 --- a/Minecraft.World/ChestTileEntity.cpp +++ b/Minecraft.World/ChestTileEntity.cpp @@ -147,7 +147,21 @@ void ChestTileEntity::load(CompoundTag *base) shared_ptr loadedItem = ItemInstance::fromTag(tag); if (loadedItem == nullptr) { - app.DebugPrintf("[ChestTileEntity] Missing chest item at %d,%d,%d slot=%u id=%d count=%d damage=%d\n", x, y, z, slot, tag->getShort(L"id"), tag->getByte(L"Count"), tag->getShort(L"Damage")); + Tag *idTag = tag->get(L"id"); + int idType = idTag != nullptr ? idTag->getId() : -1; + + if (idType == Tag::TAG_String) + { + app.DebugPrintf("[ChestTileEntity] Missing chest item at %d,%d,%d slot=%u idType=%d idStr=%ls count=%d damage=%d\n", x, y, z, slot, idType, tag->getString(L"id").c_str(), tag->getByte(L"Count"), tag->getShort(L"Damage")); + } + else if (idType == Tag::TAG_Int) + { + app.DebugPrintf("[ChestTileEntity] Missing chest item at %d,%d,%d slot=%u idType=%d id=%d count=%d damage=%d\n", x, y, z, slot, idType, tag->getInt(L"id"), tag->getByte(L"Count"), tag->getShort(L"Damage")); + } + else + { + app.DebugPrintf("[ChestTileEntity] Missing chest item at %d,%d,%d slot=%u idType=%d id=%d count=%d damage=%d\n", x, y, z, slot, idType, tag->getShort(L"id"), tag->getByte(L"Count"), tag->getShort(L"Damage")); + } } (*items)[slot] = loadedItem; } diff --git a/Minecraft.World/ItemEntity.cpp b/Minecraft.World/ItemEntity.cpp index cf921d6c..4ec21a62 100644 --- a/Minecraft.World/ItemEntity.cpp +++ b/Minecraft.World/ItemEntity.cpp @@ -112,6 +112,8 @@ void ItemEntity::tick() { friction = 0.6f * 0.98f; int t = level->getTile( Mth::floor(x), Mth::floor(bb->y0) - 1, Mth::floor(z) ); + Tile *tile = Tile::tiles[t]; + if (tile == nullptr & t != 0) return; // tu31 tutorial world fix if (t > 0) { friction = Tile::tiles[t]->friction * 0.98f; diff --git a/Minecraft.World/ItemInstance.cpp b/Minecraft.World/ItemInstance.cpp index f315f3f0..eedb450a 100644 --- a/Minecraft.World/ItemInstance.cpp +++ b/Minecraft.World/ItemInstance.cpp @@ -14,6 +14,197 @@ #include "ItemInstance.h" #include "HtmlString.h" #include "../Minecraft.Client/Common/Consoles_App.h" +#include +#include +#include +#include +#include +#include "../Minecraft.Server/vendor/nlohmann/json.hpp" + +using nlohmann::json; +namespace fs = std::filesystem; + +namespace +{ +wstring NormalizeItemNameId(const wstring &rawName) +{ + if (rawName.empty()) + { + return rawName; + } + + wstring normalized = rawName; + for (size_t i = 0; i < normalized.size(); ++i) + { + normalized[i] = static_cast(towlower(normalized[i])); + } + + size_t namespaceSep = normalized.find(L':'); + if (namespaceSep != wstring::npos && namespaceSep + 1 < normalized.size()) + { + normalized = normalized.substr(namespaceSep + 1); + } + + return normalized; +} + +wstring ToSnakeCase(const wstring &value) +{ + if (value.empty()) + { + return value; + } + + wstring out; + out.reserve(value.size() * 2); + for (size_t i = 0; i < value.size(); ++i) + { + const wchar_t c = value[i]; + if (c >= L'A' && c <= L'Z') + { + if (i > 0) + { + out.push_back(L'_'); + } + out.push_back(static_cast(towlower(c))); + } + else + { + out.push_back(c); + } + } + + return NormalizeItemNameId(out); +} + +void AddNameAlias(unordered_map &nameToId, const wchar_t *name, int id) +{ + nameToId[NormalizeItemNameId(name)] = id; +} + +bool TryLoadExternalItemIdAliases(unordered_map &nameToId) +{ + static bool attempted = false; + static bool loaded = false; + if (attempted) + { + return loaded; + } + attempted = true; + + // todo: convert canidatePaths to single path now that we know where the mapping file is + + // const vector candidatePaths = { + // "Common/Localization/itemId.json" + // }; + + static const string path = "Common/Localization/itemId.json"; + + app.DebugPrintf("[ItemInstance] Trying to load from: %s\n", path.c_str()); + + if (!fs::exists(path)) + { + app.DebugPrintf("[ItemInstance] File does not exist: %s\n", path.c_str()); + return false; + } + + app.DebugPrintf("[ItemInstance] File exists, reading data...\n"); + + ifstream file(path.c_str(), ios::in); + if (!file.good()) + { + app.DebugPrintf("[ItemInstance] Failed to open file: %s\n", path.c_str()); + return false; + } + try + { + json j = json::parse(file); + if (!j.is_object()) + { + app.DebugPrintf("[ItemInstance] ItemId alias JSON is not a valid object: %s\n", path.c_str()); + return false; + } + for (const auto &entry : j.items()) + { + const string &key = entry.key(); + const auto &value = entry.value(); + if (!value.is_number_integer()) + { + continue; + } + wstring wkey(key.begin(), key.end()); + nameToId[NormalizeItemNameId(wkey)] = value.get(); + } + loaded = true; + app.DebugPrintf("[ItemInstance] SUCCESS: Loaded %zu item id aliases from %s\n", j.size(), path.c_str()); + } + catch (const exception &e) + { + app.DebugPrintf("[ItemInstance] Parsing failed: %s (error: %s)\n", path.c_str(), e.what()); + return false; + } + + if (!loaded) + { + app.DebugPrintf("[ItemInstance] FAILED: No valid ItemId aliases were found.\n"); + } + + return loaded; +} + +int ResolveLegacyItemIdFromStringName(const wstring &rawName) +{ + static unordered_map sNameToId; + static bool sInitialized = false; + + if (!sInitialized) + { + sInitialized = true; + TryLoadExternalItemIdAliases(sNameToId); + } + + const wstring name = NormalizeItemNameId(rawName); + auto it = sNameToId.find(name); + if (it != sNameToId.end()) + { + return it->second; + } + + return -1; +} + +int ParseNumericItemId(const wstring &idString, bool &parsed) +{ + parsed = false; + if (idString.empty()) + { + return 0; + } + + try + { + size_t parseEnd = 0; + long parsedValue = std::stol(idString, &parseEnd, 10); + if (parseEnd == idString.size()) + { + parsed = true; + return static_cast(parsedValue); + } + } + catch (...) + { + } + + return 0; +} + +int ByteSwapShortToInt(short value) +{ + unsigned short raw = static_cast(value); + unsigned short swapped = static_cast((raw >> 8) | (raw << 8)); + return static_cast(swapped); +} +} const wstring ItemInstance::ATTRIBUTE_MODIFIER_FORMAT = L"#.###"; @@ -174,7 +365,62 @@ CompoundTag *ItemInstance::save(CompoundTag *compoundTag) void ItemInstance::load(CompoundTag *compoundTag) { popTime = 0; - id = compoundTag->getShort(L"id"); + id = 0; + Tag *idTag = compoundTag->get(L"id"); + if (idTag != nullptr) + { + switch (idTag->getId()) + { + case Tag::TAG_Int: + id = compoundTag->getInt(L"id"); + break; + case Tag::TAG_Short: + { + short rawId = compoundTag->getShort(L"id"); + id = rawId; + + if ((id < 0 || id >= Item::items.length || Item::items[id] == nullptr) && rawId != 0) + { + int swappedId = ByteSwapShortToInt(rawId); + if (swappedId >= 0 && swappedId < Item::items.length && Item::items[swappedId] != nullptr) + { + app.DebugPrintf("[ItemInstance] Recovered byte-swapped short item id: raw=%d swapped=%d\n", id, swappedId); + id = swappedId; + } + } + break; + } + case Tag::TAG_String: + { + wstring idString = compoundTag->getString(L"id"); + + int mappedId = ResolveLegacyItemIdFromStringName(idString); + if (mappedId >= 0) + { + id = mappedId; + break; + } + + bool parsedNumeric = false; + id = ParseNumericItemId(idString, parsedNumeric); + if (!parsedNumeric) + { + app.DebugPrintf("[ItemInstance] Unsupported string item id '%ls' (expected numeric legacy id)\n", idString.c_str()); + id = 0; + } + break; + } + default: + app.DebugPrintf("[ItemInstance] Unsupported item id tag type %d\n", idTag->getId()); + id = 0; + break; + } + } + else + { + app.DebugPrintf("[ItemInstance] Missing item id tag\n"); + } + count = compoundTag->getByte(L"Count"); auxValue = compoundTag->getShort(L"Damage"); if (auxValue < 0) diff --git a/Minecraft.World/LiquidTileDynamic.cpp b/Minecraft.World/LiquidTileDynamic.cpp index 43d6366c..0394f1ef 100644 --- a/Minecraft.World/LiquidTileDynamic.cpp +++ b/Minecraft.World/LiquidTileDynamic.cpp @@ -207,7 +207,9 @@ void LiquidTileDynamic::trySpreadTo(Level *level, int x, int y, int z, int fromX } else { - Tile::tiles[old]->spawnResources(level, x, y, z, level->getData(x, y, z), 0); + Tile *tile = Tile::tiles[old]; + if (tile == nullptr) return; // tu31 tutorial world fix + tile->spawnResources(level, x, y, z, level->getData(x, y, z), 0); } } } @@ -317,8 +319,9 @@ bool LiquidTileDynamic::isWaterBlocking(Level *level, int x, int y, int z) { return true; } - if (t == 0) return false; - Material *m = Tile::tiles[t]->material; + Tile *tile = Tile::tiles[t]; + if (t == 0 || tile == nullptr) return false; // tu31 tutorial world fix + Material *m = tile->material; if (m == Material::portal) return true; if (m->blocksMotion()) return true; return false; diff --git a/Minecraft.World/PathFinder.cpp b/Minecraft.World/PathFinder.cpp index eb3bd45e..fbb419bb 100644 --- a/Minecraft.World/PathFinder.cpp +++ b/Minecraft.World/PathFinder.cpp @@ -246,6 +246,7 @@ int PathFinder::isFree(Entity *entity, int x, int y, int z, Node *size, bool avo } } + if (tile == nullptr) continue; // tu31 tutorial world fix if (tile->isPathfindable(entity->level, xx, yy, zz)) continue; if (canOpenDoors && tileId == Tile::door_wood_Id) continue; diff --git a/Minecraft.World/PathNavigation.cpp b/Minecraft.World/PathNavigation.cpp index 51d08d1e..22beaeb1 100644 --- a/Minecraft.World/PathNavigation.cpp +++ b/Minecraft.World/PathNavigation.cpp @@ -346,7 +346,9 @@ bool PathNavigation::canWalkOn(int x, int y, int z, int sx, int sy, int sz, Vec3 if (dirX * goalDirX + dirZ * goalDirZ < 0) continue; int tile = level->getTile(xx, y - 1, zz); if (tile <= 0) return false; - Material *m = Tile::tiles[tile]->material; + Tile *tileObj = Tile::tiles[tile]; + if (tileObj == nullptr) continue; // tu31 tutorial world fix + Material *m = tileObj->material; if (m == Material::water && !mob->isInWater()) return false; if (m == Material::lava) return false; } @@ -370,7 +372,9 @@ bool PathNavigation::canWalkAbove(int startX, int startY, int startZ, int sx, in if (dirX * goalDirX + dirZ * goalDirZ < 0) continue; int tile = level->getTile(xx, yy, zz); if (tile <= 0) continue; - if (!Tile::tiles[tile]->isPathfindable(level, xx, yy, zz)) return false; + Tile *tileObj = Tile::tiles[tile]; + if (tileObj == nullptr) continue; // tu31 tutorial world fix + if (!tileObj->isPathfindable(level, xx, yy, zz)) return false; } } }