fix: tutorial

items actually appear now yay
item frames though...
This commit is contained in:
Fireblade 2026-05-03 01:43:43 -04:00
parent 229d22ab7b
commit a7cad496e3
7 changed files with 759 additions and 7 deletions

View file

@ -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
}

View file

@ -147,7 +147,21 @@ void ChestTileEntity::load(CompoundTag *base)
shared_ptr<ItemInstance> 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;
}

View file

@ -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;

View file

@ -14,6 +14,197 @@
#include "ItemInstance.h"
#include "HtmlString.h"
#include "../Minecraft.Client/Common/Consoles_App.h"
#include <cwctype>
#include <unordered_map>
#include <fstream>
#include <string>
#include <filesystem>
#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<wchar_t>(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<wchar_t>(towlower(c)));
}
else
{
out.push_back(c);
}
}
return NormalizeItemNameId(out);
}
void AddNameAlias(unordered_map<wstring, int> &nameToId, const wchar_t *name, int id)
{
nameToId[NormalizeItemNameId(name)] = id;
}
bool TryLoadExternalItemIdAliases(unordered_map<wstring, int> &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<string> 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<int>();
}
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<wstring, int> 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<int>(parsedValue);
}
}
catch (...)
{
}
return 0;
}
int ByteSwapShortToInt(short value)
{
unsigned short raw = static_cast<unsigned short>(value);
unsigned short swapped = static_cast<unsigned short>((raw >> 8) | (raw << 8));
return static_cast<int>(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)

View file

@ -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;

View file

@ -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;

View file

@ -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;
}
}
}