diff --git a/Minecraft.Client/Common/Audio/SoundEngine.cpp b/Minecraft.Client/Common/Audio/SoundEngine.cpp index cf140c78..543b6d67 100644 --- a/Minecraft.Client/Common/Audio/SoundEngine.cpp +++ b/Minecraft.Client/Common/Audio/SoundEngine.cpp @@ -115,7 +115,6 @@ const char *SoundEngine::m_szStreamFileA[eStream_Max]= "nuance1", "nuance2", -#ifndef _XBOX "creative1", "creative2", "creative3", @@ -126,7 +125,6 @@ const char *SoundEngine::m_szStreamFileA[eStream_Max]= "menu2", "menu3", "menu4", -#endif "piano1", "piano2", diff --git a/Minecraft.Client/Common/UI/IUIScene_CreativeMenu.cpp b/Minecraft.Client/Common/UI/IUIScene_CreativeMenu.cpp index 4be3e89e..ae2635b4 100644 --- a/Minecraft.Client/Common/UI/IUIScene_CreativeMenu.cpp +++ b/Minecraft.Client/Common/UI/IUIScene_CreativeMenu.cpp @@ -192,7 +192,8 @@ void IUIScene_CreativeMenu::staticCtor() ITEM_AUX(Item::skull_Id,SkullTileEntity::TYPE_ZOMBIE) ITEM_AUX(Item::skull_Id,SkullTileEntity::TYPE_CHAR) ITEM_AUX(Item::skull_Id,SkullTileEntity::TYPE_CREEPER) - ITEM(Tile::sponge_Id) + ITEM_AUX(Tile::sponge_Id, 0) // dry sponge + ITEM_AUX(Tile::sponge_Id, 1) // wet sponge ITEM(Tile::melon_Id) ITEM(Tile::pumpkin_Id) ITEM(Tile::litPumpkin_Id) diff --git a/Minecraft.World/ArmorStand.cpp b/Minecraft.World/ArmorStand.cpp index cff11345..c9d52ade 100644 --- a/Minecraft.World/ArmorStand.cpp +++ b/Minecraft.World/ArmorStand.cpp @@ -413,7 +413,7 @@ void ArmorStand::handleEntityEvent(byte id) double px = x + (random->nextFloat() * 0.1f - 0.05f); - double py = y + (bbHeight * 0.75f) + (random->nextFloat() * 0.2f); + double py = y + (bbHeight * 0.6f) + (random->nextFloat() * 0.2f); double pz = z + (random->nextFloat() * 0.1f - 0.05f); diff --git a/Minecraft.World/FurnaceRecipes.cpp b/Minecraft.World/FurnaceRecipes.cpp index fc5bf008..3eacf9f1 100644 --- a/Minecraft.World/FurnaceRecipes.cpp +++ b/Minecraft.World/FurnaceRecipes.cpp @@ -35,6 +35,7 @@ FurnaceRecipes::FurnaceRecipes() addFurnaceRecipy(Tile::emeraldOre_Id, new ItemInstance(Item::emerald), 1); addFurnaceRecipy(Item::potato_Id, new ItemInstance(Item::potatoBaked), .35f); addFurnaceRecipy(Tile::netherRack_Id, new ItemInstance(Item::netherbrick), .1f); + addFurnaceRecipy(new ItemInstance(Tile::sponge, 1, 1), new ItemInstance(Tile::sponge, 1, 0), .15f); // special silk touch related recipes: addFurnaceRecipy(Tile::coalOre_Id, new ItemInstance(Item::coal), .1f); @@ -42,7 +43,6 @@ FurnaceRecipes::FurnaceRecipes() addFurnaceRecipy(Tile::lapisOre_Id, new ItemInstance(Item::dye_powder, 1, DyePowderItem::BLUE), .2f); addFurnaceRecipy(Tile::netherQuartz_Id, new ItemInstance(Item::netherQuartz), .2f); - } void FurnaceRecipes::addFurnaceRecipy(int itemId, ItemInstance *result, float value) @@ -52,19 +52,27 @@ void FurnaceRecipes::addFurnaceRecipy(int itemId, ItemInstance *result, float va recipeValue[result->id] = value; } -bool FurnaceRecipes::isFurnaceItem(int itemId) +void FurnaceRecipes::addFurnaceRecipy(ItemInstance* input, ItemInstance* result, float value) { - auto it = recipies.find(itemId); - return it != recipies.end(); + int key = input->id | (input->getAuxValue() << 12); + recipies[key] = result; + recipeValue[result->id] = value; } -ItemInstance *FurnaceRecipes::getResult(int itemId) +bool FurnaceRecipes::isFurnaceItem(int itemId, int data) { - auto it = recipies.find(itemId); - if(it != recipies.end()) - { - return it->second; - } + int key = itemId | (data << 12); + if (recipies.find(key) != recipies.end()) return true; + return recipies.find(itemId) != recipies.end(); +} + +ItemInstance* FurnaceRecipes::getResult(int itemId, int data) +{ + int key = itemId | (data << 12); + auto it = recipies.find(key); + if (it != recipies.end()) return it->second; + it = recipies.find(itemId); + if (it != recipies.end()) return it->second; return nullptr; } diff --git a/Minecraft.World/FurnaceRecipes.h b/Minecraft.World/FurnaceRecipes.h index 168831c0..f4dbaad7 100644 --- a/Minecraft.World/FurnaceRecipes.h +++ b/Minecraft.World/FurnaceRecipes.h @@ -22,8 +22,9 @@ public: public: void addFurnaceRecipy(int itemId, ItemInstance *result, float value); - bool isFurnaceItem(int itemId); - ItemInstance *getResult(int itemId); + void addFurnaceRecipy(ItemInstance* input, ItemInstance* result, float value); + bool isFurnaceItem(int itemId, int data); + ItemInstance* getResult(int itemId, int data = 0); unordered_map *getRecipies(); float getRecipeValue(int itemId); diff --git a/Minecraft.World/FurnaceTileEntity.cpp b/Minecraft.World/FurnaceTileEntity.cpp index 901235c0..b4f394f2 100644 --- a/Minecraft.World/FurnaceTileEntity.cpp +++ b/Minecraft.World/FurnaceTileEntity.cpp @@ -250,7 +250,7 @@ void FurnaceTileEntity::tick() bool FurnaceTileEntity::canBurn() { if (items[SLOT_INPUT] == nullptr) return false; - const ItemInstance *burnResult = FurnaceRecipes::getInstance()->getResult(items[SLOT_INPUT]->getItem()->id); + const ItemInstance* burnResult = FurnaceRecipes::getInstance()->getResult(items[SLOT_INPUT]->getItem()->id, items[SLOT_INPUT]->getAuxValue()); if (burnResult == nullptr) return false; if (items[SLOT_RESULT] == nullptr) return true; if (!items[SLOT_RESULT]->sameItem_not_shared(burnResult)) return false; @@ -264,7 +264,7 @@ void FurnaceTileEntity::burn() { if (!canBurn()) return; - const ItemInstance *result = FurnaceRecipes::getInstance()->getResult(items[SLOT_INPUT]->getItem()->id); + const ItemInstance* result = FurnaceRecipes::getInstance()->getResult(items[SLOT_INPUT]->getItem()->id, items[SLOT_INPUT]->getAuxValue()); if (items[SLOT_RESULT] == nullptr) items[SLOT_RESULT] = result->copy(); else if (items[SLOT_RESULT]->id == result->id) items[SLOT_RESULT]->count++; diff --git a/Minecraft.World/Sponge.cpp b/Minecraft.World/Sponge.cpp index 960589e6..d50f4a6e 100644 --- a/Minecraft.World/Sponge.cpp +++ b/Minecraft.World/Sponge.cpp @@ -1,11 +1,131 @@ #include "stdafx.h" +#include "net.minecraft.h" #include "net.minecraft.world.level.h" +#include "net.minecraft.world.h" #include "Sponge.h" -const int RANGE = 2; - +const unsigned int Sponge::SPONGE_NAMES[SPONGE_NAMES_LENGTH] = { IDS_TILE_SPONGE, IDS_TILE_SPONGE }; Sponge::Sponge(int id) : Tile(id, Material::sponge) { + wet = false; + icon = nullptr; + icon_wet = nullptr; +} + +void Sponge::onPlace(Level *level, int x, int y, int z) +{ + wet = level->getData(x, y, z) == 1; + tryAbsorb(level, x, y, z); +} + +void Sponge::neighborChanged(Level* level, int x, int y, int z, int type) +{ + tryAbsorb(level, x, y, z); +} + +void Sponge::tryAbsorb(Level* level, int x, int y, int z) { + if (!wet && absorb(level, x, y, z)) { + wet = true; + level->setTileAndData(x, y, z, Tile::sponge_Id, 1, UPDATE_CLIENTS); + } +} + +bool Sponge::absorb(Level* level, int x, int y, int z) { + std::queue> queue; + std::vector> absorbed; + queue.push({ x, y, z, 0 }); + int count = 0; + int dx[] = { 1,-1,0,0,0,0 }; + int dy[] = { 0,0,1,-1,0,0 }; + int dz[] = { 0,0,0,0,1,-1 }; + while (!queue.empty()) + { + auto [bx, by, bz, depth] = queue.front(); + queue.pop(); + for (int i = 0; i < 6; i++) + { + int nx = bx + dx[i]; + int ny = by + dy[i]; + int nz = bz + dz[i]; + if (level->getMaterial(nx, ny, nz) == Material::water) + { + level->removeTile(nx, ny, nz); + absorbed.push_back({ nx, ny, nz }); + ++count; + if (depth < 6) + queue.push({ nx, ny, nz, depth + 1 }); + } + } + if (count > 64) + break; + } + + for (auto [ax, ay, az] : absorbed) + { + level->checkLight(ax, ay, az); + } + + return count > 0; +} + +void Sponge::animateTick(Level* level, int x, int y, int z, Random* random) +{ + if (wet) { + int facings[] = { Facing::UP, Facing::DOWN, Facing::WEST, Facing::EAST }; + int facing = facings[rand() % 4]; + + if (facing != Facing::UP && !level->isTopSolidBlocking(x + Facing::STEP_X[facing], y + Facing::STEP_Y[facing], z + Facing::STEP_Z[facing])) + { + double d0 = (double)x; + double d1 = (double)y; + double d2 = (double)z; + + if (facing == Facing::DOWN) + { + d1 = d1 - 0.05; + d0 += (double)rand() / RAND_MAX; + d2 += (double)rand() / RAND_MAX; + } + else + { + d1 = d1 + ((double)rand() / RAND_MAX) * 0.8; + + if (facing == Facing::EAST) + { + d2 += (double)rand() / RAND_MAX; + ++d0; + } + else if (facing == Facing::WEST) + { + d2 += (double)rand() / RAND_MAX; + d0 += 0.05; + } + else + { + d0 += (double)rand() / RAND_MAX; + d2 += 0.05; + } + } + + level->addParticle(eParticleType_dripWater, d0, d1, d2, 0.0, 0.0, 0.0); + } + } +} + +Icon* Sponge::getTexture(int face, int data) +{ + return data == 1 ? icon_wet : icon; +} + +void Sponge::registerIcons(IconRegister* iconRegister) +{ + icon_wet = iconRegister->registerIcon(L"sponge_wet"); + icon = iconRegister->registerIcon(L"sponge"); +} + +int Sponge::getSpawnResourcesAuxValue(int data) +{ + return data; } \ No newline at end of file diff --git a/Minecraft.World/Sponge.h b/Minecraft.World/Sponge.h index a488ce62..b8641db5 100644 --- a/Minecraft.World/Sponge.h +++ b/Minecraft.World/Sponge.h @@ -6,8 +6,24 @@ class Sponge : public Tile { friend class Tile; public: - static const int RANGE = 2; + static const int SPONGE_NAMES_LENGTH = 2; + + static const unsigned int SPONGE_NAMES[SPONGE_NAMES_LENGTH]; + static const wstring TEXTURE_NAMES[]; + + bool wet; +private: + Icon* icon_wet; + Icon* icon; protected: Sponge(int id); + void onPlace(Level* level, int x, int y, int z); + void neighborChanged(Level* level, int x, int y, int z, int type); + void tryAbsorb(Level* level, int x, int y, int z); + bool absorb(Level* level, int x, int y, int z); + void animateTick(Level* level, int x, int y, int z, Random* random); + void registerIcons(IconRegister* iconRegister); + Icon* getTexture(int face, int data); + int getSpawnResourcesAuxValue(int data); }; \ No newline at end of file diff --git a/Minecraft.World/Tile.cpp b/Minecraft.World/Tile.cpp index 6b4d2d50..cac85e14 100644 --- a/Minecraft.World/Tile.cpp +++ b/Minecraft.World/Tile.cpp @@ -307,7 +307,7 @@ void Tile::staticCtor() Tile::treeTrunk = (new TreeTile(17))->setDestroyTime(2.0f) ->setSoundType(Tile::SOUND_WOOD)->setIconName(L"log")->setDescriptionId(IDS_TILE_LOG)->sendTileData()->setUseDescriptionId(IDS_DESC_LOG); // 4J - for leaves, have specified that only the data bits that encode the type of leaf are important to be sent Tile::leaves = static_cast((new LeafTile(18))->setDestroyTime(0.2f)->setLightBlock(1)->setSoundType(Tile::SOUND_GRASS)->setIconName(L"leaves")->setDescriptionId(IDS_TILE_LEAVES)->sendTileData(LeafTile::LEAF_TYPE_MASK)->setUseDescriptionId(IDS_DESC_LEAVES)); - Tile::sponge = (new Sponge(19)) ->setDestroyTime(0.6f)->setSoundType(Tile::SOUND_GRASS)->setIconName(L"sponge")->setDescriptionId(IDS_TILE_SPONGE)->setUseDescriptionId(IDS_DESC_SPONGE); + Tile::sponge = (new Sponge(19)) ->setDestroyTime(0.6f)->setSoundType(Tile::SOUND_GRASS)->setIconName(L"sponge")->setDescriptionId(IDS_TILE_SPONGE)->setUseDescriptionId(IDS_DESC_SPONGE)->sendTileData(); Tile::glass = (new GlassTile(20, Material::glass, false)) ->setDestroyTime(0.3f)->setSoundType(Tile::SOUND_GLASS)->setIconName(L"glass")->setDescriptionId(IDS_TILE_GLASS)->setUseDescriptionId(IDS_DESC_GLASS); Tile::lapisOre = (new OreTile(21)) ->setDestroyTime(3.0f)->setExplodeable(5)->setSoundType(Tile::SOUND_STONE)->setIconName(L"lapis_ore")->setDescriptionId(IDS_TILE_ORE_LAPIS)->setUseDescriptionId(IDS_DESC_ORE_LAPIS); @@ -531,6 +531,7 @@ void Tile::staticCtor() Item::items[sand_Id] = (new MultiTextureTileItem(Tile::sand_Id - 256, sand, (int*)SandTile::SAND_NAMES, SandTile::SAND_NAMES_LENGTH))->setIconName(L"sand")->setDescriptionId(IDS_TILE_SAND)->setUseDescriptionId(IDS_DESC_SAND); Item::items[red_sandstone_Id] = (new MultiTextureTileItem(Tile::red_sandstone_Id - 256, red_sandstone, (int*)RedSandStoneTile::SANDSTONE_NAMES, RedSandStoneTile::SANDSTONE_BLOCK_NAMES))->setIconName(L"red_sandstone")->setDescriptionId(IDS_TILE_SANDSTONE)->setUseDescriptionId(IDS_DESC_SANDSTONE); Item::items[tree2Trunk_Id] = (new MultiTextureTileItem(Tile::tree2Trunk_Id - 256, tree2Trunk, (int*)TreeTile2::TREE_NAMES, TreeTile2::TREE_NAMES_LENGTH))->setIconName(L"log")->setDescriptionId(IDS_TILE_LOG)->setUseDescriptionId(IDS_DESC_LOG); + Item::items[sponge_Id] = (new MultiTextureTileItem(Tile::sponge_Id - 256, sponge, (int*)Sponge::SPONGE_NAMES, Sponge::SPONGE_NAMES_LENGTH))->setIconName(L"sponge")->setDescriptionId(IDS_TILE_SPONGE)->setUseDescriptionId(IDS_DESC_SPONGE); for (int i = 0; i < 256; i++) { @@ -1007,6 +1008,7 @@ void Tile::popExperience(Level *level, int x, int y, int z, int amount) } } + int Tile::getSpawnResourcesAuxValue(int data) { return 0;