diff --git a/Minecraft.World/Items/ArmorItem.cpp b/Minecraft.World/Items/ArmorItem.cpp index 5713d16fd..3feb87e07 100644 --- a/Minecraft.World/Items/ArmorItem.cpp +++ b/Minecraft.World/Items/ArmorItem.cpp @@ -1,7 +1,11 @@ #include "../Platform/stdafx.h" #include "../../Minecraft.Client/Minecraft.h" #include "../Headers/net.minecraft.world.h" +#include "../Headers/net.minecraft.world.level.tile.h" #include "../Headers/net.minecraft.world.entity.player.h" +#include "../Headers/net.minecraft.world.entity.h" +#include "../Headers/net.minecraft.world.phys.h" +#include "../Headers/net.minecraft.world.level.h" #include "../Headers/com.mojang.nbt.h" #include "ArmorItem.h" @@ -15,6 +19,42 @@ const std::wstring ArmorItem::TEXTURE_EMPTY_SLOTS[] = { L"slot_empty_helmet", L"slot_empty_chestplate", L"slot_empty_leggings", L"slot_empty_boots"}; +std::shared_ptr ArmorItem::ArmorDispenseItemBehavior::execute( + BlockSource* source, std::shared_ptr dispensed, + eOUTCOME& outcome) { + FacingEnum* facing = DispenserTile::getFacing(source->getData()); + int x = source->getBlockX() + facing->getStepX(); + int y = source->getBlockY() + facing->getStepY(); + int z = source->getBlockZ() + facing->getStepZ(); + AABB* bb = AABB::newTemp(x, y, z, x + 1, y + 1, z + 1); + EntitySelector* selector = new MobCanWearArmourEntitySelector(dispensed); + std::vector >* entities = + source->getWorld()->getEntitiesOfClass(typeid(LivingEntity), bb, + selector); + delete selector; + + if (entities->size() > 0) { + std::shared_ptr target = + std::dynamic_pointer_cast(entities->at(0)); + int offset = target->instanceof(eTYPE_PLAYER) ? 1 : 0; + int slot = Mob::getEquipmentSlotForItem(dispensed); + std::shared_ptr equip = dispensed->copy(); + equip->count = 1; + target->setEquippedSlot(slot - offset, equip); + if (target->instanceof(eTYPE_MOB)) + std::dynamic_pointer_cast(target)->setDropChance(slot, 2); + dispensed->count--; + + outcome = ACTIVATED_ITEM; + + delete entities; + return dispensed; + } else { + delete entities; + return DefaultDispenseItemBehavior::execute(source, dispensed, outcome); + } +} + typedef ArmorItem::ArmorMaterial _ArmorMaterial; const int _ArmorMaterial::clothArray[] = {1, 3, 2, 1}; @@ -76,6 +116,7 @@ ArmorItem::ArmorItem(int id, const ArmorMaterial* armorType, int icon, int slot) defense(armorType->getDefenseForSlot(slot)) { setMaxDamage(armorType->getHealthForSlot(slot)); maxStackSize = 1; + DispenserTile::REGISTRY.add(this, new ArmorDispenseItemBehavior()); } int ArmorItem::getColor(std::shared_ptr item, int spriteLayer) { @@ -88,7 +129,6 @@ int ArmorItem::getColor(std::shared_ptr item, int spriteLayer) { return color; } -//@Override bool ArmorItem::hasMultipleSpriteLayers() { return armorType == ArmorMaterial::CLOTH; } @@ -129,7 +169,6 @@ int ArmorItem::getColor(std::shared_ptr item) { } } -//@Override Icon* ArmorItem::getLayerIcon(int auxValue, int spriteLayer) { if (spriteLayer == 1) { return overlayIcon; @@ -175,7 +214,6 @@ bool ArmorItem::isValidRepairItem(std::shared_ptr source, return Item::isValidRepairItem(source, repairItem); } -//@Override void ArmorItem::registerIcons(IconRegister* iconRegister) { Item::registerIcons(iconRegister); diff --git a/Minecraft.World/Items/ArmorItem.h b/Minecraft.World/Items/ArmorItem.h index 3bbbb453e..f63da30c5 100644 --- a/Minecraft.World/Items/ArmorItem.h +++ b/Minecraft.World/Items/ArmorItem.h @@ -1,6 +1,7 @@ #pragma once #include "Item.h" +#include "../Core/DefaultDispenseItemBehavior.h" class ArmorItem : public Item { public: @@ -18,6 +19,14 @@ private: public: static const std::wstring TEXTURE_EMPTY_SLOTS[]; +private: + class ArmorDispenseItemBehavior : public DefaultDispenseItemBehavior { + protected: + virtual std::shared_ptr execute( + BlockSource* source, std::shared_ptr dispensed, + eOUTCOME& outcome); + }; + public: class ArmorMaterial { public: @@ -65,28 +74,20 @@ private: public: ArmorItem(int id, const ArmorMaterial* armorType, int icon, int slot); - //@Override - int getColor(std::shared_ptr item, int spriteLayer); - - //@Override - bool hasMultipleSpriteLayers(); - + virtual int getColor(std::shared_ptr item, int spriteLayer); + virtual bool hasMultipleSpriteLayers(); virtual int getEnchantmentValue(); + virtual const ArmorMaterial* getMaterial(); + virtual bool hasCustomColor(std::shared_ptr item); + virtual int getColor(std::shared_ptr item); - const ArmorMaterial* getMaterial(); - bool hasCustomColor(std::shared_ptr item); - int getColor(std::shared_ptr item); + virtual Icon* getLayerIcon(int auxValue, int spriteLayer); + virtual void clearColor(std::shared_ptr item); + virtual void setColor(std::shared_ptr item, int color); - //@Override - Icon* getLayerIcon(int auxValue, int spriteLayer); - void clearColor(std::shared_ptr item); - void setColor(std::shared_ptr item, int color); - - bool isValidRepairItem(std::shared_ptr source, - std::shared_ptr repairItem); - - //@Override - void registerIcons(IconRegister* iconRegister); + virtual bool isValidRepairItem(std::shared_ptr source, + std::shared_ptr repairItem); + virtual void registerIcons(IconRegister* iconRegister); static Icon* getEmptyIcon(int slot); }; \ No newline at end of file diff --git a/Minecraft.World/Items/BedItem.cpp b/Minecraft.World/Items/BedItem.cpp index bf587e2b9..cac4f35dd 100644 --- a/Minecraft.World/Items/BedItem.cpp +++ b/Minecraft.World/Items/BedItem.cpp @@ -14,6 +14,8 @@ bool BedItem::useOn(std::shared_ptr itemInstance, std::shared_ptr player, Level* level, int x, int y, int z, int face, float clickX, float clickY, float clickZ, bool bTestUseOnOnly) { + if (level->isClientSide) return true; + if (face != Facing::UP) { return false; } @@ -32,7 +34,8 @@ bool BedItem::useOn(std::shared_ptr itemInstance, if (dir == Direction::NORTH) zra = -1; if (dir == Direction::EAST) xra = 1; - if (!player->mayBuild(x, y, z) || !player->mayBuild(x + xra, y, z + zra)) + if (!player->mayUseItemAt(x, y, z, face, itemInstance) || + !player->mayUseItemAt(x + xra, y, z + zra, face, itemInstance)) return false; if (level->isEmptyTile(x, y, z) && @@ -41,7 +44,7 @@ bool BedItem::useOn(std::shared_ptr itemInstance, level->isTopSolidBlocking(x + xra, y - 1, z + zra)) { // 4J-PB - Adding a test only version to allow tooltips to be displayed if (!bTestUseOnOnly) { - level->setTileAndData(x, y, z, tile->id, dir); + level->setTileAndData(x, y, z, tile->id, dir, Tile::UPDATE_ALL); // double-check that the bed was successfully placed if (level->getTile(x, y, z) == tile->id) { // 4J-JEV: Hook for durango 'BlockPlaced' event. @@ -51,7 +54,8 @@ bool BedItem::useOn(std::shared_ptr itemInstance, tile->id, itemInstance->getAuxValue(), 1)); level->setTileAndData(x + xra, y, z + zra, tile->id, - dir + BedTile::HEAD_PIECE_DATA); + dir + BedTile::HEAD_PIECE_DATA, + Tile::UPDATE_ALL); } itemInstance->count--; diff --git a/Minecraft.World/Items/BoatItem.cpp b/Minecraft.World/Items/BoatItem.cpp index d9974e8b0..90f9b7f32 100644 --- a/Minecraft.World/Items/BoatItem.cpp +++ b/Minecraft.World/Items/BoatItem.cpp @@ -7,9 +7,10 @@ #include "ItemInstance.h" #include "BoatItem.h" -BoatItem::BoatItem(int id) : Item(id) { this->maxStackSize = 1; } +BoatItem::BoatItem(int id) : Item(id) { maxStackSize = 1; } -bool BoatItem::TestUse(Level* level, std::shared_ptr player) { +bool BoatItem::TestUse(std::shared_ptr itemInstance, Level* level, + std::shared_ptr player) { // 4J-PB - added for tooltips to test use // 4J TODO really we should have the crosshair hitresult telling us if it // hit water, and at what distance, so we don't need to do this again if the @@ -103,20 +104,28 @@ std::shared_ptr BoatItem::use( int yt = hr->y; int zt = hr->z; - if (!level->isClientSide) { - if (level->getTile(xt, yt, zt) == Tile::topSnow_Id) yt--; - if (level->countInstanceOf(eTYPE_BOAT, true) < - Level::MAX_XBOX_BOATS) // 4J - added limit - { - level->addEntity(std::shared_ptr( - new Boat(level, xt + 0.5f, yt + 1.0f, zt + 0.5f))); - if (!player->abilities.instabuild) { - itemInstance->count--; - } - } else { - // display a message to say max boats has been hit - player->displayClientMessage(IDS_MAX_BOATS); + if (level->getTile(xt, yt, zt) == Tile::topSnow_Id) yt--; + if (level->countInstanceOf(eTYPE_BOAT, true) < + Level::MAX_XBOX_BOATS) // 4J - added limit + { + std::shared_ptr boat = std::shared_ptr( + new Boat(level, xt + 0.5f, yt + 1.0f, zt + 0.5f)); + boat->yRot = + ((Mth::floor(player->yRot * 4.0F / 360.0F + 0.5) & 0x3) - 1) * + 90; + if (!level->getCubes(boat, boat->bb->grow(-.1, -.1, -.1)) + ->empty()) { + return itemInstance; } + if (!level->isClientSide) { + level->addEntity(boat); + } + if (!player->abilities.instabuild) { + itemInstance->count--; + } + } else { + // display a message to say max boats has been hit + player->displayClientMessage(IDS_MAX_BOATS); } } delete hr; diff --git a/Minecraft.World/Items/BoatItem.h b/Minecraft.World/Items/BoatItem.h index 060051b86..0e41c33b3 100644 --- a/Minecraft.World/Items/BoatItem.h +++ b/Minecraft.World/Items/BoatItem.h @@ -9,7 +9,8 @@ class BoatItem : public Item { public: BoatItem(int id); - virtual bool TestUse(Level* level, std::shared_ptr player); + virtual bool TestUse(std::shared_ptr itemInstance, + Level* level, std::shared_ptr player); virtual std::shared_ptr use( std::shared_ptr itemInstance, Level* level, std::shared_ptr player); diff --git a/Minecraft.World/Items/BottleItem.cpp b/Minecraft.World/Items/BottleItem.cpp index 429933b50..ee6d12132 100644 --- a/Minecraft.World/Items/BottleItem.cpp +++ b/Minecraft.World/Items/BottleItem.cpp @@ -25,7 +25,7 @@ std::shared_ptr BottleItem::use( if (!level->mayInteract(player, xt, yt, zt, 0)) { return itemInstance; } - if (!player->mayBuild(xt, yt, zt)) { + if (!player->mayUseItemAt(xt, yt, zt, hr->f, itemInstance)) { return itemInstance; } if (level->getMaterial(xt, yt, zt) == Material::water) { @@ -49,7 +49,8 @@ std::shared_ptr BottleItem::use( } // 4J-PB - added to allow tooltips -bool BottleItem::TestUse(Level* level, std::shared_ptr player) { +bool BottleItem::TestUse(std::shared_ptr itemInstance, + Level* level, std::shared_ptr player) { HitResult* hr = getPlayerPOVHitResult(level, player, true); if (hr == NULL) return false; @@ -62,7 +63,7 @@ bool BottleItem::TestUse(Level* level, std::shared_ptr player) { if (!level->mayInteract(player, xt, yt, zt, 0)) { return false; } - if (!player->mayBuild(xt, yt, zt)) { + if (!player->mayUseItemAt(xt, yt, zt, hr->f, itemInstance)) { return false; } if (level->getMaterial(xt, yt, zt) == Material::water) { diff --git a/Minecraft.World/Items/BottleItem.h b/Minecraft.World/Items/BottleItem.h index edaefb797..f268a7a7b 100644 --- a/Minecraft.World/Items/BottleItem.h +++ b/Minecraft.World/Items/BottleItem.h @@ -14,7 +14,8 @@ public: virtual std::shared_ptr use( std::shared_ptr itemInstance, Level* level, std::shared_ptr player); - virtual bool TestUse(Level* level, std::shared_ptr player); + virtual bool TestUse(std::shared_ptr itemInstance, + Level* level, std::shared_ptr player); //@Override void registerIcons(IconRegister* iconRegister); diff --git a/Minecraft.World/Items/BowItem.cpp b/Minecraft.World/Items/BowItem.cpp index b126c3f3a..20ba0d448 100644 --- a/Minecraft.World/Items/BowItem.cpp +++ b/Minecraft.World/Items/BowItem.cpp @@ -50,10 +50,11 @@ void BowItem::releaseUsing(std::shared_ptr itemInstance, itemInstance) > 0) { arrow->setOnFire(100); } - itemInstance->hurt(1, player); + itemInstance->hurtAndBreak(1, player); - level->playSound(player, eSoundType_RANDOM_BOW, 1.0f, - 1 / (random->nextFloat() * 0.4f + 1.2f) + pow * 0.5f); + level->playEntitySound( + player, eSoundType_RANDOM_BOW, 1.0f, + 1 / (random->nextFloat() * 0.4f + 1.2f) + pow * 0.5f); if (infiniteArrows) { arrow->pickup = Arrow::PICKUP_CREATIVE_ONLY; diff --git a/Minecraft.World/Items/BucketItem.cpp b/Minecraft.World/Items/BucketItem.cpp index 4cd80d2db..3825125a9 100644 --- a/Minecraft.World/Items/BucketItem.cpp +++ b/Minecraft.World/Items/BucketItem.cpp @@ -15,7 +15,7 @@ #include "../../Minecraft.Client/Player/LocalPlayer.h" #include "../../Minecraft.Client/Player/ServerPlayer.h" #include "../../Minecraft.Client/Network/PlayerConnection.h" -#include "../Network/Packets/ChatPacket.h" +#include "../Minecraft.World/ChatPacket.h" #include "../Util/SoundTypes.h" BucketItem::BucketItem(int id, int content) : Item(id) { @@ -23,11 +23,8 @@ BucketItem::BucketItem(int id, int content) : Item(id) { this->content = content; } -bool BucketItem::TestUse(Level* level, std::shared_ptr player) { - // double x = player->xo + (player->x - player->xo); - // double y = player->yo + (player->y - player->yo) + 1.62 - - // player->heightOffset; double z = player->zo + (player->z - player->zo); - +bool BucketItem::TestUse(std::shared_ptr itemInstance, + Level* level, std::shared_ptr player) { bool pickLiquid = content == 0; HitResult* hr = getPlayerPOVHitResult(level, player, pickLiquid); if (hr == NULL) return false; @@ -43,7 +40,8 @@ bool BucketItem::TestUse(Level* level, std::shared_ptr player) { } if (content == 0) { - if (!player->mayBuild(xt, yt, zt)) return false; + if (!player->mayUseItemAt(xt, yt, zt, hr->f, itemInstance)) + return false; if (level->getMaterial(xt, yt, zt) == Material::water && level->getData(xt, yt, zt) == 0) { delete hr; @@ -65,7 +63,8 @@ bool BucketItem::TestUse(Level* level, std::shared_ptr player) { if (hr->f == 4) xt--; if (hr->f == 5) xt++; - if (!player->mayBuild(xt, yt, zt)) return false; + if (!player->mayUseItemAt(xt, yt, zt, hr->f, itemInstance)) + return false; if (level->isEmptyTile(xt, yt, zt) || !level->getMaterial(xt, yt, zt)->isSolid()) { @@ -121,10 +120,11 @@ std::shared_ptr BucketItem::use( } if (content == 0) { - if (!player->mayBuild(xt, yt, zt)) return itemInstance; + if (!player->mayUseItemAt(xt, yt, zt, hr->f, itemInstance)) + return itemInstance; if (level->getMaterial(xt, yt, zt) == Material::water && level->getData(xt, yt, zt) == 0) { - level->setTile(xt, yt, zt, 0); + level->removeTile(xt, yt, zt); delete hr; if (player->abilities.instabuild) { return itemInstance; @@ -148,7 +148,7 @@ std::shared_ptr BucketItem::use( player->awardStat(GenericStats::netherLavaCollected(), GenericStats::param_noArgs()); - level->setTile(xt, yt, zt, 0); + level->removeTile(xt, yt, zt); delete hr; if (player->abilities.instabuild) { return itemInstance; @@ -177,45 +177,30 @@ std::shared_ptr BucketItem::use( if (hr->f == 4) xt--; if (hr->f == 5) xt++; - if (!player->mayBuild(xt, yt, zt)) return itemInstance; + if (!player->mayUseItemAt(xt, yt, zt, hr->f, itemInstance)) + return itemInstance; - if (emptyBucket(level, x, y, z, xt, yt, zt) && + if (emptyBucket(level, xt, yt, zt) && !player->abilities.instabuild) { return std::shared_ptr( new ItemInstance(Item::bucket_empty)); } } - } else { - if (content == 0) { - if (hr->entity->GetType() == eTYPE_COW) { - delete hr; - if (--itemInstance->count <= 0) { - return std::shared_ptr( - new ItemInstance(Item::milk)); - } else { - if (!player->inventory->add(std::shared_ptr( - new ItemInstance(Item::milk)))) { - player->drop(std::shared_ptr( - new ItemInstance(Item::milk_Id, 1, 0))); - } - return itemInstance; - } - } - } } delete hr; return itemInstance; } -bool BucketItem::emptyBucket(Level* level, double x, double y, double z, int xt, - int yt, int zt) { +bool BucketItem::emptyBucket(Level* level, int xt, int yt, int zt) { if (content <= 0) return false; - if (level->isEmptyTile(xt, yt, zt) || - !level->getMaterial(xt, yt, zt)->isSolid()) { + Material* material = level->getMaterial(xt, yt, zt); + bool nonSolid = !material->isSolid(); + + if (level->isEmptyTile(xt, yt, zt) || nonSolid) { if (level->dimension->ultraWarm && content == Tile::water_Id) { level->playSound( - x + 0.5f, y + 0.5f, z + 0.5f, eSoundType_RANDOM_FIZZ, 0.5f, + xt + 0.5f, yt + 0.5f, zt + 0.5f, eSoundType_RANDOM_FIZZ, 0.5f, 2.6f + (level->random->nextFloat() - level->random->nextFloat()) * 0.8f); @@ -226,7 +211,10 @@ bool BucketItem::emptyBucket(Level* level, double x, double y, double z, int xt, zt + Math::random(), 0, 0, 0); } } else { - level->setTileAndData(xt, yt, zt, content, 0); + if (!level->isClientSide && nonSolid && !material->isLiquid()) { + level->destroyTile(xt, yt, zt, true); + } + level->setTileAndData(xt, yt, zt, content, 0, Tile::UPDATE_ALL); } return true; diff --git a/Minecraft.World/Items/BucketItem.h b/Minecraft.World/Items/BucketItem.h index 86ee30ed2..871b75037 100644 --- a/Minecraft.World/Items/BucketItem.h +++ b/Minecraft.World/Items/BucketItem.h @@ -12,22 +12,11 @@ private: public: BucketItem(int id, int content); - virtual bool TestUse(Level* level, std::shared_ptr player); + virtual bool TestUse(std::shared_ptr itemInstance, + Level* level, std::shared_ptr player); virtual std::shared_ptr use( std::shared_ptr itemInstance, Level* level, std::shared_ptr player); - // TU9 - bool emptyBucket(Level* level, double x, double y, double z, int xt, int yt, - int zt); - - /* - * public boolean useOn(ItemInstance instance, Player player, Level level, - * int x, int y, int z, int face) { if (content == 0) { } else { if (face == - * 0) y--; if (face == 1) y++; if (face == 2) z--; if (face == 3) z++; if - * (face == 4) x--; if (face == 5) x++; int targetType = level.getTile(x, y, - * z); if (targetType == 0) { level.setTile(x, y, z, content); } - * player->inventory.items[player->inventory.selected] = new - * ItemInstance(Item.bucket_empty); } return true; } - */ + bool emptyBucket(Level* level, int xt, int yt, int zt); }; \ No newline at end of file diff --git a/Minecraft.World/Items/CarrotOnAStickItem.cpp b/Minecraft.World/Items/CarrotOnAStickItem.cpp index 8aef55b32..96b6a9b20 100644 --- a/Minecraft.World/Items/CarrotOnAStickItem.cpp +++ b/Minecraft.World/Items/CarrotOnAStickItem.cpp @@ -25,7 +25,7 @@ std::shared_ptr CarrotOnAStickItem::use( itemInstance->getMaxDamage() - itemInstance->getAuxValue() >= 7) { pig->getControlGoal()->boost(); - itemInstance->hurt(7, player); + itemInstance->hurtAndBreak(7, player); if (itemInstance->count == 0) { std::shared_ptr replacement = diff --git a/Minecraft.World/Items/CoalItem.cpp b/Minecraft.World/Items/CoalItem.cpp index 3318e61dc..348a24e6e 100644 --- a/Minecraft.World/Items/CoalItem.cpp +++ b/Minecraft.World/Items/CoalItem.cpp @@ -1,9 +1,8 @@ - - #include "../Platform/stdafx.h" #include "../Headers/net.minecraft.world.item.h" #include "../Headers/net.minecraft.world.entity.item.h" #include "../Headers/net.minecraft.world.entity.player.h" +#include "../Headers/net.minecraft.world.h" #include "CoalItem.h" CoalItem::CoalItem(int id) : Item(id) { @@ -18,3 +17,16 @@ unsigned int CoalItem::getDescriptionId( } return IDS_ITEM_COAL; } + +Icon* CoalItem::getIcon(int auxValue) { + if (auxValue == CHAR_COAL) { + return charcoalIcon; + } + return Item::getIcon(auxValue); +} + +void CoalItem::registerIcons(IconRegister* iconRegister) { + Item::registerIcons(iconRegister); + + charcoalIcon = iconRegister->registerIcon(L"charcoal"); +} \ No newline at end of file diff --git a/Minecraft.World/Items/CoalItem.h b/Minecraft.World/Items/CoalItem.h index a21f5663a..fdd15ee61 100644 --- a/Minecraft.World/Items/CoalItem.h +++ b/Minecraft.World/Items/CoalItem.h @@ -5,6 +5,9 @@ class ItemInstance; class CoalItem : public Item { +private: + Icon* charcoalIcon; + public: static const int STONE_COAL = 0; static const int CHAR_COAL = 1; @@ -13,4 +16,7 @@ public: virtual unsigned int getDescriptionId( std::shared_ptr instance); + + Icon* getIcon(int auxValue); + void registerIcons(IconRegister* iconRegister); }; \ No newline at end of file diff --git a/Minecraft.World/Items/DiggerItem.cpp b/Minecraft.World/Items/DiggerItem.cpp index a54e76bd1..2756b79d8 100644 --- a/Minecraft.World/Items/DiggerItem.cpp +++ b/Minecraft.World/Items/DiggerItem.cpp @@ -1,10 +1,12 @@ #include "../Platform/stdafx.h" #include "../Headers/net.minecraft.world.entity.h" +#include "../Headers/net.minecraft.world.entity.ai.attributes.h" +#include "../Headers/net.minecraft.world.entity.monster.h" #include "../Headers/net.minecraft.world.item.h" #include "../Headers/net.minecraft.world.level.tile.h" #include "DiggerItem.h" -DiggerItem::DiggerItem(int id, int attackDamage, const Tier* tier, +DiggerItem::DiggerItem(int id, float attackDamage, const Tier* tier, TileArray* tiles) : Item(id), tier(tier) { // this->tier = tier; @@ -23,25 +25,21 @@ float DiggerItem::getDestroySpeed(std::shared_ptr itemInstance, } bool DiggerItem::hurtEnemy(std::shared_ptr itemInstance, - std::shared_ptr mob, - std::shared_ptr attacker) { - itemInstance->hurt(2, attacker); + std::shared_ptr mob, + std::shared_ptr attacker) { + itemInstance->hurtAndBreak(2, attacker); return true; } bool DiggerItem::mineBlock(std::shared_ptr itemInstance, Level* level, int tile, int x, int y, int z, - std::shared_ptr owner) { + std::shared_ptr owner) { // Don't damage tools if the tile can be destroyed in one hit. if (Tile::tiles[tile]->getDestroySpeed(level, x, y, z) != 0.0) - itemInstance->hurt(1, owner); + itemInstance->hurtAndBreak(1, owner); return true; } -int DiggerItem::getAttackDamage(std::shared_ptr entity) { - return attackDamage; -} - bool DiggerItem::isHandEquipped() { return true; } int DiggerItem::getEnchantmentValue() { return tier->getEnchantmentValue(); } @@ -54,4 +52,14 @@ bool DiggerItem::isValidRepairItem(std::shared_ptr source, return true; } return Item::isValidRepairItem(source, repairItem); +} + +attrAttrModMap* DiggerItem::getDefaultAttributeModifiers() { + attrAttrModMap* result = Item::getDefaultAttributeModifiers(); + + (*result)[SharedMonsterAttributes::ATTACK_DAMAGE->getId()] = + new AttributeModifier(eModifierId_ITEM_BASEDAMAGE, attackDamage, + AttributeModifier::OPERATION_ADDITION); + + return result; } \ No newline at end of file diff --git a/Minecraft.World/Items/DiggerItem.h b/Minecraft.World/Items/DiggerItem.h index 2e01d1b69..549c1f0d3 100644 --- a/Minecraft.World/Items/DiggerItem.h +++ b/Minecraft.World/Items/DiggerItem.h @@ -12,27 +12,27 @@ protected: float speed; private: - int attackDamage; + float attackDamage; protected: const Tier* tier; - DiggerItem(int id, int attackDamage, const Tier* tier, TileArray* tiles); + DiggerItem(int id, float attackDamage, const Tier* tier, TileArray* tiles); public: virtual float getDestroySpeed(std::shared_ptr itemInstance, Tile* tile); virtual bool hurtEnemy(std::shared_ptr itemInstance, - std::shared_ptr mob, - std::shared_ptr attacker); + std::shared_ptr mob, + std::shared_ptr attacker); virtual bool mineBlock(std::shared_ptr itemInstance, Level* level, int tile, int x, int y, int z, - std::shared_ptr owner); - virtual int getAttackDamage(std::shared_ptr entity); + std::shared_ptr owner); virtual bool isHandEquipped(); virtual int getEnchantmentValue(); const Tier* getTier(); bool isValidRepairItem(std::shared_ptr source, std::shared_ptr repairItem); + virtual attrAttrModMap* getDefaultAttributeModifiers(); }; \ No newline at end of file diff --git a/Minecraft.World/Items/DoorItem.cpp b/Minecraft.World/Items/DoorItem.cpp index e4cc4ef80..da161538d 100644 --- a/Minecraft.World/Items/DoorItem.cpp +++ b/Minecraft.World/Items/DoorItem.cpp @@ -1,5 +1,4 @@ - #include "../Platform/stdafx.h" #include "../Headers/net.minecraft.world.h" #include "../Headers/net.minecraft.world.entity.player.h" @@ -31,7 +30,8 @@ bool DoorItem::useOn(std::shared_ptr instance, else tile = Tile::door_iron; - if (!player->mayBuild(x, y, z) || !player->mayBuild(x, y + 1, z)) + if (!player->mayUseItemAt(x, y, z, face, instance) || + !player->mayUseItemAt(x, y + 1, z, face, instance)) return false; if (!tile->mayPlace(level, x, y, z)) return false; @@ -76,10 +76,9 @@ void DoorItem::place(Level* level, int x, int y, int z, int dir, Tile* tile) { else if (solidRight > solidLeft) flip = true; - level->noNeighborUpdate = true; - level->setTileAndData(x, y, z, tile->id, dir); - level->setTileAndData(x, y + 1, z, tile->id, 8 | (flip ? 1 : 0)); - level->noNeighborUpdate = false; + level->setTileAndData(x, y, z, tile->id, dir, Tile::UPDATE_CLIENTS); + level->setTileAndData(x, y + 1, z, tile->id, 8 | (flip ? 1 : 0), + Tile::UPDATE_CLIENTS); level->updateNeighborsAt(x, y, z, tile->id); level->updateNeighborsAt(x, y + 1, z, tile->id); } diff --git a/Minecraft.World/Items/DyePowderItem.cpp b/Minecraft.World/Items/DyePowderItem.cpp index 930755bb8..943de2359 100644 --- a/Minecraft.World/Items/DyePowderItem.cpp +++ b/Minecraft.World/Items/DyePowderItem.cpp @@ -1,5 +1,4 @@ - #include "../Platform/stdafx.h" #include "../Headers/com.mojang.nbt.h" #include "../Headers/net.minecraft.world.level.tile.h" @@ -39,15 +38,12 @@ const unsigned int DyePowderItem::COLOR_USE_DESCS[] = { IDS_DESC_DYE_WHITE}; const std::wstring DyePowderItem::COLOR_TEXTURES[] = { - L"dyePowder_black", L"dyePowder_red", L"dyePowder_green", - L"dyePowder_brown", L"dyePowder_blue", L"dyePowder_purple", - L"dyePowder_cyan", L"dyePowder_silver", L"dyePowder_gray", - L"dyePowder_pink", L"dyePowder_lime", L"dyePowder_yellow", - L"dyePowder_lightBlue", L"dyePowder_magenta", L"dyePowder_orange", - L"dyePowder_white"}; + L"black", L"red", L"green", L"brown", L"blue", L"purple", + L"cyan", L"silver", L"gray", L"pink", L"lime", L"yellow", + L"light_blue", L"magenta", L"orange", L"white"}; const int DyePowderItem::COLOR_RGB[] = {0x1e1b1b, 0xb3312c, 0x3b511a, 0x51301a, - 0x253192, 0x7b2fbe, 0xababab, 0x287697, + 0x253192, 0x7b2fbe, 0x287697, 0xababab, 0x434343, 0xd88198, 0x41cd34, 0xdecf2a, 0x6689d3, 0xc354cd, 0xeb8844, 0xf0f0f0}; @@ -88,115 +84,16 @@ bool DyePowderItem::useOn(std::shared_ptr itemInstance, std::shared_ptr player, Level* level, int x, int y, int z, int face, float clickX, float clickY, float clickZ, bool bTestUseOnOnly) { - if (!player->mayBuild(x, y, z)) return false; + if (!player->mayUseItemAt(x, y, z, face, itemInstance)) return false; // 4J-PB - Adding a test only version to allow tooltips to be displayed if (itemInstance->getAuxValue() == WHITE) { // bone meal is a fertilizer, so instantly grow trees and stuff - int tile = level->getTile(x, y, z); - if (tile == Tile::sapling_Id) { - if (!bTestUseOnOnly) { - if (!level->isClientSide) { - ((Sapling*)Tile::sapling) - ->growTree(level, x, y, z, level->random); - itemInstance->count--; - } - } - return true; - } else if (tile == Tile::mushroom1_Id || tile == Tile::mushroom2_Id) { - if (!bTestUseOnOnly) { - if (!level->isClientSide) { - if (((Mushroom*)Tile::tiles[tile]) - ->growTree(level, x, y, z, level->random)) { - itemInstance->count--; - } - } - } - return true; - } else if (tile == Tile::melonStem_Id || tile == Tile::pumpkinStem_Id) { - if (level->getData(x, y, z) == 7) return false; - if (!bTestUseOnOnly) { - if (!level->isClientSide) { - ((StemTile*)Tile::tiles[tile]) - ->growCropsToMax(level, x, y, z); - itemInstance->count--; - } - } - return true; - } else if (tile == Tile::carrots_Id || tile == Tile::potatoes_Id) { - if (level->getData(x, y, z) == 7) return false; - if (!bTestUseOnOnly) { - if (!level->isClientSide) { - ((CropTile*)Tile::tiles[tile]) - ->growCropsToMax(level, x, y, z); - itemInstance->count--; - } - } - return true; - } else if (tile == Tile::crops_Id) { - if (level->getData(x, y, z) == 7) return false; - if (!bTestUseOnOnly) { - if (!level->isClientSide) { - ((CropTile*)Tile::crops)->growCropsToMax(level, x, y, z); - itemInstance->count--; - } - } - return true; - } else if (tile == Tile::cocoa_Id) { - if (!bTestUseOnOnly) { - if (!level->isClientSide) { - level->setData(x, y, z, - (2 << 2) | DirectionalTile::getDirection( - level->getData(x, y, z))); - itemInstance->count--; - } - } - return true; - } else if (tile == Tile::grass_Id) { - if (!bTestUseOnOnly) { - if (!level->isClientSide) { - itemInstance->count--; - - for (int j = 0; j < 128; j++) { - int xx = x; - int yy = y + 1; - int zz = z; - for (int i = 0; i < j / 16; i++) { - xx += random->nextInt(3) - 1; - yy += (random->nextInt(3) - 1) * - random->nextInt(3) / 2; - zz += random->nextInt(3) - 1; - if (level->getTile(xx, yy - 1, zz) != - Tile::grass_Id || - level->isSolidBlockingTile(xx, yy, zz)) { - goto mainloop; - } - } - - if (level->getTile(xx, yy, zz) == 0) { - if (random->nextInt(10) != 0) { - if (Tile::tallgrass->canSurvive(level, xx, yy, - zz)) - level->setTileAndData( - xx, yy, zz, Tile::tallgrass_Id, - TallGrass::TALL_GRASS); - } else if (random->nextInt(3) != 0) { - if (Tile::flower->canSurvive(level, xx, yy, zz)) - level->setTile(xx, yy, zz, Tile::flower_Id); - } else { - if (Tile::rose->canSurvive(level, xx, yy, zz)) - level->setTile(xx, yy, zz, Tile::rose_Id); - } - } - - // 4J - Stops infinite loops. - mainloop: - continue; - } - } - } - + if (growCrop(itemInstance, level, x, y, z, bTestUseOnOnly)) { + if (!level->isClientSide) + level->levelEvent(LevelEvent::PARTICLES_PLANT_GROWTH, x, y, z, + 0); return true; } } else if (itemInstance->getAuxValue() == BROWN) { @@ -219,7 +116,8 @@ bool DyePowderItem::useOn(std::shared_ptr itemInstance, int cocoaData = Tile::tiles[Tile::cocoa_Id]->getPlacedOnFaceDataValue( level, x, y, z, face, clickX, clickY, clickZ, 0); - level->setTileAndData(x, y, z, Tile::cocoa_Id, cocoaData); + level->setTileAndData(x, y, z, Tile::cocoa_Id, cocoaData, + Tile::UPDATE_CLIENTS); if (!player->abilities.instabuild) { itemInstance->count--; } @@ -231,13 +129,148 @@ bool DyePowderItem::useOn(std::shared_ptr itemInstance, return false; } +bool DyePowderItem::growCrop(std::shared_ptr itemInstance, + Level* level, int x, int y, int z, + bool bTestUseOnOnly) { + int tile = level->getTile(x, y, z); + if (tile == Tile::sapling_Id) { + if (!bTestUseOnOnly) { + if (!level->isClientSide) { + if (level->random->nextFloat() < 0.45) + ((Sapling*)Tile::sapling) + ->advanceTree(level, x, y, z, level->random); + itemInstance->count--; + } + } + return true; + } else if (tile == Tile::mushroom_brown_Id || + tile == Tile::mushroom_red_Id) { + if (!bTestUseOnOnly) { + if (!level->isClientSide) { + if (level->random->nextFloat() < 0.4) + ((Mushroom*)Tile::tiles[tile]) + ->growTree(level, x, y, z, level->random); + itemInstance->count--; + } + } + return true; + } else if (tile == Tile::melonStem_Id || tile == Tile::pumpkinStem_Id) { + if (level->getData(x, y, z) == 7) return false; + if (!bTestUseOnOnly) { + if (!level->isClientSide) { + ((StemTile*)Tile::tiles[tile])->growCrops(level, x, y, z); + itemInstance->count--; + } + } + return true; + } else if (tile == Tile::carrots_Id || tile == Tile::potatoes_Id) { + if (level->getData(x, y, z) == 7) return false; + if (!bTestUseOnOnly) { + if (!level->isClientSide) { + ((CropTile*)Tile::tiles[tile])->growCrops(level, x, y, z); + itemInstance->count--; + } + } + return true; + } else if (tile == Tile::wheat_Id) { + if (level->getData(x, y, z) == 7) return false; + if (!bTestUseOnOnly) { + if (!level->isClientSide) { + ((CropTile*)Tile::tiles[tile])->growCrops(level, x, y, z); + itemInstance->count--; + } + } + return true; + } else if (tile == Tile::cocoa_Id) { + if (!bTestUseOnOnly) { + int data = level->getData(x, y, z); + int direction = DirectionalTile::getDirection(data); + int age = CocoaTile::getAge(data); + if (age >= 2) return false; + if (!level->isClientSide) { + age++; + level->setData(x, y, z, (age << 2) | direction, + Tile::UPDATE_CLIENTS); + itemInstance->count--; + } + } + return true; + } else if (tile == Tile::grass_Id) { + if (!bTestUseOnOnly) { + if (!level->isClientSide) { + itemInstance->count--; + + for (int j = 0; j < 128; j++) { + int xx = x; + int yy = y + 1; + int zz = z; + for (int i = 0; i < j / 16; i++) { + xx += random->nextInt(3) - 1; + yy += (random->nextInt(3) - 1) * random->nextInt(3) / 2; + zz += random->nextInt(3) - 1; + if (level->getTile(xx, yy - 1, zz) != Tile::grass_Id || + level->isSolidBlockingTile(xx, yy, zz)) { + goto mainloop; + } + } + + if (level->getTile(xx, yy, zz) == 0) { + if (random->nextInt(10) != 0) { + if (Tile::tallgrass->canSurvive(level, xx, yy, zz)) + level->setTileAndData( + xx, yy, zz, Tile::tallgrass_Id, + TallGrass::TALL_GRASS, Tile::UPDATE_ALL); + } else if (random->nextInt(3) != 0) { + if (Tile::flower->canSurvive(level, xx, yy, zz)) + level->setTileAndUpdate(xx, yy, zz, + Tile::flower_Id); + } else { + if (Tile::rose->canSurvive(level, xx, yy, zz)) + level->setTileAndUpdate(xx, yy, zz, + Tile::rose_Id); + } + } + + // 4J - Stops infinite loops. + mainloop: + continue; + } + } + } + + return true; + } + return false; +} + +void DyePowderItem::addGrowthParticles(Level* level, int x, int y, int z, + int count) { + int id = level->getTile(x, y, z); + if (count == 0) count = 15; + Tile* tile = id > 0 && id < Tile::TILE_NUM_COUNT ? Tile::tiles[id] : NULL; + + if (tile == NULL) return; + tile->updateShape(level, x, y, z); + + for (int i = 0; i < count; i++) { + double xa = level->random->nextGaussian() * 0.02; + double ya = level->random->nextGaussian() * 0.02; + double za = level->random->nextGaussian() * 0.02; + level->addParticle(eParticleType_happyVillager, + x + level->random->nextFloat(), + y + level->random->nextFloat() * tile->getShapeY1(), + z + level->random->nextFloat(), xa, ya, za); + } +} + bool DyePowderItem::interactEnemy(std::shared_ptr itemInstance, - std::shared_ptr mob) { + std::shared_ptr player, + std::shared_ptr mob) { if (std::dynamic_pointer_cast(mob) != NULL) { std::shared_ptr sheep = std::dynamic_pointer_cast(mob); // convert to tile-based color value (0 is white instead of black) - int newColor = - ClothTile::getTileDataForItemAuxValue(itemInstance->getAuxValue()); + int newColor = ColoredTile::getTileDataForItemAuxValue( + itemInstance->getAuxValue()); if (!sheep->isSheared() && sheep->getColor() != newColor) { sheep->setColor(newColor); itemInstance->count--; @@ -251,6 +284,7 @@ void DyePowderItem::registerIcons(IconRegister* iconRegister) { icons = new Icon*[DYE_POWDER_ITEM_TEXTURE_COUNT]; for (int i = 0; i < DYE_POWDER_ITEM_TEXTURE_COUNT; i++) { - icons[i] = iconRegister->registerIcon(COLOR_TEXTURES[i]); + icons[i] = iconRegister->registerIcon(getIconName() + L"_" + + COLOR_TEXTURES[i]); } } \ No newline at end of file diff --git a/Minecraft.World/Items/DyePowderItem.h b/Minecraft.World/Items/DyePowderItem.h index 9fc7fe036..5ed4091b1 100644 --- a/Minecraft.World/Items/DyePowderItem.h +++ b/Minecraft.World/Items/DyePowderItem.h @@ -46,8 +46,14 @@ public: std::shared_ptr player, Level* level, int x, int y, int z, int face, float clickX, float clickY, float clickZ, bool bTestUseOnOnly = false); + static bool growCrop(std::shared_ptr itemInstance, + Level* level, int x, int y, int z, + bool bTestUseOnOnly); + static void addGrowthParticles(Level* level, int x, int y, int z, + int count); virtual bool interactEnemy(std::shared_ptr itemInstance, - std::shared_ptr mob); + std::shared_ptr player, + std::shared_ptr mob); //@Override void registerIcons(IconRegister* iconRegister); diff --git a/Minecraft.World/Items/EggItem.cpp b/Minecraft.World/Items/EggItem.cpp index d2b9ebc28..b47cf12da 100644 --- a/Minecraft.World/Items/EggItem.cpp +++ b/Minecraft.World/Items/EggItem.cpp @@ -1,5 +1,4 @@ - #include "../Platform/stdafx.h" #include "../Headers/com.mojang.nbt.h" #include "../Headers/net.minecraft.world.level.tile.h" @@ -13,7 +12,7 @@ #include "EggItem.h" #include "../Util/SoundTypes.h" -EggItem::EggItem(int id) : Item(id) { this->maxStackSize = 16; } +EggItem::EggItem(int id) : Item(id) { maxStackSize = 16; } std::shared_ptr EggItem::use( std::shared_ptr instance, Level* level, @@ -21,11 +20,10 @@ std::shared_ptr EggItem::use( if (!player->abilities.instabuild) { instance->count--; } - level->playSound(std::dynamic_pointer_cast(player), - eSoundType_RANDOM_BOW, 0.5f, - 0.4f / (random->nextFloat() * 0.4f + 0.8f)); + level->playEntitySound(player, eSoundType_RANDOM_BOW, 0.5f, + 0.4f / (random->nextFloat() * 0.4f + 0.8f)); if (!level->isClientSide) - level->addEntity(std::shared_ptr( - new ThrownEgg(level, std::dynamic_pointer_cast(player)))); + level->addEntity( + std::shared_ptr(new ThrownEgg(level, player))); return instance; } diff --git a/Minecraft.World/Items/EmptyMapItem.cpp b/Minecraft.World/Items/EmptyMapItem.cpp new file mode 100644 index 000000000..1fd80a19b --- /dev/null +++ b/Minecraft.World/Items/EmptyMapItem.cpp @@ -0,0 +1,40 @@ +#include "../Platform/stdafx.h" +#include "../Headers/net.minecraft.world.item.h" +#include "../Headers/net.minecraft.world.entity.player.h" +#include "EmptyMapItem.h" + +EmptyMapItem::EmptyMapItem(int id) : ComplexItem(id) {} + +std::shared_ptr EmptyMapItem::use( + std::shared_ptr itemInstance, Level* level, + std::shared_ptr player) { + // shared_ptr map = shared_ptr( new + // ItemInstance(Item::map, 1, level->getFreeAuxValueFor(L"map")) ); + + // String id = "map_" + map.getAuxValue(); + // MapItemSavedData data = new MapItemSavedData(id); + // level.setSavedData(id, data); + + // data.scale = 0; + // int scale = MapItemSavedData.MAP_SIZE * 2 * (1 << data.scale); + // data.x = (int) (Math.round(player.x / scale) * scale); + // data.z = (int) (Math.round(player.z / scale) * scale); + // data.dimension = (byte) level.dimension.id; + + // data.setDirty(); + + std::shared_ptr map = + std::shared_ptr(new ItemInstance(Item::map, 1, -1)); + Item::map->onCraftedBy(map, level, player); + + itemInstance->count--; + if (itemInstance->count <= 0) { + return map; + } else { + if (!player->inventory->add(map->copy())) { + player->drop(map); + } + } + + return itemInstance; +} \ No newline at end of file diff --git a/Minecraft.World/Items/EmptyMapItem.h b/Minecraft.World/Items/EmptyMapItem.h new file mode 100644 index 000000000..11e7213f9 --- /dev/null +++ b/Minecraft.World/Items/EmptyMapItem.h @@ -0,0 +1,12 @@ +#pragma once + +#include "ComplexItem.h" + +class EmptyMapItem : public ComplexItem { +public: + EmptyMapItem(int id); + + std::shared_ptr use( + std::shared_ptr itemInstance, Level* level, + std::shared_ptr player); +}; \ No newline at end of file diff --git a/Minecraft.World/Items/EnchantedBookItem.cpp b/Minecraft.World/Items/EnchantedBookItem.cpp index b111d0b3e..88e8850f3 100644 --- a/Minecraft.World/Items/EnchantedBookItem.cpp +++ b/Minecraft.World/Items/EnchantedBookItem.cpp @@ -41,10 +41,8 @@ ListTag* EnchantedBookItem::getEnchantments( void EnchantedBookItem::appendHoverText( std::shared_ptr itemInstance, std::shared_ptr player, - std::vector* lines, bool advanced, - std::vector& unformattedStrings) { - Item::appendHoverText(itemInstance, player, lines, advanced, - unformattedStrings); + std::vector* lines, bool advanced) { + Item::appendHoverText(itemInstance, player, lines, advanced); ListTag* list = getEnchantments(itemInstance); @@ -57,9 +55,8 @@ void EnchantedBookItem::appendHoverText( list->get(i)->getShort((wchar_t*)ItemInstance::TAG_ENCH_LEVEL); if (Enchantment::enchantments[type] != NULL) { - lines->push_back(Enchantment::enchantments[type]->getFullname( - level, unformatted)); - unformattedStrings.push_back(unformatted); + lines->push_back( + Enchantment::enchantments[type]->getFullname(level)); } } } diff --git a/Minecraft.World/Items/EnchantedBookItem.h b/Minecraft.World/Items/EnchantedBookItem.h index 459aae6a7..7326615d5 100644 --- a/Minecraft.World/Items/EnchantedBookItem.h +++ b/Minecraft.World/Items/EnchantedBookItem.h @@ -16,8 +16,7 @@ public: ListTag* getEnchantments(std::shared_ptr item); void appendHoverText(std::shared_ptr itemInstance, std::shared_ptr player, - std::vector* lines, bool advanced, - std::vector& unformattedStrings); + std::vector* lines, bool advanced); void addEnchantment(std::shared_ptr item, EnchantmentInstance* enchantment); std::shared_ptr createForEnchantment( diff --git a/Minecraft.World/Items/EnderEyeItem.cpp b/Minecraft.World/Items/EnderEyeItem.cpp index 3d2706d9f..f3dd572ea 100644 --- a/Minecraft.World/Items/EnderEyeItem.cpp +++ b/Minecraft.World/Items/EnderEyeItem.cpp @@ -18,12 +18,15 @@ bool EnderEyeItem::useOn(std::shared_ptr instance, int targetType = level->getTile(x, y, z); int targetData = level->getData(x, y, z); - if (player->mayBuild(x, y, z) && + if (player->mayUseItemAt(x, y, z, face, instance) && targetType == Tile::endPortalFrameTile_Id && !TheEndPortalFrameTile::hasEye(targetData)) { if (bTestUseOnOnly) return true; if (level->isClientSide) return true; - level->setData(x, y, z, targetData + TheEndPortalFrameTile::EYE_BIT); + level->setData(x, y, z, targetData + TheEndPortalFrameTile::EYE_BIT, + Tile::UPDATE_CLIENTS); + level->updateNeighbourForOutputSignal(x, y, z, + Tile::endPortalFrameTile_Id); instance->count--; for (int i = 0; i < 16; i++) { @@ -112,8 +115,9 @@ bool EnderEyeItem::useOn(std::shared_ptr instance, targetX += Direction::STEP_X[direction] * pz; targetZ += Direction::STEP_Z[direction] * pz; - level->setTile(targetX, y, targetZ, - Tile::endPortalTile_Id); + level->setTileAndData(targetX, y, targetZ, + Tile::endPortalTile_Id, 0, + Tile::UPDATE_CLIENTS); } } } @@ -124,7 +128,8 @@ bool EnderEyeItem::useOn(std::shared_ptr instance, return false; } -bool EnderEyeItem::TestUse(Level* level, std::shared_ptr player) { +bool EnderEyeItem::TestUse(std::shared_ptr itemInstance, + Level* level, std::shared_ptr player) { HitResult* hr = getPlayerPOVHitResult(level, player, false); if (hr != NULL && hr->type == HitResult::TILE) { int tile = level->getTile(hr->x, hr->y, hr->z); @@ -164,7 +169,8 @@ bool EnderEyeItem::TestUse(Level* level, std::shared_ptr player) { } // TilePos *nearestMapFeature = // level->findNearestMapFeature(LargeFeature::STRONGHOLD, (int) - // player->x, (int) player->y, (int) player->z); if (nearestMapFeature + // player->x, (int) player->y, (int) player->z); if + // (nearestMapFeature // != NULL) // { // delete nearestMapFeature; @@ -201,34 +207,14 @@ std::shared_ptr EnderEyeItem::use( level->getLevelData()->getZStronghold() << 4); level->addEntity(eyeOfEnderSignal); - level->playSound(player, eSoundType_RANDOM_BOW, 0.5f, - 0.4f / (random->nextFloat() * 0.4f + 0.8f)); + level->playEntitySound(player, eSoundType_RANDOM_BOW, 0.5f, + 0.4f / (random->nextFloat() * 0.4f + 0.8f)); level->levelEvent(nullptr, LevelEvent::SOUND_LAUNCH, (int)player->x, (int)player->y, (int)player->z, 0); if (!player->abilities.instabuild) { instance->count--; } } - - /*TilePos *nearestMapFeature = - level->findNearestMapFeature(LargeFeature::STRONGHOLD, (int) player->x, - (int) player->y, (int) player->z); if (nearestMapFeature != NULL) - { - std::shared_ptr eyeOfEnderSignal = - std::shared_ptr( new EyeOfEnderSignal(level, - player->x, player->y + 1.62 - player->heightOffset, player->z) ); - eyeOfEnderSignal->signalTo(nearestMapFeature->x, - nearestMapFeature->y, nearestMapFeature->z); delete nearestMapFeature; - level->addEntity(eyeOfEnderSignal); - - level->playSound(player, eSoundType_RANDOM_BOW, 0.5f, 0.4f / - (random->nextFloat() * 0.4f + 0.8f)); level->levelEvent(NULL, - LevelEvent::SOUND_LAUNCH, (int) player->x, (int) player->y, (int) - player->z, 0); if (!player->abilities.instabuild) - { - instance->count--; - } - }*/ } return instance; } \ No newline at end of file diff --git a/Minecraft.World/Items/EnderEyeItem.h b/Minecraft.World/Items/EnderEyeItem.h index 162879445..d7510bc85 100644 --- a/Minecraft.World/Items/EnderEyeItem.h +++ b/Minecraft.World/Items/EnderEyeItem.h @@ -10,7 +10,8 @@ public: std::shared_ptr player, Level* level, int x, int y, int z, int face, float clickX, float clickY, float clickZ, bool bTestUseOnOnly = false); - virtual bool TestUse(Level* level, std::shared_ptr player); + virtual bool TestUse(std::shared_ptr itemInstance, + Level* level, std::shared_ptr player); virtual std::shared_ptr use( std::shared_ptr instance, Level* level, std::shared_ptr player); diff --git a/Minecraft.World/Items/EnderPearlItem.cpp b/Minecraft.World/Items/EnderPearlItem.cpp index ee6dd7b60..589403f72 100644 --- a/Minecraft.World/Items/EnderPearlItem.cpp +++ b/Minecraft.World/Items/EnderPearlItem.cpp @@ -5,9 +5,10 @@ #include "EnderPearlItem.h" #include "../Util/SoundTypes.h" -EnderpearlItem::EnderpearlItem(int id) : Item(id) { this->maxStackSize = 16; } +EnderpearlItem::EnderpearlItem(int id) : Item(id) { maxStackSize = 16; } -bool EnderpearlItem::TestUse(Level* level, std::shared_ptr player) { +bool EnderpearlItem::TestUse(std::shared_ptr itemInstance, + Level* level, std::shared_ptr player) { return true; } @@ -22,8 +23,8 @@ std::shared_ptr EnderpearlItem::use( instance->count--; } - level->playSound(player, eSoundType_RANDOM_BOW, 0.5f, - 0.4f / (random->nextFloat() * 0.4f + 0.8f)); + level->playEntitySound(player, eSoundType_RANDOM_BOW, 0.5f, + 0.4f / (random->nextFloat() * 0.4f + 0.8f)); if (!level->isClientSide) { level->addEntity(std::shared_ptr( new ThrownEnderpearl(level, player))); diff --git a/Minecraft.World/Items/EnderPearlItem.h b/Minecraft.World/Items/EnderPearlItem.h index f0681faa9..3ba152688 100644 --- a/Minecraft.World/Items/EnderPearlItem.h +++ b/Minecraft.World/Items/EnderPearlItem.h @@ -10,5 +10,6 @@ public: std::shared_ptr instance, Level* level, std::shared_ptr player); // 4J added - virtual bool TestUse(Level* level, std::shared_ptr player); + virtual bool TestUse(std::shared_ptr instance, Level* level, + std::shared_ptr player); }; \ No newline at end of file diff --git a/Minecraft.World/Items/ExperienceItem.cpp b/Minecraft.World/Items/ExperienceItem.cpp index 891cb5884..c02449444 100644 --- a/Minecraft.World/Items/ExperienceItem.cpp +++ b/Minecraft.World/Items/ExperienceItem.cpp @@ -12,7 +12,8 @@ bool ExperienceItem::isFoil(std::shared_ptr itemInstance) { return true; } -bool ExperienceItem::TestUse(Level* level, std::shared_ptr player) { +bool ExperienceItem::TestUse(std::shared_ptr itemInstance, + Level* level, std::shared_ptr player) { return true; } @@ -22,8 +23,8 @@ std::shared_ptr ExperienceItem::use( if (!player->abilities.instabuild) { itemInstance->count--; } - level->playSound(player, eSoundType_RANDOM_BOW, 0.5f, - 0.4f / (random->nextFloat() * 0.4f + 0.8f)); + level->playEntitySound(player, eSoundType_RANDOM_BOW, 0.5f, + 0.4f / (random->nextFloat() * 0.4f + 0.8f)); if (!level->isClientSide) level->addEntity(std::shared_ptr( new ThrownExpBottle(level, player))); diff --git a/Minecraft.World/Items/ExperienceItem.h b/Minecraft.World/Items/ExperienceItem.h index e1660cdba..0d01049cb 100644 --- a/Minecraft.World/Items/ExperienceItem.h +++ b/Minecraft.World/Items/ExperienceItem.h @@ -12,5 +12,6 @@ public: virtual std::shared_ptr use( std::shared_ptr itemInstance, Level* level, std::shared_ptr player); - virtual bool TestUse(Level* level, std::shared_ptr player); + virtual bool TestUse(std::shared_ptr itemInstance, + Level* level, std::shared_ptr player); }; \ No newline at end of file diff --git a/Minecraft.World/Items/FireChargeItem.cpp b/Minecraft.World/Items/FireChargeItem.cpp index d23c46cdc..0e5cff79a 100644 --- a/Minecraft.World/Items/FireChargeItem.cpp +++ b/Minecraft.World/Items/FireChargeItem.cpp @@ -12,7 +12,7 @@ FireChargeItem::FireChargeItem(int id) : Item(id) { m_dragonFireballIcon = NULL; } -bool FireChargeItem::useOn(std::shared_ptr itemInstance, +bool FireChargeItem::useOn(std::shared_ptr instance, std::shared_ptr player, Level* level, int x, int y, int z, int face, float clickX, float clickY, float clickZ, bool bTestUseOnOnly) { @@ -27,7 +27,7 @@ bool FireChargeItem::useOn(std::shared_ptr itemInstance, if (face == 4) x--; if (face == 5) x++; - if (!player->mayBuild(x, y, z)) { + if (!player->mayUseItemAt(x, y, z, face, instance)) { return false; } @@ -39,13 +39,13 @@ bool FireChargeItem::useOn(std::shared_ptr itemInstance, int targetType = level->getTile(x, y, z); if (targetType == 0) { - level->playSound(x + 0.5, y + 0.5, z + 0.5, eSoundType_FIRE_IGNITE, 1, - random->nextFloat() * 0.4f + 0.8f); - level->setTile(x, y, z, Tile::fire_Id); + level->playSound(x + 0.5, y + 0.5, z + 0.5, eSoundType_FIRE_NEWIGNITE, + 1, random->nextFloat() * 0.4f + 0.8f); + level->setTileAndUpdate(x, y, z, Tile::fire_Id); } if (!player->abilities.instabuild) { - itemInstance->count--; + instance->count--; } return true; } diff --git a/Minecraft.World/Items/FireworksChargeItem.cpp b/Minecraft.World/Items/FireworksChargeItem.cpp new file mode 100644 index 000000000..a6c2cc5b2 --- /dev/null +++ b/Minecraft.World/Items/FireworksChargeItem.cpp @@ -0,0 +1,173 @@ +#include "../Platform/stdafx.h" +#include "../Headers/net.minecraft.world.item.h" +#include "../Headers/net.minecraft.world.h" +#include "FireworksChargeItem.h" + +FireworksChargeItem::FireworksChargeItem(int id) : Item(id) {} + +Icon* FireworksChargeItem::getLayerIcon(int auxValue, int spriteLayer) { + if (spriteLayer > 0) { + return overlay; + } + return Item::getLayerIcon(auxValue, spriteLayer); +} + +int FireworksChargeItem::getColor(std::shared_ptr item, + int spriteLayer) { + if (spriteLayer == 1) { + Tag* colorTag = getExplosionTagField(item, FireworksItem::TAG_E_COLORS); + if (colorTag != NULL) { + IntArrayTag* colors = (IntArrayTag*)colorTag; + if (colors->data.length == 1) { + return colors->data[0]; + } + int totalRed = 0; + int totalGreen = 0; + int totalBlue = 0; + for (unsigned int i = 0; i < colors->data.length; ++i) { + int c = colors->data[i]; + totalRed += (c & 0xff0000) >> 16; + totalGreen += (c & 0x00ff00) >> 8; + totalBlue += (c & 0x0000ff) >> 0; + } + totalRed /= colors->data.length; + totalGreen /= colors->data.length; + totalBlue /= colors->data.length; + return (totalRed << 16) | (totalGreen << 8) | totalBlue; + } + return 0x8a8a8a; + } + return Item::getColor(item, spriteLayer); +} + +bool FireworksChargeItem::hasMultipleSpriteLayers() { return true; } + +Tag* FireworksChargeItem::getExplosionTagField( + std::shared_ptr instance, const std::wstring& field) { + if (instance->hasTag()) { + CompoundTag* explosion = + instance->getTag()->getCompound(FireworksItem::TAG_EXPLOSION); + if (explosion != NULL) { + return explosion->get(field); + } + } + return NULL; +} + +void FireworksChargeItem::appendHoverText( + std::shared_ptr itemInstance, std::shared_ptr player, + std::vector* lines, bool advanced) { + if (itemInstance->hasTag()) { + CompoundTag* explosion = + itemInstance->getTag()->getCompound(FireworksItem::TAG_EXPLOSION); + if (explosion != NULL) { + appendHoverText(explosion, lines); + } + } +} + +const unsigned int FIREWORKS_CHARGE_TYPE_NAME[] = { + IDS_FIREWORKS_CHARGE_TYPE_0, IDS_FIREWORKS_CHARGE_TYPE_1, + IDS_FIREWORKS_CHARGE_TYPE_2, IDS_FIREWORKS_CHARGE_TYPE_3, + IDS_FIREWORKS_CHARGE_TYPE_4}; + +const unsigned int FIREWORKS_CHARGE_COLOUR_NAME[] = { + IDS_FIREWORKS_CHARGE_BLACK, IDS_FIREWORKS_CHARGE_RED, + IDS_FIREWORKS_CHARGE_GREEN, IDS_FIREWORKS_CHARGE_BROWN, + IDS_FIREWORKS_CHARGE_BLUE, IDS_FIREWORKS_CHARGE_PURPLE, + IDS_FIREWORKS_CHARGE_CYAN, IDS_FIREWORKS_CHARGE_SILVER, + IDS_FIREWORKS_CHARGE_GRAY, IDS_FIREWORKS_CHARGE_PINK, + IDS_FIREWORKS_CHARGE_LIME, IDS_FIREWORKS_CHARGE_YELLOW, + IDS_FIREWORKS_CHARGE_LIGHT_BLUE, IDS_FIREWORKS_CHARGE_MAGENTA, + IDS_FIREWORKS_CHARGE_ORANGE, IDS_FIREWORKS_CHARGE_WHITE}; + +void FireworksChargeItem::appendHoverText(CompoundTag* expTag, + std::vector* lines) { + // shape + uint8_t type = expTag->getByte(FireworksItem::TAG_E_TYPE); + if (type >= FireworksItem::TYPE_MIN && type <= FireworksItem::TYPE_MAX) { + lines->push_back( + HtmlString(app.GetString(FIREWORKS_CHARGE_TYPE_NAME[type]))); + } else { + lines->push_back(HtmlString(app.GetString(IDS_FIREWORKS_CHARGE_TYPE))); + } + + // colors + intArray colorList = expTag->getIntArray(FireworksItem::TAG_E_COLORS); + if (colorList.length > 0) { + bool first = true; + std::wstring output = L""; + for (unsigned int i = 0; i < colorList.length; ++i) { + int c = colorList[i]; + if (!first) { + output += + L",\n"; // 4J-PB - without the newline, they tend to go + // offscreen in split-screen or localised languages + } + first = false; + + // find color name by lookup + bool found = false; + for (int dc = 0; dc < 16; dc++) { + if (c == DyePowderItem::COLOR_RGB[dc]) { + found = true; + output += app.GetString(FIREWORKS_CHARGE_COLOUR_NAME[dc]); + break; + } + } + if (!found) { + output += app.GetString(IDS_FIREWORKS_CHARGE_CUSTOM); + } + } + lines->push_back(output); + } + + // has fade? + intArray fadeList = expTag->getIntArray(FireworksItem::TAG_E_FADECOLORS); + if (fadeList.length > 0) { + bool first = true; + std::wstring output = + std::wstring(app.GetString(IDS_FIREWORKS_CHARGE_FADE_TO)) + L" "; + for (unsigned int i = 0; i < fadeList.length; ++i) { + int c = fadeList[i]; + if (!first) { + output += + L",\n"; // 4J-PB - without the newline, they tend to go + // offscreen in split-screen or localised languages + } + first = false; + + // find color name by lookup + bool found = false; + for (int dc = 0; dc < 16; dc++) { + if (c == DyePowderItem::COLOR_RGB[dc]) { + found = true; + output += app.GetString(FIREWORKS_CHARGE_COLOUR_NAME[dc]); + break; + } + } + if (!found) { + output += app.GetString(IDS_FIREWORKS_CHARGE_CUSTOM); + } + } + lines->push_back(output); + } + + // has trail + bool trail = expTag->getBoolean(FireworksItem::TAG_E_TRAIL); + if (trail) { + lines->push_back(HtmlString(app.GetString(IDS_FIREWORKS_CHARGE_TRAIL))); + } + + // has flicker + bool flicker = expTag->getBoolean(FireworksItem::TAG_E_FLICKER); + if (flicker) { + lines->push_back( + HtmlString(app.GetString(IDS_FIREWORKS_CHARGE_FLICKER))); + } +} + +void FireworksChargeItem::registerIcons(IconRegister* iconRegister) { + Item::registerIcons(iconRegister); + overlay = iconRegister->registerIcon(getIconName() + L"_overlay"); +} \ No newline at end of file diff --git a/Minecraft.World/Items/FireworksChargeItem.h b/Minecraft.World/Items/FireworksChargeItem.h new file mode 100644 index 000000000..9b3a77f74 --- /dev/null +++ b/Minecraft.World/Items/FireworksChargeItem.h @@ -0,0 +1,27 @@ +#pragma once + +#include "Item.h" + +class FireworksChargeItem : public Item { +private: + Icon* overlay; + +public: + FireworksChargeItem(int id); + + virtual Icon* getLayerIcon(int auxValue, int spriteLayer); + virtual int getColor(std::shared_ptr item, int spriteLayer); + virtual bool hasMultipleSpriteLayers(); + + static Tag* getExplosionTagField(std::shared_ptr instance, + const std::wstring& field); + + virtual void appendHoverText(std::shared_ptr itemInstance, + std::shared_ptr player, + std::vector* lines, bool advanced); + + static void appendHoverText(CompoundTag* expTag, + std::vector* lines); + + virtual void registerIcons(IconRegister* iconRegister); +}; \ No newline at end of file diff --git a/Minecraft.World/Items/FireworksItem.cpp b/Minecraft.World/Items/FireworksItem.cpp new file mode 100644 index 000000000..42cd0c133 --- /dev/null +++ b/Minecraft.World/Items/FireworksItem.cpp @@ -0,0 +1,79 @@ +#include "../Platform/stdafx.h" +#include "../Headers/net.minecraft.world.entity.player.h" +#include "../Headers/net.minecraft.world.entity.projectile.h" +#include "../Headers/net.minecraft.world.item.h" +#include "../Headers/net.minecraft.world.level.h" +#include "FireworksItem.h" + +const std::wstring FireworksItem::TAG_FIREWORKS = L"Fireworks"; +const std::wstring FireworksItem::TAG_EXPLOSION = L"Explosion"; +const std::wstring FireworksItem::TAG_EXPLOSIONS = L"Explosions"; +const std::wstring FireworksItem::TAG_FLIGHT = L"Flight"; +const std::wstring FireworksItem::TAG_E_TYPE = L"Type"; +const std::wstring FireworksItem::TAG_E_TRAIL = L"Trail"; +const std::wstring FireworksItem::TAG_E_FLICKER = L"Flicker"; +const std::wstring FireworksItem::TAG_E_COLORS = L"Colors"; +const std::wstring FireworksItem::TAG_E_FADECOLORS = L"FadeColors"; + +FireworksItem::FireworksItem(int id) : Item(id) {} + +bool FireworksItem::useOn(std::shared_ptr instance, + std::shared_ptr player, Level* level, int x, + int y, int z, int face, float clickX, float clickY, + float clickZ, bool bTestUseOnOnly) { + // 4J-JEV: Fix for xb1 #173493 - CU7: Content: UI: Missing tooltip for + // Firework Rocket. + if (bTestUseOnOnly) return true; + + if (!level->isClientSide) { + std::shared_ptr f = + std::shared_ptr(new FireworksRocketEntity( + level, x + clickX, y + clickY, z + clickZ, instance)); + level->addEntity(f); + + if (!player->abilities.instabuild) { + instance->count--; + } + return true; + } + + return false; +} + +void FireworksItem::appendHoverText(std::shared_ptr itemInstance, + std::shared_ptr player, + std::vector* lines, + bool advanced) { + if (!itemInstance->hasTag()) { + return; + } + CompoundTag* fireTag = itemInstance->getTag()->getCompound(TAG_FIREWORKS); + if (fireTag == NULL) { + return; + } + if (fireTag->contains(TAG_FLIGHT)) { + lines->push_back( + std::wstring(app.GetString(IDS_ITEM_FIREWORKS_FLIGHT)) + L" " + + _toString((fireTag->getByte(TAG_FLIGHT)))); + } + + ListTag* explosions = + (ListTag*)fireTag->getList(TAG_EXPLOSIONS); + if (explosions != NULL && explosions->size() > 0) { + for (int i = 0; i < explosions->size(); i++) { + CompoundTag* expTag = explosions->get(i); + + std::vector eLines; + FireworksChargeItem::appendHoverText(expTag, &eLines); + + if (eLines.size() > 0) { + // Indent lines after first line + for (int i = 1; i < eLines.size(); i++) { + eLines[i].indent = true; + } + + lines->insert(lines->end(), eLines.begin(), eLines.end()); + } + } + } +} \ No newline at end of file diff --git a/Minecraft.World/Items/FireworksItem.h b/Minecraft.World/Items/FireworksItem.h new file mode 100644 index 000000000..1340804a3 --- /dev/null +++ b/Minecraft.World/Items/FireworksItem.h @@ -0,0 +1,35 @@ +#pragma once + +#include "Item.h" + +class FireworksItem : public Item { +public: + static const std::wstring TAG_FIREWORKS; + static const std::wstring TAG_EXPLOSION; + static const std::wstring TAG_EXPLOSIONS; + static const std::wstring TAG_FLIGHT; + static const std::wstring TAG_E_TYPE; + static const std::wstring TAG_E_TRAIL; + static const std::wstring TAG_E_FLICKER; + static const std::wstring TAG_E_COLORS; + static const std::wstring TAG_E_FADECOLORS; + + static const uint8_t TYPE_SMALL = 0; + static const uint8_t TYPE_BIG = 1; + static const uint8_t TYPE_STAR = 2; + static const uint8_t TYPE_CREEPER = 3; + static const uint8_t TYPE_BURST = 4; + + static const uint8_t TYPE_MIN = TYPE_SMALL; + static const uint8_t TYPE_MAX = TYPE_BURST; + + FireworksItem(int id); + + bool useOn(std::shared_ptr instance, + std::shared_ptr player, Level* level, int x, int y, + int z, int face, float clickX, float clickY, float clickZ, + bool bTestUseOnOnly = false); + void appendHoverText(std::shared_ptr itemInstance, + std::shared_ptr player, + std::vector* lines, bool advanced); +}; \ No newline at end of file diff --git a/Minecraft.World/Items/FishingRodItem.cpp b/Minecraft.World/Items/FishingRodItem.cpp index 818aed1f3..d95db92e7 100644 --- a/Minecraft.World/Items/FishingRodItem.cpp +++ b/Minecraft.World/Items/FishingRodItem.cpp @@ -13,8 +13,6 @@ #include "FishingRodItem.h" #include "../Util/SoundTypes.h" -const std::wstring FishingRodItem::TEXTURE_EMPTY = L"fishingRod_empty"; - FishingRodItem::FishingRodItem(int id) : Item(id) { setMaxDamage(64); setMaxStackSize(1); @@ -30,11 +28,11 @@ std::shared_ptr FishingRodItem::use( std::shared_ptr player) { if (player->fishing != NULL) { int dmg = player->fishing->retrieve(); - instance->hurt(dmg, player); + instance->hurtAndBreak(dmg, player); player->swing(); } else { - level->playSound(player, eSoundType_RANDOM_BOW, 0.5f, - 0.4f / (random->nextFloat() * 0.4f + 0.8f)); + level->playEntitySound(player, eSoundType_RANDOM_BOW, 0.5f, + 0.4f / (random->nextFloat() * 0.4f + 0.8f)); if (!level->isClientSide) { // 4J Stu - Move the player->fishing out of the ctor as we cannot // reference 'this' @@ -49,8 +47,8 @@ std::shared_ptr FishingRodItem::use( } void FishingRodItem::registerIcons(IconRegister* iconRegister) { - Item::registerIcons(iconRegister); - emptyIcon = iconRegister->registerIcon(TEXTURE_EMPTY); + icon = iconRegister->registerIcon(getIconName() + L"_uncast"); + emptyIcon = iconRegister->registerIcon(getIconName() + L"_cast"); } Icon* FishingRodItem::getEmptyIcon() { return emptyIcon; } diff --git a/Minecraft.World/Items/FishingRodItem.h b/Minecraft.World/Items/FishingRodItem.h index 4a71bcc9d..e2462d975 100644 --- a/Minecraft.World/Items/FishingRodItem.h +++ b/Minecraft.World/Items/FishingRodItem.h @@ -6,9 +6,6 @@ class Player; class Level; class FishingRodItem : public Item { -public: - static const std::wstring TEXTURE_EMPTY; - private: Icon* emptyIcon; @@ -21,7 +18,6 @@ public: std::shared_ptr instance, Level* level, std::shared_ptr player); - //@Override void registerIcons(IconRegister* iconRegister); Icon* getEmptyIcon(); }; diff --git a/Minecraft.World/Items/FlintAndSteelItem.cpp b/Minecraft.World/Items/FlintAndSteelItem.cpp index b4d4dc48a..eef623779 100644 --- a/Minecraft.World/Items/FlintAndSteelItem.cpp +++ b/Minecraft.World/Items/FlintAndSteelItem.cpp @@ -26,7 +26,7 @@ bool FlintAndSteelItem::useOn(std::shared_ptr instance, if (face == 4) x--; if (face == 5) x++; - if (!player->mayBuild(x, y, z)) return false; + if (!player->mayUseItemAt(x, y, z, face, instance)) return false; int targetType = level->getTile(x, y, z); @@ -43,12 +43,13 @@ bool FlintAndSteelItem::useOn(std::shared_ptr instance, } } - level->playSound(x + 0.5, y + 0.5, z + 0.5, eSoundType_FIRE_IGNITE, - 1, random->nextFloat() * 0.4f + 0.8f); - level->setTile(x, y, z, Tile::fire_Id); + level->playSound(x + 0.5, y + 0.5, z + 0.5, + eSoundType_FIRE_NEWIGNITE, 1, + random->nextFloat() * 0.4f + 0.8f); + level->setTileAndUpdate(x, y, z, Tile::fire_Id); } - instance->hurt(1, player); + instance->hurtAndBreak(1, player); } else { if (targetType == 0) { return true; diff --git a/Minecraft.World/Items/FoodItem.cpp b/Minecraft.World/Items/FoodItem.cpp index 520fa2c77..372424aea 100644 --- a/Minecraft.World/Items/FoodItem.cpp +++ b/Minecraft.World/Items/FoodItem.cpp @@ -42,8 +42,8 @@ std::shared_ptr FoodItem::useTimeDepleted( instance->count--; player->getFoodData()->eat(this); // 4J - new sound brought forward from 1.2.3 - level->playSound(player, eSoundType_RANDOM_BURP, 0.5f, - level->random->nextFloat() * 0.1f + 0.9f); + level->playEntitySound(player, eSoundType_RANDOM_BURP, 0.5f, + level->random->nextFloat() * 0.1f + 0.9f); addEatEffect(instance, level, player); diff --git a/Minecraft.World/Items/GoldenAppleItem.cpp b/Minecraft.World/Items/GoldenAppleItem.cpp index 77e8efbb9..904ce7322 100644 --- a/Minecraft.World/Items/GoldenAppleItem.cpp +++ b/Minecraft.World/Items/GoldenAppleItem.cpp @@ -26,11 +26,16 @@ const Rarity* GoldenAppleItem::getRarity( void GoldenAppleItem::addEatEffect(std::shared_ptr instance, Level* level, std::shared_ptr player) { + if (!level->isClientSide) + player->addEffect(new MobEffectInstance( + MobEffect::absorption->id, + 2 * 60 * SharedConstants::TICKS_PER_SECOND, 0)); + if (instance->getAuxValue() > 0) { if (!level->isClientSide) { player->addEffect(new MobEffectInstance( MobEffect::regeneration->id, - 30 * SharedConstants::TICKS_PER_SECOND, 3)); + 30 * SharedConstants::TICKS_PER_SECOND, 4)); player->addEffect(new MobEffectInstance( MobEffect::damageResistance->id, 300 * SharedConstants::TICKS_PER_SECOND, 0)); diff --git a/Minecraft.World/Items/HangingEntityItem.cpp b/Minecraft.World/Items/HangingEntityItem.cpp index baf1571b7..fe4367f2f 100644 --- a/Minecraft.World/Items/HangingEntityItem.cpp +++ b/Minecraft.World/Items/HangingEntityItem.cpp @@ -3,6 +3,7 @@ #include "../Headers/net.minecraft.world.phys.h" #include "../Headers/net.minecraft.world.damagesource.h" #include "../Headers/net.minecraft.world.level.tile.h" +#include "../Headers/net.minecraft.world.item.h" #include "../Headers/net.minecraft.world.level.h" #include "HangingEntityItem.h" #include "../Entities/HangingEntity.h" @@ -12,10 +13,7 @@ HangingEntityItem::HangingEntityItem(int id, eINSTANCEOF eClassType) : Item(id) { - // super(id); - // this.clazz = clazz; this->eType = eClassType; - // setItemCategory(CreativeModeTab.TAB_DECORATIONS); } bool HangingEntityItem::useOn(std::shared_ptr instance, @@ -26,7 +24,7 @@ bool HangingEntityItem::useOn(std::shared_ptr instance, if (face == Facing::UP) return false; if (bTestOnly) { - if (!player->mayBuild(xt, yt, zt)) return false; + if (!player->mayUseItemAt(xt, yt, zt, face, instance)) return false; return true; } @@ -34,10 +32,9 @@ bool HangingEntityItem::useOn(std::shared_ptr instance, int dir = Direction::FACING_DIRECTION[face]; std::shared_ptr entity = - createEntity(level, xt, yt, zt, dir); + createEntity(level, xt, yt, zt, dir, instance->getAuxValue()); - // if (!player->mayUseItemAt(xt, yt, zt, face, instance)) return false; - if (!player->mayBuild(xt, yt, zt)) return false; + if (!player->mayUseItemAt(xt, yt, zt, face, instance)) return false; if (entity != NULL && entity->survives()) { if (!level->isClientSide) { @@ -66,13 +63,22 @@ bool HangingEntityItem::useOn(std::shared_ptr instance, return true; } -std::shared_ptr HangingEntityItem::createEntity(Level* level, - int x, int y, - int z, int dir) { +std::shared_ptr HangingEntityItem::createEntity( + Level* level, int x, int y, int z, int dir, + int auxValue) // 4J added auxValue +{ if (eType == eTYPE_PAINTING) { std::shared_ptr painting = std::shared_ptr(new Painting(level, x, y, z, dir)); - painting->PaintingPostConstructor(dir); + +#ifndef _CONTENT_PACKAGE + if (app.DebugArtToolsOn() && auxValue > 0) { + painting->PaintingPostConstructor(dir, auxValue - 1); + } else +#endif + { + painting->PaintingPostConstructor(dir); + } return std::dynamic_pointer_cast(painting); } else if (eType == eTYPE_ITEM_FRAME) { @@ -84,3 +90,29 @@ std::shared_ptr HangingEntityItem::createEntity(Level* level, return nullptr; } } + +// 4J Adding overrides for art tools +void HangingEntityItem::appendHoverText( + std::shared_ptr itemInstance, std::shared_ptr player, + std::vector* lines, bool advanced) { +#ifndef _CONTENT_PACKAGE + if (eType == eTYPE_PAINTING && app.DebugArtToolsOn() && + itemInstance->getAuxValue() > 0) { + int motive = itemInstance->getAuxValue() - 1; + + wchar_t formatted[256]; + ZeroMemory(formatted, 256 * sizeof(wchar_t)); + swprintf(formatted, 256, L"** %ls %dx%d", + Painting::Motive::values[motive]->name.c_str(), + Painting::Motive::values[motive]->w / 16, + Painting::Motive::values[motive]->h / 16); + + std::wstring motiveName = formatted; + + lines->push_back(HtmlString(motiveName.c_str(), eHTMLColor_c)); + } else +#endif + { + return Item::appendHoverText(itemInstance, player, lines, advanced); + } +} \ No newline at end of file diff --git a/Minecraft.World/Items/HangingEntityItem.h b/Minecraft.World/Items/HangingEntityItem.h index ad48ecd2f..7be0517b7 100644 --- a/Minecraft.World/Items/HangingEntityItem.h +++ b/Minecraft.World/Items/HangingEntityItem.h @@ -19,6 +19,12 @@ public: bool bTestUseOnOnly); //, float clickX, float clickY, float clickZ); private: - std::shared_ptr createEntity(Level* level, int x, int y, - int z, int dir); + std::shared_ptr createEntity( + Level* level, int x, int y, int z, int dir, + int auxValue); // 4J Stu added auxValue param + +public: + virtual void appendHoverText(std::shared_ptr itemInstance, + std::shared_ptr player, + std::vector* lines, bool advanced); }; diff --git a/Minecraft.World/Items/HatchetItem.cpp b/Minecraft.World/Items/HatchetItem.cpp index a4bb36c58..a91931373 100644 --- a/Minecraft.World/Items/HatchetItem.cpp +++ b/Minecraft.World/Items/HatchetItem.cpp @@ -23,7 +23,9 @@ HatchetItem::HatchetItem(int id, const Tier* tier) // 4J - brought forward from 1.2.3 float HatchetItem::getDestroySpeed(std::shared_ptr itemInstance, Tile* tile) { - if (tile != NULL && tile->material == Material::wood) { + if (tile != NULL && (tile->material == Material::wood || + tile->material == Material::plant || + tile->material == Material::replaceable_plant)) { return speed; } return DiggerItem::getDestroySpeed(itemInstance, tile); diff --git a/Minecraft.World/Items/HoeItem.cpp b/Minecraft.World/Items/HoeItem.cpp index 8e1e9f059..d23a61027 100644 --- a/Minecraft.World/Items/HoeItem.cpp +++ b/Minecraft.World/Items/HoeItem.cpp @@ -15,15 +15,13 @@ bool HoeItem::useOn(std::shared_ptr instance, std::shared_ptr player, Level* level, int x, int y, int z, int face, float clickX, float clickY, float clickZ, bool bTestUseOnOnly) { - if (!player->mayBuild(x, y, z)) return false; + if (!player->mayUseItemAt(x, y, z, face, instance)) return false; // 4J-PB - Adding a test only version to allow tooltips to be displayed int targetType = level->getTile(x, y, z); - // Material above = level.getMaterial(x, y + 1, z); int above = level->getTile(x, y + 1, z); - // 4J-PB - missing parentheses if (face != 0 && above == 0 && (targetType == Tile::grass_Id || targetType == Tile::dirt_Id)) { if (!bTestUseOnOnly) { @@ -34,8 +32,8 @@ bool HoeItem::useOn(std::shared_ptr instance, tile->soundType->getPitch() * 0.8f); if (level->isClientSide) return true; - level->setTile(x, y, z, tile->id); - instance->hurt(1, player); + level->setTileAndUpdate(x, y, z, tile->id); + instance->hurtAndBreak(1, player); } return true; } diff --git a/Minecraft.World/Items/Item.cpp b/Minecraft.World/Items/Item.cpp index 756d12afd..42df7d827 100644 --- a/Minecraft.World/Items/Item.cpp +++ b/Minecraft.World/Items/Item.cpp @@ -14,9 +14,13 @@ #include "MapItem.h" #include "Item.h" #include "HangingEntityItem.h" +#include "../Util/HtmlString.h" typedef Item::Tier _Tier; +// const UUID Item::BASE_ATTACK_DAMAGE_UUID = +// UUID::fromString(L"CB3F55D3-645C-4F38-A497-9C13A33DB5CF"); + std::wstring Item::ICON_DESCRIPTION_PREFIX = L"item."; const _Tier* _Tier::WOOD = new _Tier(0, 59, 2, 0, 15); // @@ -68,7 +72,7 @@ Item* Item::hatchet_gold = NULL; Item* Item::string = NULL; Item* Item::feather = NULL; -Item* Item::sulphur = NULL; +Item* Item::gunpowder = NULL; Item* Item::hoe_wood = NULL; Item* Item::hoe_stone = NULL; @@ -80,10 +84,10 @@ Item* Item::seeds_wheat = NULL; Item* Item::wheat = NULL; Item* Item::bread = NULL; -ArmorItem* Item::helmet_cloth = NULL; -ArmorItem* Item::chestplate_cloth = NULL; -ArmorItem* Item::leggings_cloth = NULL; -ArmorItem* Item::boots_cloth = NULL; +ArmorItem* Item::helmet_leather = NULL; +ArmorItem* Item::chestplate_leather = NULL; +ArmorItem* Item::leggings_leather = NULL; +ArmorItem* Item::boots_leather = NULL; ArmorItem* Item::helmet_chain = NULL; ArmorItem* Item::chestplate_chain = NULL; @@ -128,7 +132,7 @@ Item* Item::snowBall = NULL; Item* Item::boat = NULL; Item* Item::leather = NULL; -Item* Item::milk = NULL; +Item* Item::bucket_milk = NULL; Item* Item::brick = NULL; Item* Item::clay = NULL; Item* Item::reeds = NULL; @@ -152,7 +156,7 @@ Item* Item::cake = NULL; Item* Item::bed = NULL; -Item* Item::diode = NULL; +Item* Item::repeater = NULL; Item* Item::cookie = NULL; MapItem* Item::map = NULL; @@ -188,7 +192,7 @@ Item* Item::enderPearl = NULL; Item* Item::blazeRod = NULL; Item* Item::ghastTear = NULL; Item* Item::goldNugget = NULL; -Item* Item::netherStalkSeeds = NULL; +Item* Item::netherwart_seeds = NULL; PotionItem* Item::potion = NULL; Item* Item::glassBottle = NULL; Item* Item::spiderEye = NULL; @@ -200,14 +204,13 @@ Item* Item::cauldron = NULL; Item* Item::eyeOfEnder = NULL; Item* Item::speckledMelon = NULL; -Item* Item::monsterPlacer = NULL; +Item* Item::spawnEgg = NULL; Item* Item::expBottle = NULL; // TU9 Item* Item::fireball = NULL; Item* Item::frame = NULL; -Item* Item::netherbrick = NULL; Item* Item::skull = NULL; @@ -224,189 +227,205 @@ Item* Item::potato = NULL; Item* Item::potatoBaked = NULL; Item* Item::potatoPoisonous = NULL; +EmptyMapItem* Item::emptyMap = NULL; + Item* Item::carrotGolden = NULL; Item* Item::carrotOnAStick = NULL; +Item* Item::netherStar = NULL; Item* Item::pumpkinPie = NULL; +Item* Item::fireworks = NULL; +Item* Item::fireworksCharge = NULL; EnchantedBookItem* Item::enchantedBook = NULL; + +Item* Item::comparator = NULL; +Item* Item::netherbrick = NULL; Item* Item::netherQuartz = NULL; +Item* Item::minecart_tnt = NULL; +Item* Item::minecart_hopper = NULL; + +Item* Item::horseArmorMetal = NULL; +Item* Item::horseArmorGold = NULL; +Item* Item::horseArmorDiamond = NULL; +Item* Item::lead = NULL; +Item* Item::nameTag = NULL; void Item::staticCtor() { Item::sword_wood = (new WeaponItem(12, _Tier::WOOD)) ->setBaseItemTypeAndMaterial(eBaseItemType_sword, eMaterial_wood) - ->setTextureName(L"swordWood") + ->setIconName(L"swordWood") ->setDescriptionId(IDS_ITEM_SWORD_WOOD) ->setUseDescriptionId(IDS_DESC_SWORD); Item::sword_stone = (new WeaponItem(16, _Tier::STONE)) ->setBaseItemTypeAndMaterial(eBaseItemType_sword, eMaterial_stone) - ->setTextureName(L"swordStone") + ->setIconName(L"swordStone") ->setDescriptionId(IDS_ITEM_SWORD_STONE) ->setUseDescriptionId(IDS_DESC_SWORD); Item::sword_iron = (new WeaponItem(11, _Tier::IRON)) ->setBaseItemTypeAndMaterial(eBaseItemType_sword, eMaterial_iron) - ->setTextureName(L"swordIron") + ->setIconName(L"swordIron") ->setDescriptionId(IDS_ITEM_SWORD_IRON) ->setUseDescriptionId(IDS_DESC_SWORD); Item::sword_diamond = (new WeaponItem(20, _Tier::DIAMOND)) ->setBaseItemTypeAndMaterial(eBaseItemType_sword, eMaterial_diamond) - ->setTextureName(L"swordDiamond") + ->setIconName(L"swordDiamond") ->setDescriptionId(IDS_ITEM_SWORD_DIAMOND) ->setUseDescriptionId(IDS_DESC_SWORD); Item::sword_gold = (new WeaponItem(27, _Tier::GOLD)) ->setBaseItemTypeAndMaterial(eBaseItemType_sword, eMaterial_gold) - ->setTextureName(L"swordGold") + ->setIconName(L"swordGold") ->setDescriptionId(IDS_ITEM_SWORD_GOLD) ->setUseDescriptionId(IDS_DESC_SWORD); Item::shovel_wood = (new ShovelItem(13, _Tier::WOOD)) ->setBaseItemTypeAndMaterial(eBaseItemType_shovel, eMaterial_wood) - ->setTextureName(L"shovelWood") + ->setIconName(L"shovelWood") ->setDescriptionId(IDS_ITEM_SHOVEL_WOOD) ->setUseDescriptionId(IDS_DESC_SHOVEL); Item::shovel_stone = (new ShovelItem(17, _Tier::STONE)) ->setBaseItemTypeAndMaterial(eBaseItemType_shovel, eMaterial_stone) - ->setTextureName(L"shovelStone") + ->setIconName(L"shovelStone") ->setDescriptionId(IDS_ITEM_SHOVEL_STONE) ->setUseDescriptionId(IDS_DESC_SHOVEL); Item::shovel_iron = (new ShovelItem(0, _Tier::IRON)) ->setBaseItemTypeAndMaterial(eBaseItemType_shovel, eMaterial_iron) - ->setTextureName(L"shovelIron") + ->setIconName(L"shovelIron") ->setDescriptionId(IDS_ITEM_SHOVEL_IRON) ->setUseDescriptionId(IDS_DESC_SHOVEL); Item::shovel_diamond = (new ShovelItem(21, _Tier::DIAMOND)) ->setBaseItemTypeAndMaterial( eBaseItemType_shovel, eMaterial_diamond) - ->setTextureName(L"shovelDiamond") + ->setIconName(L"shovelDiamond") ->setDescriptionId(IDS_ITEM_SHOVEL_DIAMOND) ->setUseDescriptionId(IDS_DESC_SHOVEL); Item::shovel_gold = (new ShovelItem(28, _Tier::GOLD)) ->setBaseItemTypeAndMaterial(eBaseItemType_shovel, eMaterial_gold) - ->setTextureName(L"shovelGold") + ->setIconName(L"shovelGold") ->setDescriptionId(IDS_ITEM_SHOVEL_GOLD) ->setUseDescriptionId(IDS_DESC_SHOVEL); Item::pickAxe_wood = (new PickaxeItem(14, _Tier::WOOD)) ->setBaseItemTypeAndMaterial(eBaseItemType_pickaxe, eMaterial_wood) - ->setTextureName(L"pickaxeWood") + ->setIconName(L"pickaxeWood") ->setDescriptionId(IDS_ITEM_PICKAXE_WOOD) ->setUseDescriptionId(IDS_DESC_PICKAXE); Item::pickAxe_stone = (new PickaxeItem(18, _Tier::STONE)) ->setBaseItemTypeAndMaterial(eBaseItemType_pickaxe, eMaterial_stone) - ->setTextureName(L"pickaxeStone") + ->setIconName(L"pickaxeStone") ->setDescriptionId(IDS_ITEM_PICKAXE_STONE) ->setUseDescriptionId(IDS_DESC_PICKAXE); Item::pickAxe_iron = (new PickaxeItem(1, _Tier::IRON)) ->setBaseItemTypeAndMaterial(eBaseItemType_pickaxe, eMaterial_iron) - ->setTextureName(L"pickaxeIron") + ->setIconName(L"pickaxeIron") ->setDescriptionId(IDS_ITEM_PICKAXE_IRON) ->setUseDescriptionId(IDS_DESC_PICKAXE); Item::pickAxe_diamond = (new PickaxeItem(22, _Tier::DIAMOND)) ->setBaseItemTypeAndMaterial( eBaseItemType_pickaxe, eMaterial_diamond) - ->setTextureName(L"pickaxeDiamond") + ->setIconName(L"pickaxeDiamond") ->setDescriptionId(IDS_ITEM_PICKAXE_DIAMOND) ->setUseDescriptionId(IDS_DESC_PICKAXE); Item::pickAxe_gold = (new PickaxeItem(29, _Tier::GOLD)) ->setBaseItemTypeAndMaterial(eBaseItemType_pickaxe, eMaterial_gold) - ->setTextureName(L"pickaxeGold") + ->setIconName(L"pickaxeGold") ->setDescriptionId(IDS_ITEM_PICKAXE_GOLD) ->setUseDescriptionId(IDS_DESC_PICKAXE); Item::hatchet_wood = (new HatchetItem(15, _Tier::WOOD)) ->setBaseItemTypeAndMaterial(eBaseItemType_hatchet, eMaterial_wood) - ->setTextureName(L"hatchetWood") + ->setIconName(L"hatchetWood") ->setDescriptionId(IDS_ITEM_HATCHET_WOOD) ->setUseDescriptionId(IDS_DESC_HATCHET); Item::hatchet_stone = (new HatchetItem(19, _Tier::STONE)) ->setBaseItemTypeAndMaterial(eBaseItemType_hatchet, eMaterial_stone) - ->setTextureName(L"hatchetStone") + ->setIconName(L"hatchetStone") ->setDescriptionId(IDS_ITEM_HATCHET_STONE) ->setUseDescriptionId(IDS_DESC_HATCHET); Item::hatchet_iron = (new HatchetItem(2, _Tier::IRON)) ->setBaseItemTypeAndMaterial(eBaseItemType_hatchet, eMaterial_iron) - ->setTextureName(L"hatchetIron") + ->setIconName(L"hatchetIron") ->setDescriptionId(IDS_ITEM_HATCHET_IRON) ->setUseDescriptionId(IDS_DESC_HATCHET); Item::hatchet_diamond = (new HatchetItem(23, _Tier::DIAMOND)) ->setBaseItemTypeAndMaterial( eBaseItemType_hatchet, eMaterial_diamond) - ->setTextureName(L"hatchetDiamond") + ->setIconName(L"hatchetDiamond") ->setDescriptionId(IDS_ITEM_HATCHET_DIAMOND) ->setUseDescriptionId(IDS_DESC_HATCHET); Item::hatchet_gold = (new HatchetItem(30, _Tier::GOLD)) ->setBaseItemTypeAndMaterial(eBaseItemType_hatchet, eMaterial_gold) - ->setTextureName(L"hatchetGold") + ->setIconName(L"hatchetGold") ->setDescriptionId(IDS_ITEM_HATCHET_GOLD) ->setUseDescriptionId(IDS_DESC_HATCHET); Item::hoe_wood = (new HoeItem(34, _Tier::WOOD)) ->setBaseItemTypeAndMaterial(eBaseItemType_hoe, eMaterial_wood) - ->setTextureName(L"hoeWood") + ->setIconName(L"hoeWood") ->setDescriptionId(IDS_ITEM_HOE_WOOD) ->setUseDescriptionId(IDS_DESC_HOE); Item::hoe_stone = (new HoeItem(35, _Tier::STONE)) ->setBaseItemTypeAndMaterial(eBaseItemType_hoe, eMaterial_stone) - ->setTextureName(L"hoeStone") + ->setIconName(L"hoeStone") ->setDescriptionId(IDS_ITEM_HOE_STONE) ->setUseDescriptionId(IDS_DESC_HOE); Item::hoe_iron = (new HoeItem(36, _Tier::IRON)) ->setBaseItemTypeAndMaterial(eBaseItemType_hoe, eMaterial_iron) - ->setTextureName(L"hoeIron") + ->setIconName(L"hoeIron") ->setDescriptionId(IDS_ITEM_HOE_IRON) ->setUseDescriptionId(IDS_DESC_HOE); Item::hoe_diamond = (new HoeItem(37, _Tier::DIAMOND)) ->setBaseItemTypeAndMaterial(eBaseItemType_hoe, eMaterial_diamond) - ->setTextureName(L"hoeDiamond") + ->setIconName(L"hoeDiamond") ->setDescriptionId(IDS_ITEM_HOE_DIAMOND) ->setUseDescriptionId(IDS_DESC_HOE); Item::hoe_gold = (new HoeItem(38, _Tier::GOLD)) ->setBaseItemTypeAndMaterial(eBaseItemType_hoe, eMaterial_gold) - ->setTextureName(L"hoeGold") + ->setIconName(L"hoeGold") ->setDescriptionId(IDS_ITEM_HOE_GOLD) ->setUseDescriptionId(IDS_DESC_HOE); Item::door_wood = (new DoorItem(68, Material::wood)) ->setBaseItemTypeAndMaterial(eBaseItemType_door, eMaterial_wood) - ->setTextureName(L"doorWood") + ->setIconName(L"doorWood") ->setDescriptionId(IDS_ITEM_DOOR_WOOD) ->setUseDescriptionId(IDS_DESC_DOOR_WOOD); Item::door_iron = (new DoorItem(74, Material::metal)) ->setBaseItemTypeAndMaterial(eBaseItemType_door, eMaterial_iron) - ->setTextureName(L"doorIron") + ->setIconName(L"doorIron") ->setDescriptionId(IDS_ITEM_DOOR_IRON) ->setUseDescriptionId(IDS_DESC_DOOR_IRON); - Item::helmet_cloth = + Item::helmet_leather = (ArmorItem*)((new ArmorItem(42, ArmorItem::ArmorMaterial::CLOTH, 0, ArmorItem::SLOT_HEAD)) ->setBaseItemTypeAndMaterial(eBaseItemType_helmet, eMaterial_cloth) - ->setTextureName(L"helmetCloth") + ->setIconName(L"helmetCloth") ->setDescriptionId(IDS_ITEM_HELMET_CLOTH) ->setUseDescriptionId(IDS_DESC_HELMET_LEATHER)); Item::helmet_iron = @@ -414,7 +433,7 @@ void Item::staticCtor() { ArmorItem::SLOT_HEAD)) ->setBaseItemTypeAndMaterial(eBaseItemType_helmet, eMaterial_iron) - ->setTextureName(L"helmetIron") + ->setIconName(L"helmetIron") ->setDescriptionId(IDS_ITEM_HELMET_IRON) ->setUseDescriptionId(IDS_DESC_HELMET_IRON)); Item::helmet_diamond = @@ -422,7 +441,7 @@ void Item::staticCtor() { ArmorItem::SLOT_HEAD)) ->setBaseItemTypeAndMaterial(eBaseItemType_helmet, eMaterial_diamond) - ->setTextureName(L"helmetDiamond") + ->setIconName(L"helmetDiamond") ->setDescriptionId(IDS_ITEM_HELMET_DIAMOND) ->setUseDescriptionId(IDS_DESC_HELMET_DIAMOND)); Item::helmet_gold = @@ -430,16 +449,16 @@ void Item::staticCtor() { ArmorItem::SLOT_HEAD)) ->setBaseItemTypeAndMaterial(eBaseItemType_helmet, eMaterial_gold) - ->setTextureName(L"helmetGold") + ->setIconName(L"helmetGold") ->setDescriptionId(IDS_ITEM_HELMET_GOLD) ->setUseDescriptionId(IDS_DESC_HELMET_GOLD)); - Item::chestplate_cloth = + Item::chestplate_leather = (ArmorItem*)((new ArmorItem(43, ArmorItem::ArmorMaterial::CLOTH, 0, ArmorItem::SLOT_TORSO)) ->setBaseItemTypeAndMaterial(eBaseItemType_chestplate, eMaterial_cloth) - ->setTextureName(L"chestplateCloth") + ->setIconName(L"chestplateCloth") ->setDescriptionId(IDS_ITEM_CHESTPLATE_CLOTH) ->setUseDescriptionId(IDS_DESC_CHESTPLATE_LEATHER)); Item::chestplate_iron = @@ -447,7 +466,7 @@ void Item::staticCtor() { ArmorItem::SLOT_TORSO)) ->setBaseItemTypeAndMaterial(eBaseItemType_chestplate, eMaterial_iron) - ->setTextureName(L"chestplateIron") + ->setIconName(L"chestplateIron") ->setDescriptionId(IDS_ITEM_CHESTPLATE_IRON) ->setUseDescriptionId(IDS_DESC_CHESTPLATE_IRON)); Item::chestplate_diamond = @@ -455,7 +474,7 @@ void Item::staticCtor() { ArmorItem::SLOT_TORSO)) ->setBaseItemTypeAndMaterial(eBaseItemType_chestplate, eMaterial_diamond) - ->setTextureName(L"chestplateDiamond") + ->setIconName(L"chestplateDiamond") ->setDescriptionId(IDS_ITEM_CHESTPLATE_DIAMOND) ->setUseDescriptionId(IDS_DESC_CHESTPLATE_DIAMOND)); Item::chestplate_gold = @@ -463,16 +482,16 @@ void Item::staticCtor() { ArmorItem::SLOT_TORSO)) ->setBaseItemTypeAndMaterial(eBaseItemType_chestplate, eMaterial_gold) - ->setTextureName(L"chestplateGold") + ->setIconName(L"chestplateGold") ->setDescriptionId(IDS_ITEM_CHESTPLATE_GOLD) ->setUseDescriptionId(IDS_DESC_CHESTPLATE_GOLD)); - Item::leggings_cloth = + Item::leggings_leather = (ArmorItem*)((new ArmorItem(44, ArmorItem::ArmorMaterial::CLOTH, 0, ArmorItem::SLOT_LEGS)) ->setBaseItemTypeAndMaterial(eBaseItemType_leggings, eMaterial_cloth) - ->setTextureName(L"leggingsCloth") + ->setIconName(L"leggingsCloth") ->setDescriptionId(IDS_ITEM_LEGGINGS_CLOTH) ->setUseDescriptionId(IDS_DESC_LEGGINGS_LEATHER)); Item::leggings_iron = @@ -480,7 +499,7 @@ void Item::staticCtor() { ArmorItem::SLOT_LEGS)) ->setBaseItemTypeAndMaterial(eBaseItemType_leggings, eMaterial_iron) - ->setTextureName(L"leggingsIron") + ->setIconName(L"leggingsIron") ->setDescriptionId(IDS_ITEM_LEGGINGS_IRON) ->setUseDescriptionId(IDS_DESC_LEGGINGS_IRON)); Item::leggings_diamond = @@ -488,7 +507,7 @@ void Item::staticCtor() { ArmorItem::SLOT_LEGS)) ->setBaseItemTypeAndMaterial(eBaseItemType_leggings, eMaterial_diamond) - ->setTextureName(L"leggingsDiamond") + ->setIconName(L"leggingsDiamond") ->setDescriptionId(IDS_ITEM_LEGGINGS_DIAMOND) ->setUseDescriptionId(IDS_DESC_LEGGINGS_DIAMOND)); Item::leggings_gold = @@ -496,7 +515,7 @@ void Item::staticCtor() { ArmorItem::SLOT_LEGS)) ->setBaseItemTypeAndMaterial(eBaseItemType_leggings, eMaterial_gold) - ->setTextureName(L"leggingsGold") + ->setIconName(L"leggingsGold") ->setDescriptionId(IDS_ITEM_LEGGINGS_GOLD) ->setUseDescriptionId(IDS_DESC_LEGGINGS_GOLD)); @@ -505,7 +524,7 @@ void Item::staticCtor() { ArmorItem::SLOT_HEAD)) ->setBaseItemTypeAndMaterial(eBaseItemType_helmet, eMaterial_chain) - ->setTextureName(L"helmetChain") + ->setIconName(L"helmetChain") ->setDescriptionId(IDS_ITEM_HELMET_CHAIN) ->setUseDescriptionId(IDS_DESC_HELMET_CHAIN)); Item::chestplate_chain = @@ -513,7 +532,7 @@ void Item::staticCtor() { ArmorItem::SLOT_TORSO)) ->setBaseItemTypeAndMaterial(eBaseItemType_chestplate, eMaterial_chain) - ->setTextureName(L"chestplateChain") + ->setIconName(L"chestplateChain") ->setDescriptionId(IDS_ITEM_CHESTPLATE_CHAIN) ->setUseDescriptionId(IDS_DESC_CHESTPLATE_CHAIN)); Item::leggings_chain = @@ -521,7 +540,7 @@ void Item::staticCtor() { ArmorItem::SLOT_LEGS)) ->setBaseItemTypeAndMaterial(eBaseItemType_leggings, eMaterial_chain) - ->setTextureName(L"leggingsChain") + ->setIconName(L"leggingsChain") ->setDescriptionId(IDS_ITEM_LEGGINGS_CHAIN) ->setUseDescriptionId(IDS_DESC_LEGGINGS_CHAIN)); Item::boots_chain = @@ -529,16 +548,16 @@ void Item::staticCtor() { ArmorItem::SLOT_FEET)) ->setBaseItemTypeAndMaterial(eBaseItemType_boots, eMaterial_chain) - ->setTextureName(L"bootsChain") + ->setIconName(L"bootsChain") ->setDescriptionId(IDS_ITEM_BOOTS_CHAIN) ->setUseDescriptionId(IDS_DESC_BOOTS_CHAIN)); - Item::boots_cloth = + Item::boots_leather = (ArmorItem*)((new ArmorItem(45, ArmorItem::ArmorMaterial::CLOTH, 0, ArmorItem::SLOT_FEET)) ->setBaseItemTypeAndMaterial(eBaseItemType_boots, eMaterial_cloth) - ->setTextureName(L"bootsCloth") + ->setIconName(L"bootsCloth") ->setDescriptionId(IDS_ITEM_BOOTS_CLOTH) ->setUseDescriptionId(IDS_DESC_BOOTS_LEATHER)); Item::boots_iron = @@ -546,7 +565,7 @@ void Item::staticCtor() { ArmorItem::SLOT_FEET)) ->setBaseItemTypeAndMaterial(eBaseItemType_boots, eMaterial_iron) - ->setTextureName(L"bootsIron") + ->setIconName(L"bootsIron") ->setDescriptionId(IDS_ITEM_BOOTS_IRON) ->setUseDescriptionId(IDS_DESC_BOOTS_IRON)); Item::boots_diamond = @@ -554,7 +573,7 @@ void Item::staticCtor() { ArmorItem::SLOT_FEET)) ->setBaseItemTypeAndMaterial(eBaseItemType_boots, eMaterial_diamond) - ->setTextureName(L"bootsDiamond") + ->setIconName(L"bootsDiamond") ->setDescriptionId(IDS_ITEM_BOOTS_DIAMOND) ->setUseDescriptionId(IDS_DESC_BOOTS_DIAMOND)); Item::boots_gold = @@ -562,19 +581,19 @@ void Item::staticCtor() { ArmorItem::SLOT_FEET)) ->setBaseItemTypeAndMaterial(eBaseItemType_boots, eMaterial_gold) - ->setTextureName(L"bootsGold") + ->setIconName(L"bootsGold") ->setDescriptionId(IDS_ITEM_BOOTS_GOLD) ->setUseDescriptionId(IDS_DESC_BOOTS_GOLD)); Item::ironIngot = (new Item(9)) - ->setTextureName(L"ingotIron") + ->setIconName(L"ingotIron") ->setBaseItemTypeAndMaterial(eBaseItemType_treasure, eMaterial_iron) ->setDescriptionId(IDS_ITEM_INGOT_IRON) ->setUseDescriptionId(IDS_DESC_INGOT); Item::goldIngot = (new Item(10)) - ->setTextureName(L"ingotGold") + ->setIconName(L"ingotGold") ->setBaseItemTypeAndMaterial(eBaseItemType_treasure, eMaterial_gold) ->setDescriptionId(IDS_ITEM_INGOT_GOLD) ->setUseDescriptionId(IDS_DESC_INGOT); @@ -583,61 +602,61 @@ void Item::staticCtor() { Item::bucket_empty = (new BucketItem(69, 0)) ->setBaseItemTypeAndMaterial(eBaseItemType_utensil, eMaterial_water) - ->setTextureName(L"bucket") + ->setIconName(L"bucket") ->setDescriptionId(IDS_ITEM_BUCKET) ->setUseDescriptionId(IDS_DESC_BUCKET) ->setMaxStackSize(16); Item::bowl = (new Item(25)) ->setBaseItemTypeAndMaterial(eBaseItemType_utensil, eMaterial_wood) - ->setTextureName(L"bowl") + ->setIconName(L"bowl") ->setDescriptionId(IDS_ITEM_BOWL) ->setUseDescriptionId(IDS_DESC_BOWL) ->setMaxStackSize(64); Item::bucket_water = (new BucketItem(70, Tile::water_Id)) - ->setTextureName(L"bucketWater") + ->setIconName(L"bucketWater") ->setDescriptionId(IDS_ITEM_BUCKET_WATER) ->setCraftingRemainingItem(Item::bucket_empty) ->setUseDescriptionId(IDS_DESC_BUCKET_WATER); Item::bucket_lava = (new BucketItem(71, Tile::lava_Id)) - ->setTextureName(L"bucketLava") + ->setIconName(L"bucketLava") ->setDescriptionId(IDS_ITEM_BUCKET_LAVA) ->setCraftingRemainingItem(Item::bucket_empty) ->setUseDescriptionId(IDS_DESC_BUCKET_LAVA); - Item::milk = (new MilkBucketItem(79)) - ->setTextureName(L"milk") - ->setDescriptionId(IDS_ITEM_BUCKET_MILK) - ->setCraftingRemainingItem(Item::bucket_empty) - ->setUseDescriptionId(IDS_DESC_BUCKET_MILK); + Item::bucket_milk = (new MilkBucketItem(79)) + ->setIconName(L"milk") + ->setDescriptionId(IDS_ITEM_BUCKET_MILK) + ->setCraftingRemainingItem(Item::bucket_empty) + ->setUseDescriptionId(IDS_DESC_BUCKET_MILK); Item::bow = (BowItem*)(new BowItem(5)) - ->setTextureName(L"bow") + ->setIconName(L"bow") ->setBaseItemTypeAndMaterial(eBaseItemType_bow, eMaterial_bow) ->setDescriptionId(IDS_ITEM_BOW) ->setUseDescriptionId(IDS_DESC_BOW); Item::arrow = (new Item(6)) - ->setTextureName(L"arrow") + ->setIconName(L"arrow") ->setBaseItemTypeAndMaterial(eBaseItemType_bow, eMaterial_arrow) ->setDescriptionId(IDS_ITEM_ARROW) ->setUseDescriptionId(IDS_DESC_ARROW); Item::compass = (new CompassItem(89)) - ->setTextureName(L"compass") + ->setIconName(L"compass") ->setBaseItemTypeAndMaterial(eBaseItemType_pockettool, eMaterial_compass) ->setDescriptionId(IDS_ITEM_COMPASS) ->setUseDescriptionId(IDS_DESC_COMPASS); Item::clock = (new ClockItem(91)) - ->setTextureName(L"clock") + ->setIconName(L"clock") ->setBaseItemTypeAndMaterial(eBaseItemType_pockettool, eMaterial_clock) ->setDescriptionId(IDS_ITEM_CLOCK) ->setUseDescriptionId(IDS_DESC_CLOCK); Item::map = (MapItem*)(new MapItem(102)) - ->setTextureName(L"map") + ->setIconName(L"map") ->setBaseItemTypeAndMaterial(eBaseItemType_pockettool, eMaterial_map) ->setDescriptionId(IDS_ITEM_MAP) @@ -645,82 +664,87 @@ void Item::staticCtor() { Item::flintAndSteel = (new FlintAndSteelItem(3)) - ->setTextureName(L"flintAndSteel") + ->setIconName(L"flintAndSteel") ->setBaseItemTypeAndMaterial(eBaseItemType_devicetool, eMaterial_flintandsteel) ->setDescriptionId(IDS_ITEM_FLINT_AND_STEEL) ->setUseDescriptionId(IDS_DESC_FLINTANDSTEEL); Item::apple = (new FoodItem(4, 4, FoodConstants::FOOD_SATURATION_LOW, false)) - ->setTextureName(L"apple") + ->setIconName(L"apple") ->setDescriptionId(IDS_ITEM_APPLE) ->setUseDescriptionId(IDS_DESC_APPLE); - Item::coal = (new CoalItem(7)) - ->setTextureName(L"coal") - ->setDescriptionId(IDS_ITEM_COAL) - ->setUseDescriptionId(IDS_DESC_COAL); + Item::coal = + (new CoalItem(7)) + ->setBaseItemTypeAndMaterial(eBaseItemType_treasure, eMaterial_coal) + ->setIconName(L"coal") + ->setDescriptionId(IDS_ITEM_COAL) + ->setUseDescriptionId(IDS_DESC_COAL); Item::diamond = (new Item(8)) ->setBaseItemTypeAndMaterial(eBaseItemType_treasure, eMaterial_diamond) - ->setTextureName(L"diamond") + ->setIconName(L"diamond") ->setDescriptionId(IDS_ITEM_DIAMOND) ->setUseDescriptionId(IDS_DESC_DIAMONDS); Item::stick = (new Item(24)) - ->setTextureName(L"stick") + ->setIconName(L"stick") ->handEquipped() ->setDescriptionId(IDS_ITEM_STICK) ->setUseDescriptionId(IDS_DESC_STICK); Item::mushroomStew = (new BowlFoodItem(26, 6)) - ->setTextureName(L"mushroomStew") + ->setIconName(L"mushroomStew") ->setDescriptionId(IDS_ITEM_MUSHROOM_STEW) ->setUseDescriptionId(IDS_DESC_MUSHROOMSTEW); Item::string = (new TilePlanterItem(31, Tile::tripWire)) - ->setTextureName(L"string") + ->setIconName(L"string") ->setDescriptionId(IDS_ITEM_STRING) ->setUseDescriptionId(IDS_DESC_STRING); Item::feather = (new Item(32)) - ->setTextureName(L"feather") + ->setIconName(L"feather") ->setDescriptionId(IDS_ITEM_FEATHER) ->setUseDescriptionId(IDS_DESC_FEATHER); - Item::sulphur = (new Item(33)) - ->setTextureName(L"sulphur") - ->setDescriptionId(IDS_ITEM_SULPHUR) - ->setUseDescriptionId(IDS_DESC_SULPHUR) - ->setPotionBrewingFormula(PotionBrewing::MOD_GUNPOWDER); + Item::gunpowder = + (new Item(33)) + ->setIconName(L"sulphur") + ->setDescriptionId(IDS_ITEM_SULPHUR) + ->setUseDescriptionId(IDS_DESC_SULPHUR) + ->setPotionBrewingFormula(PotionBrewing::MOD_GUNPOWDER); - Item::seeds_wheat = (new SeedItem(39, Tile::crops_Id, Tile::farmland_Id)) - ->setTextureName(L"seeds") + Item::seeds_wheat = (new SeedItem(39, Tile::wheat_Id, Tile::farmland_Id)) + ->setIconName(L"seeds") ->setDescriptionId(IDS_ITEM_WHEAT_SEEDS) ->setUseDescriptionId(IDS_DESC_WHEAT_SEEDS); Item::wheat = (new Item(40)) - ->setTextureName(L"wheat") + ->setBaseItemTypeAndMaterial(eBaseItemType_treasure, + eMaterial_wheat) + ->setIconName(L"wheat") ->setDescriptionId(IDS_ITEM_WHEAT) ->setUseDescriptionId(IDS_DESC_WHEAT); Item::bread = (new FoodItem(41, 5, FoodConstants::FOOD_SATURATION_NORMAL, false)) - ->setTextureName(L"bread") + ->setIconName(L"bread") ->setDescriptionId(IDS_ITEM_BREAD) ->setUseDescriptionId(IDS_DESC_BREAD); Item::flint = (new Item(62)) - ->setTextureName(L"flint") + ->setIconName(L"flint") ->setDescriptionId(IDS_ITEM_FLINT) ->setUseDescriptionId(IDS_DESC_FLINT); Item::porkChop_raw = (new FoodItem(63, 3, FoodConstants::FOOD_SATURATION_LOW, true)) - ->setTextureName(L"porkchopRaw") + ->setIconName(L"porkchopRaw") ->setDescriptionId(IDS_ITEM_PORKCHOP_RAW) ->setUseDescriptionId(IDS_DESC_PORKCHOP_RAW); Item::porkChop_cooked = (new FoodItem(64, 8, FoodConstants::FOOD_SATURATION_GOOD, true)) - ->setTextureName(L"porkchopCooked") + ->setIconName(L"porkchopCooked") ->setDescriptionId(IDS_ITEM_PORKCHOP_COOKED) ->setUseDescriptionId(IDS_DESC_PORKCHOP_COOKED); Item::painting = (new HangingEntityItem(65, eTYPE_PAINTING)) ->setBaseItemTypeAndMaterial(eBaseItemType_HangingItem, eMaterial_cloth) - ->setTextureName(L"painting") + ->setIconName(L"painting") ->setDescriptionId(IDS_ITEM_PAINTING) ->setUseDescriptionId(IDS_DESC_PICTURE); @@ -728,122 +752,128 @@ void Item::staticCtor() { (new GoldenAppleItem(66, 4, FoodConstants::FOOD_SATURATION_SUPERNATURAL, false)) ->setCanAlwaysEat() - ->setEatEffect(MobEffect::regeneration->id, 5, 0, 1.0f) + ->setEatEffect(MobEffect::regeneration->id, 5, 1, 1.0f) ->setBaseItemTypeAndMaterial(eBaseItemType_giltFruit, eMaterial_apple) - ->setTextureName(L"appleGold") + ->setIconName(L"appleGold") ->setDescriptionId( IDS_ITEM_APPLE_GOLD); //->setUseDescriptionId(IDS_DESC_GOLDENAPPLE); Item::sign = (new SignItem(67)) ->setBaseItemTypeAndMaterial(eBaseItemType_HangingItem, eMaterial_wood) - ->setTextureName(L"sign") + ->setIconName(L"sign") ->setDescriptionId(IDS_ITEM_SIGN) ->setUseDescriptionId(IDS_DESC_SIGN); - Item::minecart = (new MinecartItem(72, Minecart::RIDEABLE)) - ->setTextureName(L"minecart") + Item::minecart = (new MinecartItem(72, Minecart::TYPE_RIDEABLE)) + ->setIconName(L"minecart") ->setDescriptionId(IDS_ITEM_MINECART) ->setUseDescriptionId(IDS_DESC_MINECART); Item::saddle = (new SaddleItem(73)) - ->setTextureName(L"saddle") + ->setIconName(L"saddle") ->setDescriptionId(IDS_ITEM_SADDLE) ->setUseDescriptionId(IDS_DESC_SADDLE); Item::redStone = (new RedStoneItem(75)) - ->setTextureName(L"redstone") + ->setBaseItemTypeAndMaterial(eBaseItemType_treasure, + eMaterial_redstone) + ->setIconName(L"redstone") ->setDescriptionId(IDS_ITEM_REDSTONE) ->setUseDescriptionId(IDS_DESC_REDSTONE_DUST) ->setPotionBrewingFormula(PotionBrewing::MOD_REDSTONE); Item::snowBall = (new SnowballItem(76)) - ->setTextureName(L"snowball") + ->setIconName(L"snowball") ->setDescriptionId(IDS_ITEM_SNOWBALL) ->setUseDescriptionId(IDS_DESC_SNOWBALL); Item::boat = (new BoatItem(77)) - ->setTextureName(L"boat") + ->setIconName(L"boat") ->setDescriptionId(IDS_ITEM_BOAT) ->setUseDescriptionId(IDS_DESC_BOAT); Item::leather = (new Item(78)) - ->setTextureName(L"leather") + ->setIconName(L"leather") ->setDescriptionId(IDS_ITEM_LEATHER) ->setUseDescriptionId(IDS_DESC_LEATHER); Item::brick = (new Item(80)) - ->setTextureName(L"brick") + ->setIconName(L"brick") ->setDescriptionId(IDS_ITEM_BRICK) ->setUseDescriptionId(IDS_DESC_BRICK); Item::clay = (new Item(81)) - ->setTextureName(L"clay") + ->setIconName(L"clay") ->setDescriptionId(IDS_ITEM_CLAY) ->setUseDescriptionId(IDS_DESC_CLAY); Item::reeds = (new TilePlanterItem(82, Tile::reeds)) - ->setTextureName(L"reeds") + ->setIconName(L"reeds") ->setDescriptionId(IDS_ITEM_REEDS) ->setUseDescriptionId(IDS_DESC_REEDS); Item::paper = (new Item(83)) - ->setTextureName(L"paper") + ->setBaseItemTypeAndMaterial(Item::eBaseItemType_paper, + Item::eMaterial_paper) + ->setIconName(L"paper") ->setDescriptionId(IDS_ITEM_PAPER) ->setUseDescriptionId(IDS_DESC_PAPER); Item::book = (new BookItem(84)) - ->setTextureName(L"book") + ->setBaseItemTypeAndMaterial(Item::eBaseItemType_paper, + Item::eMaterial_book) + ->setIconName(L"book") ->setDescriptionId(IDS_ITEM_BOOK) ->setUseDescriptionId(IDS_DESC_BOOK); Item::slimeBall = (new Item(85)) - ->setTextureName(L"slimeball") + ->setIconName(L"slimeball") ->setDescriptionId(IDS_ITEM_SLIMEBALL) ->setUseDescriptionId(IDS_DESC_SLIMEBALL); Item::minecart_chest = - (new MinecartItem(86, Minecart::CHEST)) - ->setTextureName(L"minecartChest") + (new MinecartItem(86, Minecart::TYPE_CHEST)) + ->setIconName(L"minecart_chest") ->setDescriptionId(IDS_ITEM_MINECART_CHEST) ->setUseDescriptionId(IDS_DESC_MINECARTWITHCHEST); Item::minecart_furnace = - (new MinecartItem(87, Minecart::FURNACE)) - ->setTextureName(L"minecartFurnace") + (new MinecartItem(87, Minecart::TYPE_FURNACE)) + ->setIconName(L"minecart_furnace") ->setDescriptionId(IDS_ITEM_MINECART_FURNACE) ->setUseDescriptionId(IDS_DESC_MINECARTWITHFURNACE); Item::egg = (new EggItem(88)) - ->setTextureName(L"egg") + ->setIconName(L"egg") ->setDescriptionId(IDS_ITEM_EGG) ->setUseDescriptionId(IDS_DESC_EGG); Item::fishingRod = (FishingRodItem*)(new FishingRodItem(90)) ->setBaseItemTypeAndMaterial(eBaseItemType_rod, eMaterial_wood) - ->setTextureName(L"fishingRod") + ->setIconName(L"fishingRod") ->setDescriptionId(IDS_ITEM_FISHING_ROD) ->setUseDescriptionId(IDS_DESC_FISHINGROD); Item::yellowDust = (new Item(92)) - ->setTextureName(L"yellowDust") + ->setIconName(L"yellowDust") ->setDescriptionId(IDS_ITEM_YELLOW_DUST) ->setUseDescriptionId(IDS_DESC_YELLOW_DUST) ->setPotionBrewingFormula(PotionBrewing::MOD_GLOWSTONE); Item::fish_raw = (new FoodItem(93, 2, FoodConstants::FOOD_SATURATION_LOW, false)) - ->setTextureName(L"fishRaw") + ->setIconName(L"fishRaw") ->setDescriptionId(IDS_ITEM_FISH_RAW) ->setUseDescriptionId(IDS_DESC_FISH_RAW); Item::fish_cooked = (new FoodItem(94, 5, FoodConstants::FOOD_SATURATION_NORMAL, false)) - ->setTextureName(L"fishCooked") + ->setIconName(L"fishCooked") ->setDescriptionId(IDS_ITEM_FISH_COOKED) ->setUseDescriptionId(IDS_DESC_FISH_COOKED); Item::dye_powder = (new DyePowderItem(95)) ->setBaseItemTypeAndMaterial(eBaseItemType_dyepowder, eMaterial_dye) - ->setTextureName(L"dyePowder") + ->setIconName(L"dyePowder") ->setDescriptionId(IDS_ITEM_DYE_POWDER) ->setUseDescriptionId(-1); Item::bone = (new Item(96)) - ->setTextureName(L"bone") + ->setIconName(L"bone") ->setDescriptionId(IDS_ITEM_BONE) ->handEquipped() ->setUseDescriptionId(IDS_DESC_BONE); Item::sugar = (new Item(97)) - ->setTextureName(L"sugar") + ->setIconName(L"sugar") ->setDescriptionId(IDS_ITEM_SUGAR) ->setUseDescriptionId(IDS_DESC_SUGAR) ->setPotionBrewingFormula(PotionBrewing::MOD_SUGAR); @@ -852,28 +882,28 @@ void Item::staticCtor() { // )->setMaxStackSize(1)->setIcon(13, // 1)->setDescriptionId(IDS_ITEM_CAKE)->setUseDescriptionId(IDS_DESC_CAKE); Item::cake = (new TilePlanterItem(98, Tile::cake)) - ->setTextureName(L"cake") + ->setIconName(L"cake") ->setDescriptionId(IDS_ITEM_CAKE) ->setUseDescriptionId(IDS_DESC_CAKE); Item::bed = (new BedItem(99)) ->setMaxStackSize(1) - ->setTextureName(L"bed") + ->setIconName(L"bed") ->setDescriptionId(IDS_ITEM_BED) ->setUseDescriptionId(IDS_DESC_BED); - Item::diode = (new TilePlanterItem(100, (Tile*)Tile::diode_off)) - ->setTextureName(L"diode") - ->setDescriptionId(IDS_ITEM_DIODE) - ->setUseDescriptionId(IDS_DESC_REDSTONEREPEATER); + Item::repeater = (new TilePlanterItem(100, (Tile*)Tile::diode_off)) + ->setIconName(L"diode") + ->setDescriptionId(IDS_ITEM_DIODE) + ->setUseDescriptionId(IDS_DESC_REDSTONEREPEATER); Item::cookie = (new FoodItem(101, 2, FoodConstants::FOOD_SATURATION_POOR, false)) - ->setTextureName(L"cookie") + ->setIconName(L"cookie") ->setDescriptionId(IDS_ITEM_COOKIE) ->setUseDescriptionId(IDS_DESC_COOKIE); Item::shears = (ShearsItem*)(new ShearsItem(103)) - ->setTextureName(L"shears") + ->setIconName(L"shears") ->setBaseItemTypeAndMaterial(eBaseItemType_devicetool, eMaterial_shears) ->setDescriptionId(IDS_ITEM_SHEARS) @@ -881,115 +911,115 @@ void Item::staticCtor() { Item::melon = (new FoodItem(104, 2, FoodConstants::FOOD_SATURATION_LOW, false)) - ->setTextureName(L"melon") + ->setIconName(L"melon") ->setDescriptionId(IDS_ITEM_MELON_SLICE) ->setUseDescriptionId(IDS_DESC_MELON_SLICE); Item::seeds_pumpkin = (new SeedItem(105, Tile::pumpkinStem_Id, Tile::farmland_Id)) - ->setTextureName(L"seeds_pumpkin") + ->setIconName(L"seeds_pumpkin") ->setBaseItemTypeAndMaterial(eBaseItemType_seed, eMaterial_pumpkin) ->setDescriptionId(IDS_ITEM_PUMPKIN_SEEDS) ->setUseDescriptionId(IDS_DESC_PUMPKIN_SEEDS); Item::seeds_melon = (new SeedItem(106, Tile::melonStem_Id, Tile::farmland_Id)) - ->setTextureName(L"seeds_melon") + ->setIconName(L"seeds_melon") ->setBaseItemTypeAndMaterial(eBaseItemType_seed, eMaterial_melon) ->setDescriptionId(IDS_ITEM_MELON_SEEDS) ->setUseDescriptionId(IDS_DESC_MELON_SEEDS); Item::beef_raw = (new FoodItem(107, 3, FoodConstants::FOOD_SATURATION_LOW, true)) - ->setTextureName(L"beefRaw") + ->setIconName(L"beefRaw") ->setDescriptionId(IDS_ITEM_BEEF_RAW) ->setUseDescriptionId(IDS_DESC_BEEF_RAW); Item::beef_cooked = (new FoodItem(108, 8, FoodConstants::FOOD_SATURATION_GOOD, true)) - ->setTextureName(L"beefCooked") + ->setIconName(L"beefCooked") ->setDescriptionId(IDS_ITEM_BEEF_COOKED) ->setUseDescriptionId(IDS_DESC_BEEF_COOKED); Item::chicken_raw = (new FoodItem(109, 2, FoodConstants::FOOD_SATURATION_LOW, true)) ->setEatEffect(MobEffect::hunger->id, 30, 0, .3f) - ->setTextureName(L"chickenRaw") + ->setIconName(L"chickenRaw") ->setDescriptionId(IDS_ITEM_CHICKEN_RAW) ->setUseDescriptionId(IDS_DESC_CHICKEN_RAW); Item::chicken_cooked = (new FoodItem(110, 6, FoodConstants::FOOD_SATURATION_NORMAL, true)) - ->setTextureName(L"chickenCooked") + ->setIconName(L"chickenCooked") ->setDescriptionId(IDS_ITEM_CHICKEN_COOKED) ->setUseDescriptionId(IDS_DESC_CHICKEN_COOKED); Item::rotten_flesh = (new FoodItem(111, 4, FoodConstants::FOOD_SATURATION_POOR, true)) ->setEatEffect(MobEffect::hunger->id, 30, 0, .8f) - ->setTextureName(L"rottenFlesh") + ->setIconName(L"rottenFlesh") ->setDescriptionId(IDS_ITEM_ROTTEN_FLESH) ->setUseDescriptionId(IDS_DESC_ROTTEN_FLESH); Item::enderPearl = (new EnderpearlItem(112)) - ->setTextureName(L"enderPearl") + ->setIconName(L"enderPearl") ->setDescriptionId(IDS_ITEM_ENDER_PEARL) ->setUseDescriptionId(IDS_DESC_ENDER_PEARL); Item::blazeRod = (new Item(113)) - ->setTextureName(L"blazeRod") + ->setIconName(L"blazeRod") ->setDescriptionId(IDS_ITEM_BLAZE_ROD) ->setUseDescriptionId(IDS_DESC_BLAZE_ROD) ->handEquipped(); Item::ghastTear = (new Item(114)) - ->setTextureName(L"ghastTear") + ->setIconName(L"ghastTear") ->setDescriptionId(IDS_ITEM_GHAST_TEAR) ->setUseDescriptionId(IDS_DESC_GHAST_TEAR) ->setPotionBrewingFormula(PotionBrewing::MOD_GHASTTEARS); Item::goldNugget = (new Item(115)) ->setBaseItemTypeAndMaterial(eBaseItemType_treasure, eMaterial_gold) - ->setTextureName(L"goldNugget") + ->setIconName(L"goldNugget") ->setDescriptionId(IDS_ITEM_GOLD_NUGGET) ->setUseDescriptionId(IDS_DESC_GOLD_NUGGET); - Item::netherStalkSeeds = - (new SeedItem(116, Tile::netherStalk_Id, Tile::hellSand_Id)) - ->setTextureName(L"netherStalkSeeds") + Item::netherwart_seeds = + (new SeedItem(116, Tile::netherStalk_Id, Tile::soulsand_Id)) + ->setIconName(L"netherStalkSeeds") ->setDescriptionId(IDS_ITEM_NETHER_STALK_SEEDS) ->setUseDescriptionId(IDS_DESC_NETHER_STALK_SEEDS) ->setPotionBrewingFormula(PotionBrewing::MOD_NETHERWART); Item::potion = (PotionItem*)((new PotionItem(117)) - ->setTextureName(L"potion") + ->setIconName(L"potion") ->setDescriptionId(IDS_ITEM_POTION) ->setUseDescriptionId(IDS_DESC_POTION)); Item::glassBottle = (new BottleItem(118)) ->setBaseItemTypeAndMaterial(eBaseItemType_utensil, eMaterial_glass) - ->setTextureName(L"glassBottle") + ->setIconName(L"glassBottle") ->setDescriptionId(IDS_ITEM_GLASS_BOTTLE) ->setUseDescriptionId(IDS_DESC_GLASS_BOTTLE); Item::spiderEye = (new FoodItem(119, 2, FoodConstants::FOOD_SATURATION_GOOD, false)) ->setEatEffect(MobEffect::poison->id, 5, 0, 1.0f) - ->setTextureName(L"spiderEye") + ->setIconName(L"spiderEye") ->setDescriptionId(IDS_ITEM_SPIDER_EYE) ->setUseDescriptionId(IDS_DESC_SPIDER_EYE) ->setPotionBrewingFormula(PotionBrewing::MOD_SPIDEREYE); Item::fermentedSpiderEye = (new Item(120)) - ->setTextureName(L"fermentedSpiderEye") + ->setIconName(L"fermentedSpiderEye") ->setDescriptionId(IDS_ITEM_FERMENTED_SPIDER_EYE) ->setUseDescriptionId(IDS_DESC_FERMENTED_SPIDER_EYE) ->setPotionBrewingFormula(PotionBrewing::MOD_FERMENTEDEYE); Item::blazePowder = (new Item(121)) - ->setTextureName(L"blazePowder") + ->setIconName(L"blazePowder") ->setDescriptionId(IDS_ITEM_BLAZE_POWDER) ->setUseDescriptionId(IDS_DESC_BLAZE_POWDER) ->setPotionBrewingFormula(PotionBrewing::MOD_BLAZEPOWDER); Item::magmaCream = (new Item(122)) - ->setTextureName(L"magmaCream") + ->setIconName(L"magmaCream") ->setDescriptionId(IDS_ITEM_MAGMA_CREAM) ->setUseDescriptionId(IDS_DESC_MAGMA_CREAM) ->setPotionBrewingFormula(PotionBrewing::MOD_MAGMACREAM); @@ -997,89 +1027,89 @@ void Item::staticCtor() { Item::brewingStand = (new TilePlanterItem(123, Tile::brewingStand)) ->setBaseItemTypeAndMaterial(eBaseItemType_device, eMaterial_blaze) - ->setTextureName(L"brewingStand") + ->setIconName(L"brewingStand") ->setDescriptionId(IDS_ITEM_BREWING_STAND) ->setUseDescriptionId(IDS_DESC_BREWING_STAND); Item::cauldron = (new TilePlanterItem(124, Tile::cauldron)) ->setBaseItemTypeAndMaterial(eBaseItemType_utensil, eMaterial_iron) - ->setTextureName(L"cauldron") + ->setIconName(L"cauldron") ->setDescriptionId(IDS_ITEM_CAULDRON) ->setUseDescriptionId(IDS_DESC_CAULDRON); Item::eyeOfEnder = (new EnderEyeItem(125)) ->setBaseItemTypeAndMaterial( eBaseItemType_pockettool, eMaterial_ender) - ->setTextureName(L"eyeOfEnder") + ->setIconName(L"eyeOfEnder") ->setDescriptionId(IDS_ITEM_EYE_OF_ENDER) ->setUseDescriptionId(IDS_DESC_EYE_OF_ENDER); Item::speckledMelon = (new Item(126)) ->setBaseItemTypeAndMaterial(eBaseItemType_giltFruit, eMaterial_melon) - ->setTextureName(L"speckledMelon") + ->setIconName(L"speckledMelon") ->setDescriptionId(IDS_ITEM_SPECKLED_MELON) ->setUseDescriptionId(IDS_DESC_SPECKLED_MELON) ->setPotionBrewingFormula(PotionBrewing::MOD_SPECKLEDMELON); - Item::monsterPlacer = (new MonsterPlacerItem(127)) - ->setTextureName(L"monsterPlacer") - ->setDescriptionId(IDS_ITEM_MONSTER_SPAWNER) - ->setUseDescriptionId(IDS_DESC_MONSTER_SPAWNER); + Item::spawnEgg = (new SpawnEggItem(127)) + ->setIconName(L"monsterPlacer") + ->setDescriptionId(IDS_ITEM_MONSTER_SPAWNER) + ->setUseDescriptionId(IDS_DESC_MONSTER_SPAWNER); // 4J Stu - Brought this forward Item::expBottle = (new ExperienceItem(128)) - ->setTextureName(L"expBottle") + ->setIconName(L"expBottle") ->setDescriptionId(IDS_ITEM_EXP_BOTTLE) ->setUseDescriptionId(IDS_DESC_EXP_BOTTLE); Item::record_01 = (new RecordingItem(2000, L"13")) - ->setTextureName(L"record") + ->setIconName(L"record") ->setDescriptionId(IDS_ITEM_RECORD_01) ->setUseDescriptionId(IDS_DESC_RECORD); Item::record_02 = (new RecordingItem(2001, L"cat")) - ->setTextureName(L"record") + ->setIconName(L"record") ->setDescriptionId(IDS_ITEM_RECORD_02) ->setUseDescriptionId(IDS_DESC_RECORD); // 4J - new records brought forward from 1.2.3 Item::record_03 = (new RecordingItem(2002, L"blocks")) - ->setTextureName(L"record") + ->setIconName(L"record") ->setDescriptionId(IDS_ITEM_RECORD_03) ->setUseDescriptionId(IDS_DESC_RECORD); Item::record_04 = (new RecordingItem(2003, L"chirp")) - ->setTextureName(L"record") + ->setIconName(L"record") ->setDescriptionId(IDS_ITEM_RECORD_04) ->setUseDescriptionId(IDS_DESC_RECORD); Item::record_05 = (new RecordingItem(2004, L"far")) - ->setTextureName(L"record") + ->setIconName(L"record") ->setDescriptionId(IDS_ITEM_RECORD_05) ->setUseDescriptionId(IDS_DESC_RECORD); Item::record_06 = (new RecordingItem(2005, L"mall")) - ->setTextureName(L"record") + ->setIconName(L"record") ->setDescriptionId(IDS_ITEM_RECORD_06) ->setUseDescriptionId(IDS_DESC_RECORD); Item::record_07 = (new RecordingItem(2006, L"mellohi")) - ->setTextureName(L"record") + ->setIconName(L"record") ->setDescriptionId(IDS_ITEM_RECORD_07) ->setUseDescriptionId(IDS_DESC_RECORD); Item::record_09 = (new RecordingItem(2007, L"stal")) - ->setTextureName(L"record") + ->setIconName(L"record") ->setDescriptionId(IDS_ITEM_RECORD_08) ->setUseDescriptionId(IDS_DESC_RECORD); Item::record_10 = (new RecordingItem(2008, L"strad")) - ->setTextureName(L"record") + ->setIconName(L"record") ->setDescriptionId(IDS_ITEM_RECORD_09) ->setUseDescriptionId(IDS_DESC_RECORD); Item::record_11 = (new RecordingItem(2009, L"ward")) - ->setTextureName(L"record") + ->setIconName(L"record") ->setDescriptionId(IDS_ITEM_RECORD_10) ->setUseDescriptionId(IDS_DESC_RECORD); Item::record_12 = (new RecordingItem(2010, L"11")) - ->setTextureName(L"record") + ->setIconName(L"record") ->setDescriptionId(IDS_ITEM_RECORD_11) ->setUseDescriptionId(IDS_DESC_RECORD); Item::record_08 = (new RecordingItem(2011, L"where are we now")) - ->setTextureName(L"record") + ->setIconName(L"record") ->setDescriptionId(IDS_ITEM_RECORD_12) ->setUseDescriptionId(IDS_DESC_RECORD); @@ -1089,23 +1119,19 @@ void Item::staticCtor() { Item::fireball = (new FireChargeItem(129)) ->setBaseItemTypeAndMaterial(eBaseItemType_torch, eMaterial_setfire) - ->setTextureName(L"fireball") + ->setIconName(L"fireball") ->setDescriptionId(IDS_ITEM_FIREBALL) ->setUseDescriptionId(IDS_DESC_FIREBALL); Item::frame = (new HangingEntityItem(133, eTYPE_ITEM_FRAME)) ->setBaseItemTypeAndMaterial(eBaseItemType_HangingItem, eMaterial_glass) - ->setTextureName(L"frame") + ->setIconName(L"frame") ->setDescriptionId(IDS_ITEM_ITEMFRAME) ->setUseDescriptionId(IDS_DESC_ITEMFRAME); - Item::netherbrick = (new Item(149)) - ->setTextureName(L"netherbrick") - ->setDescriptionId(IDS_ITEM_NETHERBRICK) - ->setUseDescriptionId(IDS_DESC_ITEM_NETHERBRICK); // TU12 Item::skull = (new SkullItem(141)) - ->setTextureName(L"skull") + ->setIconName(L"skull") ->setDescriptionId(IDS_ITEM_SKULL) ->setUseDescriptionId(IDS_DESC_SKULL); @@ -1117,44 +1143,49 @@ void Item::staticCtor() { Item::emerald = (new Item(132)) ->setBaseItemTypeAndMaterial(eBaseItemType_treasure, eMaterial_emerald) - ->setTextureName(L"emerald") + ->setIconName(L"emerald") ->setDescriptionId(IDS_ITEM_EMERALD) ->setUseDescriptionId(IDS_DESC_EMERALD); Item::flowerPot = (new TilePlanterItem(134, Tile::flowerPot)) - ->setTextureName(L"flowerPot") + ->setIconName(L"flowerPot") ->setDescriptionId(IDS_FLOWERPOT) ->setUseDescriptionId(IDS_DESC_FLOWERPOT); Item::carrots = (new SeedFoodItem(135, 4, FoodConstants::FOOD_SATURATION_NORMAL, Tile::carrots_Id, Tile::farmland_Id)) - ->setTextureName(L"carrots") + ->setIconName(L"carrots") ->setDescriptionId(IDS_CARROTS) ->setUseDescriptionId(IDS_DESC_CARROTS); Item::potato = (new SeedFoodItem(136, 1, FoodConstants::FOOD_SATURATION_LOW, Tile::potatoes_Id, Tile::farmland_Id)) - ->setTextureName(L"potato") + ->setIconName(L"potato") ->setDescriptionId(IDS_POTATO) ->setUseDescriptionId(IDS_DESC_POTATO); Item::potatoBaked = (new FoodItem(137, 6, FoodConstants::FOOD_SATURATION_NORMAL, false)) - ->setTextureName(L"potatoBaked") + ->setIconName(L"potatoBaked") ->setDescriptionId(IDS_ITEM_POTATO_BAKED) ->setUseDescriptionId(IDS_DESC_POTATO_BAKED); Item::potatoPoisonous = (new FoodItem(138, 2, FoodConstants::FOOD_SATURATION_LOW, false)) ->setEatEffect(MobEffect::poison->id, 5, 0, .6f) - ->setTextureName(L"potatoPoisonous") + ->setIconName(L"potatoPoisonous") ->setDescriptionId(IDS_ITEM_POTATO_POISONOUS) ->setUseDescriptionId(IDS_DESC_POTATO_POISONOUS); + Item::emptyMap = (EmptyMapItem*)(new EmptyMapItem(139)) + ->setIconName(L"map_empty") + ->setDescriptionId(IDS_ITEM_MAP_EMPTY) + ->setUseDescriptionId(IDS_DESC_MAP_EMPTY); + Item::carrotGolden = (new FoodItem(140, 6, FoodConstants::FOOD_SATURATION_SUPERNATURAL, false)) ->setBaseItemTypeAndMaterial(eBaseItemType_giltFruit, eMaterial_carrot) - ->setTextureName(L"carrotGolden") + ->setIconName(L"carrotGolden") ->setPotionBrewingFormula(PotionBrewing::MOD_GOLDENCARROT) ->setDescriptionId(IDS_ITEM_CARROT_GOLDEN) ->setUseDescriptionId(IDS_DESC_CARROT_GOLDEN); @@ -1162,32 +1193,94 @@ void Item::staticCtor() { Item::carrotOnAStick = (new CarrotOnAStickItem(142)) ->setBaseItemTypeAndMaterial(eBaseItemType_rod, eMaterial_carrot) - ->setTextureName(L"carrotOnAStick") + ->setIconName(L"carrotOnAStick") ->setDescriptionId(IDS_ITEM_CARROT_ON_A_STICK) ->setUseDescriptionId(IDS_DESC_CARROT_ON_A_STICK); + Item::netherStar = (new SimpleFoiledItem(143)) + ->setIconName(L"nether_star") + ->setDescriptionId(IDS_NETHER_STAR) + ->setUseDescriptionId(IDS_DESC_NETHER_STAR); Item::pumpkinPie = (new FoodItem(144, 8, FoodConstants::FOOD_SATURATION_LOW, false)) - ->setTextureName(L"pumpkinPie") + ->setIconName(L"pumpkinPie") ->setDescriptionId(IDS_ITEM_PUMPKIN_PIE) ->setUseDescriptionId(IDS_DESC_PUMPKIN_PIE); - + Item::fireworks = + (new FireworksItem(145)) + ->setBaseItemTypeAndMaterial(Item::eBaseItemType_fireworks, + Item::eMaterial_undefined) + ->setIconName(L"fireworks") + ->setDescriptionId(IDS_FIREWORKS) + ->setUseDescriptionId(IDS_DESC_FIREWORKS); + Item::fireworksCharge = + (new FireworksChargeItem(146)) + ->setBaseItemTypeAndMaterial(Item::eBaseItemType_fireworks, + Item::eMaterial_undefined) + ->setIconName(L"fireworks_charge") + ->setDescriptionId(IDS_FIREWORKS_CHARGE) + ->setUseDescriptionId(IDS_DESC_FIREWORKS_CHARGE); EnchantedBookItem::enchantedBook = (EnchantedBookItem*)(new EnchantedBookItem(147)) ->setMaxStackSize(1) - ->setTextureName(L"enchantedBook") + ->setIconName(L"enchantedBook") ->setDescriptionId(IDS_ITEM_ENCHANTED_BOOK) ->setUseDescriptionId(IDS_DESC_ENCHANTED_BOOK); + Item::comparator = (new TilePlanterItem(148, Tile::comparator_off)) + ->setIconName(L"comparator") + ->setDescriptionId(IDS_ITEM_COMPARATOR) + ->setUseDescriptionId(IDS_DESC_COMPARATOR); + Item::netherbrick = (new Item(149)) + ->setIconName(L"netherbrick") + ->setDescriptionId(IDS_ITEM_NETHERBRICK) + ->setUseDescriptionId(IDS_DESC_ITEM_NETHERBRICK); Item::netherQuartz = (new Item(150)) - ->setTextureName(L"netherquartz") + ->setIconName(L"netherquartz") ->setDescriptionId(IDS_ITEM_NETHER_QUARTZ) ->setUseDescriptionId(IDS_DESC_NETHER_QUARTZ); + Item::minecart_tnt = (new MinecartItem(151, Minecart::TYPE_TNT)) + ->setIconName(L"minecart_tnt") + ->setDescriptionId(IDS_ITEM_MINECART_TNT) + ->setUseDescriptionId(IDS_DESC_MINECART_TNT); + Item::minecart_hopper = (new MinecartItem(152, Minecart::TYPE_HOPPER)) + ->setIconName(L"minecart_hopper") + ->setDescriptionId(IDS_ITEM_MINECART_HOPPER) + ->setUseDescriptionId(IDS_DESC_MINECART_HOPPER); + + Item::horseArmorMetal = + (new Item(161)) + ->setIconName(L"iron_horse_armor") + ->setMaxStackSize(1) + ->setDescriptionId(IDS_ITEM_IRON_HORSE_ARMOR) + ->setUseDescriptionId(IDS_DESC_IRON_HORSE_ARMOR); + Item::horseArmorGold = (new Item(162)) + ->setIconName(L"gold_horse_armor") + ->setMaxStackSize(1) + ->setDescriptionId(IDS_ITEM_GOLD_HORSE_ARMOR) + ->setUseDescriptionId(IDS_DESC_GOLD_HORSE_ARMOR); + Item::horseArmorDiamond = + (new Item(163)) + ->setIconName(L"diamond_horse_armor") + ->setMaxStackSize(1) + ->setDescriptionId(IDS_ITEM_DIAMOND_HORSE_ARMOR) + ->setUseDescriptionId(IDS_DESC_DIAMOND_HORSE_ARMOR); + Item::lead = (new LeashItem(164)) + ->setBaseItemTypeAndMaterial(eBaseItemType_pockettool, + eMaterial_undefined) + ->setIconName(L"lead") + ->setDescriptionId(IDS_ITEM_LEAD) + ->setUseDescriptionId(IDS_DESC_LEAD); + Item::nameTag = (new NameTagItem(165)) + ->setIconName(L"name_tag") + ->setDescriptionId(IDS_ITEM_NAME_TAG) + ->setUseDescriptionId(IDS_DESC_NAME_TAG); } // 4J Stu - We need to do this after the staticCtor AND after staticCtors for // other class eg Recipes void Item::staticInit() { Stats::buildItemStats(); } -_Tier::Tier(int level, int uses, float speed, int damage, int enchantmentValue) +_Tier::Tier(int level, int uses, float speed, float damage, + int enchantmentValue) : level(level), uses(uses), speed(speed), @@ -1198,7 +1291,7 @@ int _Tier::getUses() const { return uses; } float _Tier::getSpeed() const { return speed; } -int _Tier::getAttackDamageBonus() const { return damage; } +float _Tier::getAttackDamageBonus() const { return damage; } int _Tier::getLevel() const { return level; } @@ -1208,7 +1301,7 @@ int _Tier::getTierItemId() const { if (this == Tier::WOOD) { return Tile::wood_Id; } else if (this == Tier::STONE) { - return Tile::stoneBrick_Id; + return Tile::cobblestone_Id; } else if (this == Tier::GOLD) { return Item::goldIngot_Id; } else if (this == Tier::IRON) { @@ -1256,12 +1349,14 @@ int Item::getBaseItemType() { return this->m_iBaseItemType; } int Item::getMaterial() { return this->m_iMaterial; } -Item* Item::setTextureName(const std::wstring& name) { +Item* Item::setIconName(const std::wstring& name) { m_textureName = name; return this; } +std::wstring Item::getIconName() { return m_textureName; } + Item* Item::setMaxStackSize(int max) { maxStackSize = max; return this; @@ -1275,11 +1370,6 @@ Icon* Item::getIcon(std::shared_ptr itemInstance) { return getIcon(itemInstance->getAuxValue()); } -const bool Item::useOn(std::shared_ptr itemInstance, Level* level, - int x, int y, int z, int face, bool bTestUseOnOnly) { - return false; -} - bool Item::useOn(std::shared_ptr itemInstance, std::shared_ptr player, Level* level, int x, int y, int z, int face, float clickX, float clickY, float clickZ, @@ -1292,7 +1382,8 @@ float Item::getDestroySpeed(std::shared_ptr itemInstance, return 1; } -bool Item::TestUse(Level* level, std::shared_ptr player) { +bool Item::TestUse(std::shared_ptr itemInstance, Level* level, + std::shared_ptr player) { return false; } @@ -1337,7 +1428,8 @@ bool Item::canBeDepleted() { return maxDamage > 0 && !m_isStackedByData; } * @return */ bool Item::hurtEnemy(std::shared_ptr itemInstance, - std::shared_ptr mob, std::shared_ptr attacker) { + std::shared_ptr mob, + std::shared_ptr attacker) { return false; } @@ -1354,7 +1446,7 @@ bool Item::hurtEnemy(std::shared_ptr itemInstance, */ bool Item::mineBlock(std::shared_ptr itemInstance, Level* level, int tile, int x, int y, int z, - std::shared_ptr owner) { + std::shared_ptr owner) { return false; } @@ -1363,12 +1455,13 @@ int Item::getAttackDamage(std::shared_ptr entity) { return 1; } bool Item::canDestroySpecial(Tile* tile) { return false; } bool Item::interactEnemy(std::shared_ptr itemInstance, - std::shared_ptr mob) { + std::shared_ptr player, + std::shared_ptr mob) { return false; } Item* Item::handEquipped() { - this->m_handEquipped = true; + m_handEquipped = true; return this; } @@ -1381,12 +1474,12 @@ Item* Item::setDescriptionId(unsigned int id) { return this; } -const wchar_t* Item::getDescription() { +LPCWSTR Item::getDescription() { return app.GetString(getDescriptionId()); // return I18n::get(getDescriptionId()); } -const wchar_t* Item::getDescription(std::shared_ptr instance) { +LPCWSTR Item::getDescription(std::shared_ptr instance) { return app.GetString(getDescriptionId(instance)); // return I18n::get(getDescriptionId(instance)); } @@ -1467,8 +1560,7 @@ bool Item::hasPotionBrewingFormula() { return !potionBrewingFormula.empty(); } void Item::appendHoverText(std::shared_ptr itemInstance, std::shared_ptr player, - std::vector* lines, bool advanced, - std::vector& unformattedStrings) {} + std::vector* lines, bool advanced) {} std::wstring Item::getHoverName(std::shared_ptr itemInstance) { // String elementName = ("" + @@ -1528,6 +1620,8 @@ Icon* Item::getLayerIcon(int auxValue, int spriteLayer) { return getIcon(auxValue); } +bool Item::mayBePlacedInAdventureMode() { return true; } + bool Item::isValidRepairItem(std::shared_ptr source, std::shared_ptr repairItem) { return false; @@ -1537,6 +1631,10 @@ void Item::registerIcons(IconRegister* iconRegister) { icon = iconRegister->registerIcon(m_textureName); } +attrAttrModMap* Item::getDefaultAttributeModifiers() { + return new attrAttrModMap(); +} + /* 4J: These are necesary on the PS3. (and 4 and Vita). @@ -1576,7 +1674,7 @@ const int Item::pickAxe_gold_Id; const int Item::hatchet_gold_Id; const int Item::string_Id; const int Item::feather_Id; -const int Item::sulphur_Id; +const int Item::gunpowder_Id; const int Item::hoe_wood_Id; const int Item::hoe_stone_Id; const int Item::hoe_iron_Id; @@ -1585,10 +1683,10 @@ const int Item::hoe_gold_Id; const int Item::seeds_wheat_Id; const int Item::wheat_Id; const int Item::bread_Id; -const int Item::helmet_cloth_Id; -const int Item::chestplate_cloth_Id; -const int Item::leggings_cloth_Id; -const int Item::boots_cloth_Id; +const int Item::helmet_leather_Id; +const int Item::chestplate_leather_Id; +const int Item::leggings_leather_Id; +const int Item::boots_leather_Id; const int Item::helmet_chain_Id; const int Item::chestplate_chain_Id; const int Item::leggings_chain_Id; @@ -1622,7 +1720,7 @@ const int Item::redStone_Id; const int Item::snowBall_Id; const int Item::boat_Id; const int Item::leather_Id; -const int Item::milk_Id; +const int Item::bucket_milk_Id; const int Item::brick_Id; const int Item::clay_Id; const int Item::reeds_Id; @@ -1643,7 +1741,7 @@ const int Item::bone_Id; const int Item::sugar_Id; const int Item::cake_Id; const int Item::bed_Id; -const int Item::diode_Id; +const int Item::repeater_Id; const int Item::cookie_Id; const int Item::map_Id; const int Item::shears_Id; @@ -1659,7 +1757,7 @@ const int Item::enderPearl_Id; const int Item::blazeRod_Id; const int Item::ghastTear_Id; const int Item::goldNugget_Id; -const int Item::netherStalkSeeds_Id; +const int Item::netherwart_seeds_Id; const int Item::potion_Id; const int Item::glassBottle_Id; const int Item::spiderEye_Id; @@ -1670,7 +1768,7 @@ const int Item::brewingStand_Id; const int Item::cauldron_Id; const int Item::eyeOfEnder_Id; const int Item::speckledMelon_Id; -const int Item::monsterPlacer_Id; +const int Item::spawnEgg_Id; const int Item::expBottle_Id; const int Item::skull_Id; const int Item::record_01_Id; diff --git a/Minecraft.World/Items/Item.h b/Minecraft.World/Items/Item.h index 2d6013284..42067e480 100644 --- a/Minecraft.World/Items/Item.h +++ b/Minecraft.World/Items/Item.h @@ -18,10 +18,14 @@ class ArmorItem; class BowItem; class FishingRodItem; class EnchantedBookItem; +class EmptyMapItem; #define ITEM_ICON_COLUMNS 16 class Item : public std::enable_shared_from_this { +protected: + // static const UUID BASE_ATTACK_DAMAGE_UUID; + public: static const int ITEM_NUM_COUNT = 32000; @@ -74,7 +78,14 @@ public: eMaterial_emerald, eMaterial_quartz, eMaterial_apple, - eMaterial_carrot + eMaterial_carrot, + eMaterial_redstone, + eMaterial_coal, + eMaterial_paper, + eMaterial_book, + eMaterial_bookshelf, + eMaterial_wheat, + } eMaterial; enum { @@ -116,6 +127,12 @@ public: eBaseItemType_rod, eBaseItemType_giltFruit, eBaseItemType_carpet, + eBaseItemType_clay, + eBaseItemType_glass, + eBaseItemType_redstoneContainer, + eBaseItemType_fireworks, + eBaseItemType_lever, + eBaseItemType_paper, eBaseItemType_MAXTYPES, } eBaseItemType; @@ -138,26 +155,21 @@ public: const int level; const int uses; const float speed; - const int damage; + const float damage; const int enchantmentValue; // 4J Stu - Had to make this public but was protected // We shouldn't be creating these except the static initialisation public: - Tier(int level, int uses, float speed, int damage, + Tier(int level, int uses, float speed, float damage, int enchantmentValue); public: int getUses() const; - float getSpeed() const; - - int getAttackDamageBonus() const; - + float getAttackDamageBonus() const; int getLevel() const; - int getEnchantmentValue() const; - int getTierItemId() const; }; @@ -207,9 +219,9 @@ public: static Item* pickAxe_gold; static Item* hatchet_gold; - static Item* string; + static Item* std::string; static Item* feather; - static Item* sulphur; + static Item* gunpowder; static Item* hoe_wood; static Item* hoe_stone; @@ -221,10 +233,10 @@ public: static Item* wheat; static Item* bread; - static ArmorItem* helmet_cloth; - static ArmorItem* chestplate_cloth; - static ArmorItem* leggings_cloth; - static ArmorItem* boots_cloth; + static ArmorItem* helmet_leather; + static ArmorItem* chestplate_leather; + static ArmorItem* leggings_leather; + static ArmorItem* boots_leather; static ArmorItem* helmet_chain; static ArmorItem* chestplate_chain; @@ -269,7 +281,7 @@ public: static Item* boat; static Item* leather; - static Item* milk; + static Item* bucket_milk; static Item* brick; static Item* clay; static Item* reeds; @@ -293,7 +305,7 @@ public: static Item* bed; - static Item* diode; + static Item* repeater; static Item* cookie; static MapItem* map; @@ -317,7 +329,7 @@ public: static Item* ghastTear; static Item* goldNugget; - static Item* netherStalkSeeds; + static Item* netherwart_seeds; static PotionItem* potion; static Item* glassBottle; @@ -333,7 +345,7 @@ public: static Item* eyeOfEnder; static Item* speckledMelon; - static Item* monsterPlacer; + static Item* spawnEgg; static Item* expBottle; @@ -355,7 +367,6 @@ public: // TU9 static Item* fireball; static Item* frame; - static Item* netherbrick; // TU14 // static Item writingBook; @@ -370,13 +381,29 @@ public: static Item* potatoBaked; static Item* potatoPoisonous; + static EmptyMapItem* emptyMap; + static Item* carrotGolden; static Item* carrotOnAStick; + static Item* netherStar; static Item* pumpkinPie; + + static Item* fireworks; + static Item* fireworksCharge; static Item* netherQuartz; + static Item* comparator; + static Item* netherbrick; static EnchantedBookItem* enchantedBook; + static Item* minecart_tnt; + static Item* minecart_hopper; + + static Item* horseArmorMetal; + static Item* horseArmorGold; + static Item* horseArmorDiamond; + static Item* lead; + static Item* nameTag; static const int shovel_iron_Id = 256; static const int pickAxe_iron_Id = 257; @@ -411,7 +438,7 @@ public: static const int hatchet_gold_Id = 286; static const int string_Id = 287; static const int feather_Id = 288; - static const int sulphur_Id = 289; + static const int gunpowder_Id = 289; static const int hoe_wood_Id = 290; static const int hoe_stone_Id = 291; static const int hoe_iron_Id = 292; @@ -421,10 +448,10 @@ public: static const int wheat_Id = 296; static const int bread_Id = 297; - static const int helmet_cloth_Id = 298; - static const int chestplate_cloth_Id = 299; - static const int leggings_cloth_Id = 300; - static const int boots_cloth_Id = 301; + static const int helmet_leather_Id = 298; + static const int chestplate_leather_Id = 299; + static const int leggings_leather_Id = 300; + static const int boots_leather_Id = 301; static const int helmet_chain_Id = 302; static const int chestplate_chain_Id = 303; @@ -463,7 +490,7 @@ public: static const int snowBall_Id = 332; static const int boat_Id = 333; static const int leather_Id = 334; - static const int milk_Id = 335; + static const int bucket_milk_Id = 335; static const int brick_Id = 336; static const int clay_Id = 337; static const int reeds_Id = 338; @@ -484,7 +511,7 @@ public: static const int sugar_Id = 353; static const int cake_Id = 354; static const int bed_Id = 355; - static const int diode_Id = 356; + static const int repeater_Id = 356; static const int cookie_Id = 357; static const int map_Id = 358; @@ -506,7 +533,7 @@ public: static const int blazeRod_Id = 369; static const int ghastTear_Id = 370; static const int goldNugget_Id = 371; - static const int netherStalkSeeds_Id = 372; + static const int netherwart_seeds_Id = 372; static const int potion_Id = 373; static const int glassBottle_Id = 374; static const int spiderEye_Id = 375; @@ -519,7 +546,7 @@ public: static const int speckledMelon_Id = 382; // 1.1 - static const int monsterPlacer_Id = 383; + static const int spawnEgg_Id = 383; static const int expBottle_Id = 384; @@ -544,7 +571,6 @@ public: // TU9 static const int fireball_Id = 385; static const int itemFrame_Id = 389; - static const int netherbrick_Id = 405; // TU14 // static const int writingBook_Id = 130; @@ -559,13 +585,30 @@ public: static const int potatoBaked_Id = 393; static const int potatoPoisonous_Id = 394; + static const int emptyMap_Id = 395; + static const int carrotGolden_Id = 396; static const int carrotOnAStick_Id = 398; + static const int netherStar_Id = 399; static const int pumpkinPie_Id = 400; + static const int fireworks_Id = 401; + static const int fireworksCharge_Id = 402; + static const int enchantedBook_Id = 403; + + static const int comparator_Id = 404; + static const int netherbrick_Id = 405; static const int netherQuartz_Id = 406; + static const int minecart_tnt_Id = 407; + static const int minecart_hopper_Id = 408; + + static const int horseArmorMetal_Id = 417; + static const int horseArmorGold_Id = 418; + static const int horseArmorDiamond_Id = 419; + static const int lead_Id = 420; + static const int nameTag_Id = 421; public: const int id; @@ -601,7 +644,8 @@ protected: public: // 4J Using per-item textures now - Item* setTextureName(const std::wstring& name); + Item* setIconName(const std::wstring& name); + std::wstring getIconName(); Item* setMaxStackSize(int max); Item* setBaseItemTypeAndMaterial(int iType, int iMaterial); int getBaseItemType(); @@ -611,17 +655,14 @@ public: virtual Icon* getIcon(int auxValue); Icon* getIcon(std::shared_ptr itemInstance); - const bool useOn(std::shared_ptr itemInstance, Level* level, - int x, int y, int z, int face, - bool bTestUseOnOnly = false); - virtual bool useOn(std::shared_ptr itemInstance, std::shared_ptr player, Level* level, int x, int y, int z, int face, float clickX, float clickY, float clickZ, bool bTestUseOnOnly = false); virtual float getDestroySpeed(std::shared_ptr itemInstance, Tile* tile); - virtual bool TestUse(Level* level, std::shared_ptr player); + virtual bool TestUse(std::shared_ptr itemInstance, + Level* level, std::shared_ptr player); virtual std::shared_ptr use( std::shared_ptr itemInstance, Level* level, std::shared_ptr player); @@ -653,8 +694,8 @@ public: * @return */ virtual bool hurtEnemy(std::shared_ptr itemInstance, - std::shared_ptr mob, - std::shared_ptr attacker); + std::shared_ptr mob, + std::shared_ptr attacker); /** * Returns true when the item was used to mine more efficiently @@ -669,17 +710,18 @@ public: */ virtual bool mineBlock(std::shared_ptr itemInstance, Level* level, int tile, int x, int y, int z, - std::shared_ptr owner); + std::shared_ptr owner); virtual int getAttackDamage(std::shared_ptr entity); virtual bool canDestroySpecial(Tile* tile); virtual bool interactEnemy(std::shared_ptr itemInstance, - std::shared_ptr mob); + std::shared_ptr player, + std::shared_ptr mob); Item* handEquipped(); virtual bool isHandEquipped(); virtual bool isMirroredArt(); Item* setDescriptionId(unsigned int id); - const wchar_t* getDescription(); - const wchar_t* getDescription(std::shared_ptr instance); + LPCWSTR getDescription(); + LPCWSTR getDescription(std::shared_ptr instance); virtual unsigned int getDescriptionId(int iData = -1); virtual unsigned int getDescriptionId( std::shared_ptr instance); @@ -715,12 +757,9 @@ protected: public: virtual std::wstring getPotionBrewingFormula(); virtual bool hasPotionBrewingFormula(); - virtual void appendHoverText( - std::shared_ptr itemInstance, - std::shared_ptr player, std::vector* lines, - bool advanced, - std::vector& - unformattedStrings); // 4J Added unformattedStrings + virtual void appendHoverText(std::shared_ptr itemInstance, + std::shared_ptr player, + std::vector* lines, bool advanced); virtual std::wstring getHoverName( std::shared_ptr itemInstance); virtual bool isFoil(std::shared_ptr itemInstance); @@ -736,7 +775,9 @@ public: virtual int getEnchantmentValue(); virtual bool hasMultipleSpriteLayers(); virtual Icon* getLayerIcon(int auxValue, int spriteLayer); + virtual bool mayBePlacedInAdventureMode(); virtual bool isValidRepairItem(std::shared_ptr source, std::shared_ptr repairItem); virtual void registerIcons(IconRegister* iconRegister); + virtual attrAttrModMap* getDefaultAttributeModifiers(); }; diff --git a/Minecraft.World/Items/ItemInstance.cpp b/Minecraft.World/Items/ItemInstance.cpp index 3c8b4857f..8958e2967 100644 --- a/Minecraft.World/Items/ItemInstance.cpp +++ b/Minecraft.World/Items/ItemInstance.cpp @@ -3,6 +3,8 @@ #include "../Headers/net.minecraft.locale.h" #include "../Headers/net.minecraft.stats.h" #include "../Headers/net.minecraft.world.entity.h" +#include "../Headers/net.minecraft.world.entity.ai.attributes.h" +#include "../Headers/net.minecraft.world.entity.monster.h" #include "../Headers/net.minecraft.world.entity.player.h" #include "../Headers/net.minecraft.world.level.h" #include "../Headers/net.minecraft.world.level.tile.h" @@ -10,6 +12,9 @@ #include "../Headers/net.minecraft.world.item.enchantment.h" #include "Item.h" #include "ItemInstance.h" +#include "../Util/HtmlString.h" + +const std::wstring ItemInstance::ATTRIBUTE_MODIFIER_FORMAT = L"#.###"; const wchar_t* ItemInstance::TAG_ENCH_ID = L"id"; const wchar_t* ItemInstance::TAG_ENCH_LEVEL = L"lvl"; @@ -47,6 +52,9 @@ ItemInstance::ItemInstance(Item* item, int count, int auxValue) { ItemInstance::ItemInstance(int id, int count, int damage) { _init(id, count, damage); + if (auxValue < 0) { + auxValue = 0; + } } std::shared_ptr ItemInstance::fromTag(CompoundTag* itemTag) { @@ -90,8 +98,9 @@ float ItemInstance::getDestroySpeed(Tile* tile) { return getItem()->getDestroySpeed(shared_from_this(), tile); } -bool ItemInstance::TestUse(Level* level, std::shared_ptr player) { - return getItem()->TestUse(level, player); +bool ItemInstance::TestUse(std::shared_ptr itemInstance, + Level* level, std::shared_ptr player) { + return getItem()->TestUse(itemInstance, level, player); } std::shared_ptr ItemInstance::use( @@ -108,7 +117,7 @@ CompoundTag* ItemInstance::save(CompoundTag* compoundTag) { compoundTag->putShort(L"id", (short)id); compoundTag->putByte(L"Count", (uint8_t)count); compoundTag->putShort(L"Damage", (short)auxValue); - if (this->tag != NULL) compoundTag->put(L"tag", tag->copy()); + if (tag != NULL) compoundTag->put(L"tag", tag->copy()); return compoundTag; } @@ -117,7 +126,11 @@ void ItemInstance::load(CompoundTag* compoundTag) { id = compoundTag->getShort(L"id"); count = compoundTag->getByte(L"Count"); auxValue = compoundTag->getShort(L"Damage"); + if (auxValue < 0) { + auxValue = 0; + } if (compoundTag->contains(L"tag")) { + delete tag; tag = (CompoundTag*)compoundTag->getCompound(L"tag")->copy(); } } @@ -149,43 +162,62 @@ int ItemInstance::getDamageValue() { return auxValue; } int ItemInstance::getAuxValue() const { return auxValue; } -void ItemInstance::setAuxValue(int value) { auxValue = value; } +void ItemInstance::setAuxValue(int value) { + auxValue = value; + if (auxValue < 0) { + auxValue = 0; + } +} int ItemInstance::getMaxDamage() { return Item::items[id]->getMaxDamage(); } -void ItemInstance::hurt(int i, std::shared_ptr owner) { +bool ItemInstance::hurt(int dmg, Random* random) { if (!isDamageableItem()) { - return; + return false; } - std::shared_ptr player = std::dynamic_pointer_cast(owner); - if (i > 0 && player != NULL) { - int enchanted = EnchantmentHelper::getDigDurability(player->inventory); - // Fix for #65233 - TU8: Content: Gameplay: Tools Enchanted with - // "Unbreaking" occasionally repair themselves. 4J Stu - If it's the - // clientside level, then always assume that no damage is done. This - // stops the case where the client random results in damage, but the - // server random does not - if (enchanted > 0 && - (owner->level->isClientSide || - owner->level->random->nextInt(enchanted + 1) > 0)) { - // enchantment prevents damage - return; + if (dmg > 0) { + int level = EnchantmentHelper::getEnchantmentLevel( + Enchantment::digDurability->id, shared_from_this()); + + int drop = 0; + for (int y = 0; level > 0 && y < dmg; y++) { + if (DigDurabilityEnchantment::shouldIgnoreDurabilityDrop( + shared_from_this(), level, random)) { + drop++; + } } + dmg -= drop; + + if (dmg <= 0) return false; } - // 4J Stu - Changed in TU6 to not damage items in creative mode - if (!(owner != NULL && player->abilities.instabuild)) auxValue += i; + auxValue += dmg; - if (auxValue > getMaxDamage()) { + return auxValue > getMaxDamage(); +} + +void ItemInstance::hurtAndBreak(int dmg, std::shared_ptr owner) { + std::shared_ptr player = std::dynamic_pointer_cast(owner); + if (player != NULL && player->abilities.instabuild) return; + if (!isDamageableItem()) return; + + if (hurt(dmg, owner->getRandom())) { owner->breakItem(shared_from_this()); + count--; + if (player != NULL) { + // player->awardStat(Stats::itemBroke[id], 1); + if (count == 0 && dynamic_cast(getItem()) != NULL) { + player->removeSelectedItem(); + } + } if (count < 0) count = 0; auxValue = 0; } } -void ItemInstance::hurtEnemy(std::shared_ptr mob, +void ItemInstance::hurtEnemy(std::shared_ptr mob, std::shared_ptr attacker) { // bool used = Item::items[id]->hurtEnemy(shared_from_this(), mob, attacker); @@ -197,16 +229,13 @@ void ItemInstance::mineBlock(Level* level, int tile, int x, int y, int z, Item::items[id]->mineBlock(shared_from_this(), level, tile, x, y, z, owner); } -int ItemInstance::getAttackDamage(std::shared_ptr entity) { - return Item::items[id]->getAttackDamage(entity); -} - bool ItemInstance::canDestroySpecial(Tile* tile) { return Item::items[id]->canDestroySpecial(tile); } -bool ItemInstance::interactEnemy(std::shared_ptr mob) { - return Item::items[id]->interactEnemy(shared_from_this(), mob); +bool ItemInstance::interactEnemy(std::shared_ptr player, + std::shared_ptr mob) { + return Item::items[id]->interactEnemy(shared_from_this(), player, mob); } std::shared_ptr ItemInstance::copy() const { @@ -379,7 +408,10 @@ ListTag* ItemInstance::getEnchantmentTags() { return (ListTag*)tag->get(L"ench"); } -void ItemInstance::setTag(CompoundTag* tag) { this->tag = tag; } +void ItemInstance::setTag(CompoundTag* tag) { + delete this->tag; + this->tag = tag; +} std::wstring ItemInstance::getHoverName() { std::wstring title = getItem()->getHoverName(shared_from_this()); @@ -402,58 +434,69 @@ void ItemInstance::setHoverName(const std::wstring& name) { tag->getCompound(L"display")->putString(L"Name", name); } +void ItemInstance::resetHoverName() { + if (tag == NULL) return; + if (!tag->contains(L"display")) return; + CompoundTag* display = tag->getCompound(L"display"); + display->remove(L"Name"); + + if (display->isEmpty()) { + tag->remove(L"display"); + + if (tag->isEmpty()) { + setTag(NULL); + } + } +} + bool ItemInstance::hasCustomHoverName() { if (tag == NULL) return false; if (!tag->contains(L"display")) return false; return tag->getCompound(L"display")->contains(L"Name"); } -std::vector* ItemInstance::getHoverText( - std::shared_ptr player, bool advanced, - std::vector& unformattedStrings) { - std::vector* lines = new std::vector(); +std::vector* ItemInstance::getHoverText( + std::shared_ptr player, bool advanced) { + std::vector* lines = new std::vector(); Item* item = Item::items[id]; - std::wstring title = getHoverName(); + HtmlString title = HtmlString(getHoverName()); - // 4J Stu - We don't do italics, but do change colour. But handle this later - // in the process due to text length measuring on the Xbox360 - // if (hasCustomHoverName()) - //{ - // title = L"" + title + L""; - //} + if (hasCustomHoverName()) { + title.italics = true; + } - // 4J Stu - Don't currently have this - // if (advanced) - //{ - // String suffix = ""; + // 4J: This is for showing aux values, not useful in console version + /* + if (advanced) + { + wstring suffix = L""; - // if (title.length() > 0) { - // title += " ("; - // suffix = ")"; - // } + if (title.length() > 0) + { + title += L" ("; + suffix = L")"; + } - // if (isStackedByData()) - // { - // title += String.format("#%04d/%d%s", id, auxValue, suffix); - // } - // else - // { - // title += String.format("#%04d%s", id, suffix); - // } - //} - // else - // if (!hasCustomHoverName()) - //{ - // if (id == Item::map_Id) - // { - // title += L" #" + _toString(auxValue); - // } - //} + if (isStackedByData()) + { + title += String.format("#%04d/%d%s", id, auxValue, suffix); + } + else + { + title += String.format("#%04d%s", id, suffix); + } + } + else if (!hasCustomHoverName() && id == Item::map_Id) + */ + + /*if (!hasCustomHoverName() && id == Item::map_Id) + { + title.text += L" #" + _toString(auxValue); + }*/ lines->push_back(title); - unformattedStrings.push_back(title); - item->appendHoverText(shared_from_this(), player, lines, advanced, - unformattedStrings); + + item->appendHoverText(shared_from_this(), player, lines, advanced); if (hasTag()) { ListTag* list = getEnchantmentTags(); @@ -465,25 +508,87 @@ std::vector* ItemInstance::getHoverText( if (Enchantment::enchantments[type] != NULL) { std::wstring unformatted = L""; lines->push_back( - Enchantment::enchantments[type]->getFullname( - level, unformatted)); - unformattedStrings.push_back(unformatted); + Enchantment::enchantments[type]->getFullname(level)); } } } + + if (tag->contains(L"display")) { + // CompoundTag *display = tag->getCompound(L"display"); + + // if (display->contains(L"color")) + //{ + // if (advanced) + // { + // wchar_t text [256]; + // swprintf(text, 256, L"Color: LOCALISE #%08X", + // display->getInt(L"color")); + // lines->push_back(HtmlString(text)); + // } + // else + // { + // lines->push_back(HtmlString(L"Dyed LOCALISE", + // eMinecraftColour_NOT_SET, true)); + // } + // } + + // 4J: Lore isn't in use in game + /*if (display->contains(L"Lore")) + { + ListTag *lore = (ListTag *) + display->getList(L"Lore"); if (lore->size() > 0) + { + for (int i = 0; i < lore->size(); i++) + { + //lines->push_back(ChatFormatting::DARK_PURPLE + + "" + ChatFormatting::ITALIC + lore->get(i)->data); + lines->push_back(lore->get(i)->data); + } + } + }*/ + } } + + attrAttrModMap* modifiers = getAttributeModifiers(); + + if (!modifiers->empty()) { + // New line + lines->push_back(HtmlString(L"")); + + // Modifier descriptions + for (AUTO_VAR(it, modifiers->begin()); it != modifiers->end(); ++it) { + // 4J: Moved modifier string building to AttributeModifier + lines->push_back(it->second->getHoverText(it->first)); + } + } + + // Delete modifiers map + for (AUTO_VAR(it, modifiers->begin()); it != modifiers->end(); ++it) { + AttributeModifier* modifier = it->second; + delete modifier; + } + delete modifiers; + + if (advanced) { + if (isDamaged()) { + std::wstring damageStr = + L"Durability: LOCALISE " + + _toString((getMaxDamage()) - getDamageValue()) + L" / " + + _toString(getMaxDamage()); + lines->push_back(HtmlString(damageStr)); + } + } + return lines; } // 4J Added -std::vector* ItemInstance::getHoverTextOnly( - std::shared_ptr player, bool advanced, - std::vector& unformattedStrings) { - std::vector* lines = new std::vector(); +std::vector* ItemInstance::getHoverTextOnly( + std::shared_ptr player, bool advanced) { + std::vector* lines = new std::vector(); Item* item = Item::items[id]; - item->appendHoverText(shared_from_this(), player, lines, advanced, - unformattedStrings); + item->appendHoverText(shared_from_this(), player, lines, advanced); if (hasTag()) { ListTag* list = getEnchantmentTags(); @@ -495,9 +600,7 @@ std::vector* ItemInstance::getHoverTextOnly( if (Enchantment::enchantments[type] != NULL) { std::wstring unformatted = L""; lines->push_back( - Enchantment::enchantments[type]->getFullname( - level, unformatted)); - unformattedStrings.push_back(unformatted); + Enchantment::enchantments[type]->getFullname(level)); } } } @@ -536,11 +639,65 @@ bool ItemInstance::isEnchanted() { void ItemInstance::addTagElement(std::wstring name, Tag* tag) { if (this->tag == NULL) { - this->setTag(new CompoundTag()); + setTag(new CompoundTag()); } this->tag->put((wchar_t*)name.c_str(), tag); } +bool ItemInstance::mayBePlacedInAdventureMode() { + return getItem()->mayBePlacedInAdventureMode(); +} + +bool ItemInstance::isFramed() { return frame != NULL; } + +void ItemInstance::setFramed(std::shared_ptr frame) { + this->frame = frame; +} + +std::shared_ptr ItemInstance::getFrame() { return frame; } + +int ItemInstance::getBaseRepairCost() { + if (hasTag() && tag->contains(L"RepairCost")) { + return tag->getInt(L"RepairCost"); + } else { + return 0; + } +} + +void ItemInstance::setRepairCost(int cost) { + if (!hasTag()) tag = new CompoundTag(); + tag->putInt(L"RepairCost", cost); +} + +attrAttrModMap* ItemInstance::getAttributeModifiers() { + attrAttrModMap* result = NULL; + + if (hasTag() && tag->contains(L"AttributeModifiers")) { + result = new attrAttrModMap(); + ListTag* entries = + (ListTag*)tag->getList(L"AttributeModifiers"); + + for (int i = 0; i < entries->size(); i++) { + CompoundTag* entry = entries->get(i); + AttributeModifier* attribute = + SharedMonsterAttributes::loadAttributeModifier(entry); + + // 4J Not sure why but this is a check that the attribute ID is not + // empty + /*if (attribute->getId()->getLeastSignificantBits() != 0 && + attribute->getId()->getMostSignificantBits() != 0) + {*/ + result->insert(std::pair( + static_cast(entry->getInt(L"ID")), attribute)); + /*}*/ + } + } else { + result = getItem()->getDefaultAttributeModifiers(); + } + + return result; +} + void ItemInstance::set4JData(int data) { if (tag == NULL && data == 0) return; if (tag == NULL) this->setTag(new CompoundTag()); @@ -583,27 +740,4 @@ int ItemInstance::GetPotionStrength() { } else { return (auxValue & MASK_LEVEL2EXTENDED) >> 5; } -} - -// TU9 - -bool ItemInstance::isFramed() { return frame != NULL; } - -void ItemInstance::setFramed(std::shared_ptr frame) { - this->frame = frame; -} - -std::shared_ptr ItemInstance::getFrame() { return frame; } - -int ItemInstance::getBaseRepairCost() { - if (hasTag() && tag->contains(L"RepairCost")) { - return tag->getInt(L"RepairCost"); - } else { - return 0; - } -} - -void ItemInstance::setRepairCost(int cost) { - if (!hasTag()) tag = new CompoundTag(); - tag->putInt(L"RepairCost", cost); -} +} \ No newline at end of file diff --git a/Minecraft.World/Items/ItemInstance.h b/Minecraft.World/Items/ItemInstance.h index 9fb7bfebe..5ae064695 100644 --- a/Minecraft.World/Items/ItemInstance.h +++ b/Minecraft.World/Items/ItemInstance.h @@ -2,24 +2,30 @@ #include "../Util/UseAnim.h" #include "../Headers/com.mojang.nbt.h" +#include "../AI/Attributes/Attribute.h" class Entity; class Level; class Player; class Mob; +class LivingEntity; class CompoundTag; class Enchantment; class Rarity; +class AttributeModifier; +class Random; // 4J-PB - added class MapItem; class ItemFrame; class Icon; +class HtmlString; // 4J Stu - While this is not really an abstract class, we don't want to make // new instances of it, mainly because there are too many ctors and that doesn't // fit well into out macroisation setup class ItemInstance : public std::enable_shared_from_this { public: + static const std::wstring ATTRIBUTE_MODIFIER_FORMAT; static const wchar_t* TAG_ENCH_ID; static const wchar_t* TAG_ENCH_LEVEL; @@ -70,10 +76,11 @@ public: Icon* getIcon(); int getIconType(); bool useOn(std::shared_ptr player, Level* level, int x, int y, - int z, int face, float clickX = 0.0f, float clickY = 0.0f, - float clickZ = 0.0f, bool bTestUseOnOnly = false); + int z, int face, float clickX, float clickY, float clickZ, + bool bTestUseOnOnly = false); float getDestroySpeed(Tile* tile); - bool TestUse(Level* level, std::shared_ptr player); + bool TestUse(std::shared_ptr itemInstance, Level* level, + std::shared_ptr player); std::shared_ptr use(Level* level, std::shared_ptr player); std::shared_ptr useTimeDepleted( @@ -89,13 +96,15 @@ public: int getAuxValue() const; void setAuxValue(int value); int getMaxDamage(); - void hurt(int i, std::shared_ptr owner); - void hurtEnemy(std::shared_ptr mob, std::shared_ptr attacker); + bool hurt(int dmg, Random* random); + void hurtAndBreak(int dmg, std::shared_ptr owner); + void hurtEnemy(std::shared_ptr mob, + std::shared_ptr attacker); void mineBlock(Level* level, int tile, int x, int y, int z, std::shared_ptr owner); - int getAttackDamage(std::shared_ptr entity); bool canDestroySpecial(Tile* tile); - bool interactEnemy(std::shared_ptr mob); + bool interactEnemy(std::shared_ptr player, + std::shared_ptr mob); std::shared_ptr copy() const; ItemInstance* copy_not_shared() const; // 4J Stu - Added for use in recipes static bool tagMatches( @@ -147,31 +156,29 @@ public: void setTag(CompoundTag* tag); std::wstring getHoverName(); void setHoverName(const std::wstring& name); + void resetHoverName(); bool hasCustomHoverName(); - std::vector* getHoverText( - std::shared_ptr player, bool advanced, - std::vector& unformattedStrings); - std::vector* getHoverTextOnly( - std::shared_ptr player, bool advanced, - std::vector& unformattedStrings); // 4J Added + std::vector* getHoverText(std::shared_ptr player, + bool advanced); + std::vector* getHoverTextOnly(std::shared_ptr player, + bool advanced); // 4J Added bool isFoil(); const Rarity* getRarity(); bool isEnchantable(); void enchant(const Enchantment* enchantment, int level); bool isEnchanted(); void addTagElement(std::wstring name, Tag* tag); + bool mayBePlacedInAdventureMode(); + bool isFramed(); + void setFramed(std::shared_ptr frame); + std::shared_ptr getFrame(); + int getBaseRepairCost(); + void setRepairCost(int cost); + attrAttrModMap* getAttributeModifiers(); // 4J Added void set4JData(int data); int get4JData(); bool hasPotionStrengthBar(); int GetPotionStrength(); - - // TU9 - bool isFramed(); - void setFramed(std::shared_ptr frame); - std::shared_ptr getFrame(); - - int getBaseRepairCost(); - void setRepairCost(int cost); -}; +}; \ No newline at end of file diff --git a/Minecraft.World/Items/LeashItem.cpp b/Minecraft.World/Items/LeashItem.cpp new file mode 100644 index 000000000..a00d296a1 --- /dev/null +++ b/Minecraft.World/Items/LeashItem.cpp @@ -0,0 +1,74 @@ +#include "../Platform/stdafx.h" +#include "../Headers/net.minecraft.world.level.tile.h" +#include "../Headers/net.minecraft.world.level.h" +#include "../Headers/net.minecraft.world.entity.h" +#include "../Headers/net.minecraft.world.phys.h" +#include "LeashItem.h" + +LeashItem::LeashItem(int id) : Item(id) {} + +bool LeashItem::useOn(std::shared_ptr itemInstance, + std::shared_ptr player, Level* level, int x, + int y, int z, int face, float clickX, float clickY, + float clickZ, bool bTestUseOnOnly) { + int tile = level->getTile(x, y, z); + if (Tile::tiles[tile] != NULL && + Tile::tiles[tile]->getRenderShape() == Tile::SHAPE_FENCE) { + if (bTestUseOnOnly) return bindPlayerMobsTest(player, level, x, y, z); + + if (level->isClientSide) { + return true; + } + + bindPlayerMobs(player, level, x, y, z); + return true; + } + return false; +} + +bool LeashItem::bindPlayerMobs(std::shared_ptr player, Level* level, + int x, int y, int z) { + // check if there is a knot at the given coordinate + std::shared_ptr activeKnot = + LeashFenceKnotEntity::findKnotAt(level, x, y, z); + + // look for entities that can be attached to the fence + bool foundMobs = false; + double range = 7; + std::vector >* mobs = level->getEntitiesOfClass( + typeid(Mob), AABB::newTemp(x - range, y - range, z - range, x + range, + y + range, z + range)); + if (mobs != NULL) { + for (AUTO_VAR(it, mobs->begin()); it != mobs->end(); ++it) { + std::shared_ptr mob = std::dynamic_pointer_cast(*it); + if (mob->isLeashed() && mob->getLeashHolder() == player) { + if (activeKnot == NULL) { + activeKnot = + LeashFenceKnotEntity::createAndAddKnot(level, x, y, z); + } + mob->setLeashedTo(activeKnot, true); + foundMobs = true; + } + } + } + return foundMobs; +} + +// 4J-JEV: Similar to bindPlayerMobs, but doesn't actually bind mobs, +bool LeashItem::bindPlayerMobsTest(std::shared_ptr player, Level* level, + int x, int y, int z) { + // look for entities that can be attached to the fence + double range = 7; + std::vector >* mobs = level->getEntitiesOfClass( + typeid(Mob), AABB::newTemp(x - range, y - range, z - range, x + range, + y + range, z + range)); + + if (mobs != NULL) { + for (AUTO_VAR(it, mobs->begin()); it != mobs->end(); ++it) { + std::shared_ptr mob = std::dynamic_pointer_cast(*it); + if (mob->isLeashed() && mob->getLeashHolder() == player) + return true; + } + } + return false; +} \ No newline at end of file diff --git a/Minecraft.World/Items/LeashItem.h b/Minecraft.World/Items/LeashItem.h new file mode 100644 index 000000000..259e310c2 --- /dev/null +++ b/Minecraft.World/Items/LeashItem.h @@ -0,0 +1,17 @@ +#pragma once + +#include "Item.h" + +class LeashItem : public Item { +public: + LeashItem(int id); + + bool useOn(std::shared_ptr itemInstance, + std::shared_ptr player, Level* level, int x, int y, + int z, int face, float clickX, float clickY, float clickZ, + bool bTestUseOnOnly = false); + static bool bindPlayerMobs(std::shared_ptr player, Level* level, + int x, int y, int z); + static bool bindPlayerMobsTest(std::shared_ptr player, Level* level, + int x, int y, int z); +}; \ No newline at end of file diff --git a/Minecraft.World/Items/MapItem.cpp b/Minecraft.World/Items/MapItem.cpp index 2c11e6593..d482f0b67 100644 --- a/Minecraft.World/Items/MapItem.cpp +++ b/Minecraft.World/Items/MapItem.cpp @@ -14,7 +14,7 @@ #include "../Headers/net.minecraft.world.inventory.h" #include "../Util/JavaMath.h" -MapItem::MapItem(int id) : ComplexItem(id) { this->setMaxStackSize(1); } +MapItem::MapItem(int id) : ComplexItem(id) { setStackedByData(true); } std::shared_ptr MapItem::getSavedData(short idNum, Level* level) { @@ -94,7 +94,8 @@ std::shared_ptr MapItem::getSavedData( void MapItem::update(Level* level, std::shared_ptr player, std::shared_ptr data) { - if (level->dimension->id != data->dimension) { + if ((level->dimension->id != data->dimension) || + !player->instanceof(eTYPE_PLAYER)) { // Wrong dimension, abort return; } @@ -114,10 +115,12 @@ void MapItem::update(Level* level, std::shared_ptr player, if (level->dimension->hasCeiling) { rad /= 2; } - data->step++; + std::shared_ptr hp = + data->getHoldingPlayer(std::dynamic_pointer_cast(player)); + hp->step++; for (int x = xp - rad + 1; x < xp + rad; x++) { - if ((x & 15) != (data->step & 15)) continue; + if ((x & 15) != (hp->step & 15)) continue; int yd0 = 255; int yd1 = 0; @@ -134,10 +137,6 @@ void MapItem::update(Level* level, std::shared_ptr player, int xx = (xo / scale + x - w / 2) * scale; int zz = (zo / scale + z - h / 2) * scale; - int r = 0; - int g = 0; - int b = 0; - int count[256]; memset(count, 0, sizeof(int) * 256); @@ -154,7 +153,7 @@ void MapItem::update(Level* level, std::shared_ptr player, if (((ss >> 20) & 1) == 0) count[Tile::dirt_Id] += 10; else - count[Tile::rock_Id] += 10; + count[Tile::stone_Id] += 10; hh = 100; } else { for (int xs = 0; xs < scale; xs++) { @@ -202,9 +201,6 @@ void MapItem::update(Level* level, std::shared_ptr player, } } liquidDepth /= scale * scale; - r /= scale * scale; - g /= scale * scale; - b /= scale * scale; int best = 0; int tBest = 0; @@ -260,7 +256,7 @@ void MapItem::inventoryTick(std::shared_ptr itemInstance, if (level->isClientSide) return; std::shared_ptr data = getSavedData(itemInstance, level); - if (std::dynamic_pointer_cast(owner) != NULL) { + if (owner->instanceof(eTYPE_PLAYER)) { std::shared_ptr player = std::dynamic_pointer_cast(owner); @@ -293,6 +289,21 @@ void MapItem::inventoryTick(std::shared_ptr itemInstance, } } +std::shared_ptr MapItem::getUpdatePacket( + std::shared_ptr itemInstance, Level* level, + std::shared_ptr player) { + charArray data = MapItem::getSavedData(itemInstance, level) + ->getUpdatePacket(itemInstance, level, player); + + if (data.data == NULL || data.length == 0) return nullptr; + + std::shared_ptr retval = + std::shared_ptr(new ComplexItemDataPacket( + (short)Item::map->id, (short)itemInstance->getAuxValue(), data)); + delete data.data; + return retval; +} + void MapItem::onCraftedBy(std::shared_ptr itemInstance, Level* level, std::shared_ptr player) { wchar_t buf[64]; @@ -333,17 +344,20 @@ void MapItem::onCraftedBy(std::shared_ptr itemInstance, data->setDirty(); } -std::shared_ptr MapItem::getUpdatePacket( - std::shared_ptr itemInstance, Level* level, - std::shared_ptr player) { - charArray data = MapItem::getSavedData(itemInstance, level) - ->getUpdatePacket(itemInstance, level, player); +// 4J - Don't want +/* +void appendHoverText(ItemInstance itemInstance, Player player, List +lines, boolean advanced) { MapItemSavedData data = getSavedData(itemInstance, +player.level); - if (data.data == NULL || data.length == 0) return nullptr; - - std::shared_ptr retval = - std::shared_ptr(new ComplexItemDataPacket( - (short)Item::map->id, (short)itemInstance->getAuxValue(), data)); - delete[] data.data; // 4jcraft, changed to [] - return retval; + if (advanced) { + if (data == null) { + lines.add("Unknown map"); + } else { + lines.add("Scaling at 1:" + (1 << data.scale)); + lines.add("(Level " + data.scale + "/" + +MapItemSavedData.MAX_SCALE + ")"); + } + } } +*/ diff --git a/Minecraft.World/Items/MapItem.h b/Minecraft.World/Items/MapItem.h index 1b6cee88f..babf038cf 100644 --- a/Minecraft.World/Items/MapItem.h +++ b/Minecraft.World/Items/MapItem.h @@ -22,9 +22,9 @@ public: // 4J Stu - Was protected in Java, but then we can't access it where we virtual void inventoryTick(std::shared_ptr itemInstance, Level* level, std::shared_ptr owner, int slot, bool selected); - virtual void onCraftedBy(std::shared_ptr itemInstance, - Level* level, std::shared_ptr player); std::shared_ptr getUpdatePacket( std::shared_ptr itemInstance, Level* level, std::shared_ptr player); + virtual void onCraftedBy(std::shared_ptr itemInstance, + Level* level, std::shared_ptr player); }; diff --git a/Minecraft.World/Items/MinecartItem.cpp b/Minecraft.World/Items/MinecartItem.cpp index 95dc3545f..d73746206 100644 --- a/Minecraft.World/Items/MinecartItem.cpp +++ b/Minecraft.World/Items/MinecartItem.cpp @@ -6,9 +6,64 @@ #include "ItemInstance.h" #include "MinecartItem.h" +std::shared_ptr MinecartItem::MinecartDispenseBehavior::execute( + BlockSource* source, std::shared_ptr dispensed, + eOUTCOME& outcome) { + FacingEnum* facing = DispenserTile::getFacing(source->getData()); + Level* world = source->getWorld(); + + // Spawn the minecart 'just' outside the dispenser, it overlaps 2 'pixels' + // now. Also at half-block-height so it can connect with sloped rails + double spawnX = source->getX() + facing->getStepX() * (1 + 2.0f / 16); + double spawnY = source->getY() + facing->getStepY() * (1 + 2.0f / 16); + double spawnZ = source->getZ() + facing->getStepZ() * (1 + 2.0f / 16); + + int frontX = source->getBlockX() + facing->getStepX(); + int frontY = source->getBlockY() + facing->getStepY(); + int frontZ = source->getBlockZ() + facing->getStepZ(); + int inFront = world->getTile(frontX, frontY, frontZ); + + // 4J: If we're at limit, just dispense item (instead of adding minecart) + if (world->countInstanceOf(eTYPE_MINECART, false) >= + Level::MAX_CONSOLE_MINECARTS) { + outcome = DISPENCED_ITEM; + return defaultDispenseItemBehavior.dispense(source, dispensed); + } + + double yOffset; + if (BaseRailTile::isRail(inFront)) { + yOffset = 0; + } else if (inFront == 0 && BaseRailTile::isRail(world->getTile( + frontX, frontY - 1, frontZ))) { + yOffset = -1; + } else { + outcome = DISPENCED_ITEM; + return defaultDispenseItemBehavior.dispense(source, dispensed); + } + + outcome = ACTIVATED_ITEM; + + std::shared_ptr minecart = + Minecart::createMinecart(world, spawnX, spawnY + yOffset, spawnZ, + ((MinecartItem*)dispensed->getItem())->type); + if (dispensed->hasCustomHoverName()) { + minecart->setCustomName(dispensed->getHoverName()); + } + world->addEntity(minecart); + + dispensed->remove(1); + return dispensed; +} + +void MinecartItem::MinecartDispenseBehavior::playSound(BlockSource* source) { + source->getWorld()->levelEvent(LevelEvent::SOUND_CLICK, source->getBlockX(), + source->getBlockY(), source->getBlockZ(), 0); +} + MinecartItem::MinecartItem(int id, int type) : Item(id) { - this->maxStackSize = 1; + maxStackSize = 1; this->type = type; + DispenserTile::REGISTRY.add(this, new MinecartDispenseBehavior()); } bool MinecartItem::useOn(std::shared_ptr instance, @@ -18,11 +73,15 @@ bool MinecartItem::useOn(std::shared_ptr instance, // 4J-PB - Adding a test only version to allow tooltips to be displayed int targetType = level->getTile(x, y, z); - if (RailTile::isRail(targetType)) { + if (BaseRailTile::isRail(targetType)) { if (!bTestUseOnOnly) { if (!level->isClientSide) { - level->addEntity(std::shared_ptr( - new Minecart(level, x + 0.5f, y + 0.5f, z + 0.5f, type))); + std::shared_ptr cart = Minecart::createMinecart( + level, x + 0.5f, y + 0.5f, z + 0.5f, type); + if (instance->hasCustomHoverName()) { + cart->setCustomName(instance->getHoverName()); + } + level->addEntity(cart); } instance->count--; } diff --git a/Minecraft.World/Items/MinecartItem.h b/Minecraft.World/Items/MinecartItem.h index f9d572fed..21673e2cc 100644 --- a/Minecraft.World/Items/MinecartItem.h +++ b/Minecraft.World/Items/MinecartItem.h @@ -1,8 +1,23 @@ #pragma once #include "Item.h" +#include "../Core/DefaultDispenseItemBehavior.h" class MinecartItem : public Item { +private: + class MinecartDispenseBehavior : public DefaultDispenseItemBehavior { + private: + DefaultDispenseItemBehavior defaultDispenseItemBehavior; + + public: + virtual std::shared_ptr execute( + BlockSource* source, std::shared_ptr dispensed, + eOUTCOME& outcome); + + protected: + virtual void playSound(BlockSource* source); + }; + public: int type; diff --git a/Minecraft.World/Items/NameTagItem.cpp b/Minecraft.World/Items/NameTagItem.cpp new file mode 100644 index 000000000..1b3f7938d --- /dev/null +++ b/Minecraft.World/Items/NameTagItem.cpp @@ -0,0 +1,21 @@ +#include "../Platform/stdafx.h" +#include "../Headers/net.minecraft.world.entity.h" +#include "NameTagItem.h" + +NameTagItem::NameTagItem(int id) : Item(id) {} + +bool NameTagItem::interactEnemy(std::shared_ptr itemInstance, + std::shared_ptr player, + std::shared_ptr target) { + if (!itemInstance->hasCustomHoverName()) return false; + + if ((target != NULL) && target->instanceof(eTYPE_MOB)) { + std::shared_ptr mob = std::dynamic_pointer_cast(target); + mob->setCustomName(itemInstance->getHoverName()); + mob->setPersistenceRequired(); + itemInstance->count--; + return true; + } + + return Item::interactEnemy(itemInstance, player, target); +} \ No newline at end of file diff --git a/Minecraft.World/Items/NameTagItem.h b/Minecraft.World/Items/NameTagItem.h new file mode 100644 index 000000000..c077e2463 --- /dev/null +++ b/Minecraft.World/Items/NameTagItem.h @@ -0,0 +1,12 @@ +#pragma once + +#include "Item.h" + +class NameTagItem : public Item { +public: + NameTagItem(int id); + + bool interactEnemy(std::shared_ptr itemInstance, + std::shared_ptr player, + std::shared_ptr target); +}; \ No newline at end of file diff --git a/Minecraft.World/Items/PickaxeItem.cpp b/Minecraft.World/Items/PickaxeItem.cpp index b591c0de3..88076ff22 100644 --- a/Minecraft.World/Items/PickaxeItem.cpp +++ b/Minecraft.World/Items/PickaxeItem.cpp @@ -2,37 +2,37 @@ #include "../Headers/net.minecraft.world.level.tile.h" #include "PickaxeItem.h" -TileArray* PickaxeItem::diggables = NULL; +TileArray PickaxeItem::diggables; void PickaxeItem::staticCtor() { - PickaxeItem::diggables = new TileArray(PICKAXE_DIGGABLES); - diggables->data[0] = Tile::stoneBrick; - diggables->data[1] = Tile::stoneSlab; - diggables->data[2] = Tile::stoneSlabHalf; - diggables->data[3] = Tile::rock; - diggables->data[4] = Tile::sandStone; - diggables->data[5] = Tile::mossStone; - diggables->data[6] = Tile::ironOre; - diggables->data[7] = Tile::ironBlock; - diggables->data[8] = Tile::coalOre; - diggables->data[9] = Tile::goldBlock; - diggables->data[10] = Tile::goldOre; - diggables->data[11] = Tile::diamondOre; - diggables->data[12] = Tile::diamondBlock; - diggables->data[13] = Tile::ice; - diggables->data[14] = Tile::hellRock; - diggables->data[15] = Tile::lapisOre; - diggables->data[16] = Tile::lapisBlock; - // 4J - brought forward from 1.2.3 - diggables->data[17] = Tile::redStoneOre; - diggables->data[18] = Tile::redStoneOre_lit; - diggables->data[19] = Tile::rail; - diggables->data[20] = Tile::detectorRail; - diggables->data[21] = Tile::goldenRail; + PickaxeItem::diggables = TileArray(PICKAXE_DIGGABLES); + diggables.data[0] = Tile::cobblestone; + diggables.data[1] = Tile::stoneSlab; + diggables.data[2] = Tile::stoneSlabHalf; + diggables.data[3] = Tile::stone; + diggables.data[4] = Tile::sandStone; + diggables.data[5] = Tile::mossyCobblestone; + diggables.data[6] = Tile::ironOre; + diggables.data[7] = Tile::ironBlock; + diggables.data[8] = Tile::coalOre; + diggables.data[9] = Tile::goldBlock; + diggables.data[10] = Tile::goldOre; + diggables.data[11] = Tile::diamondOre; + diggables.data[12] = Tile::diamondBlock; + diggables.data[13] = Tile::ice; + diggables.data[14] = Tile::netherRack; + diggables.data[15] = Tile::lapisOre; + diggables.data[16] = Tile::lapisBlock; + diggables.data[17] = Tile::redStoneOre; + diggables.data[18] = Tile::redStoneOre_lit; + diggables.data[19] = Tile::rail; + diggables.data[20] = Tile::detectorRail; + diggables.data[21] = Tile::goldenRail; + diggables.data[21] = Tile::activatorRail; } PickaxeItem::PickaxeItem(int id, const Tier* tier) - : DiggerItem(id, 2, tier, diggables) {} + : DiggerItem(id, 2, tier, &diggables) {} bool PickaxeItem::canDestroySpecial(Tile* tile) { if (tile == Tile::obsidian) return tier->getLevel() == 3; diff --git a/Minecraft.World/Items/PickaxeItem.h b/Minecraft.World/Items/PickaxeItem.h index 4e9dc2d4a..082428257 100644 --- a/Minecraft.World/Items/PickaxeItem.h +++ b/Minecraft.World/Items/PickaxeItem.h @@ -2,11 +2,11 @@ #include "DiggerItem.h" -#define PICKAXE_DIGGABLES 22 +#define PICKAXE_DIGGABLES 23 class PickaxeItem : public DiggerItem { private: - static TileArray* diggables; + static TileArray diggables; public: // static void staticCtor(); diff --git a/Minecraft.World/Items/PotionItem.cpp b/Minecraft.World/Items/PotionItem.cpp index 898aa7e77..502c382e1 100644 --- a/Minecraft.World/Items/PotionItem.cpp +++ b/Minecraft.World/Items/PotionItem.cpp @@ -3,6 +3,7 @@ #include "../Headers/net.minecraft.world.item.alchemy.h" #include "../Headers/net.minecraft.world.effect.h" #include "../Headers/net.minecraft.world.level.h" +#include "../Headers/net.minecraft.world.entity.ai.attributes.h" #include "../Headers/net.minecraft.world.entity.player.h" #include "../Headers/net.minecraft.world.entity.projectile.h" #include "../Headers/net.minecraft.world.h" @@ -31,7 +32,33 @@ PotionItem::PotionItem(int id) : Item(id) { std::vector* PotionItem::getMobEffects( std::shared_ptr potion) { - return getMobEffects(potion->getAuxValue()); + if (!potion->hasTag() || + !potion->getTag()->contains(L"CustomPotionEffects")) { + std::vector* effects = NULL; + AUTO_VAR(it, cachedMobEffects.find(potion->getAuxValue())); + if (it != cachedMobEffects.end()) effects = it->second; + if (effects == NULL) { + effects = PotionBrewing::getEffects(potion->getAuxValue(), false); + cachedMobEffects[potion->getAuxValue()] = effects; + } + + // Result should be a new (unmanaged) vector, so create a new one + return effects == NULL ? NULL + : new std::vector(*effects); + } else { + std::vector* effects = + new std::vector(); + ListTag* customList = + (ListTag*)potion->getTag()->getList( + L"CustomPotionEffects"); + + for (int i = 0; i < customList->size(); i++) { + CompoundTag* tag = customList->get(i); + effects->push_back(MobEffectInstance::load(tag)); + } + + return effects; + } } std::vector* PotionItem::getMobEffects(int auxValue) { @@ -84,7 +111,8 @@ UseAnim PotionItem::getUseAnimation( return UseAnim_drink; } -bool PotionItem::TestUse(Level* level, std::shared_ptr player) { +bool PotionItem::TestUse(std::shared_ptr itemInstance, + Level* level, std::shared_ptr player) { return true; } @@ -93,8 +121,8 @@ std::shared_ptr PotionItem::use( std::shared_ptr player) { if (isThrowable(instance->getAuxValue())) { if (!player->abilities.instabuild) instance->count--; - level->playSound(player, eSoundType_RANDOM_BOW, 0.5f, - 0.4f / (random->nextFloat() * 0.4f + 0.8f)); + level->playEntitySound(player, eSoundType_RANDOM_BOW, 0.5f, + 0.4f / (random->nextFloat() * 0.4f + 0.8f)); if (!level->isClientSide) level->addEntity(std::shared_ptr( new ThrownPotion(level, player, instance->getAuxValue()))); @@ -198,22 +226,46 @@ std::wstring PotionItem::getHoverName( return elementName; } -void PotionItem::appendHoverText( - std::shared_ptr itemInstance, std::shared_ptr player, - std::vector* lines, bool advanced, - std::vector& unformattedStrings) { +void PotionItem::appendHoverText(std::shared_ptr itemInstance, + std::shared_ptr player, + std::vector* lines, + bool advanced) { if (itemInstance->getAuxValue() == 0) { return; } std::vector* effects = ((PotionItem*)Item::potion)->getMobEffects(itemInstance); + attrAttrModMap modifiers; if (effects != NULL && !effects->empty()) { // for (MobEffectInstance effect : effects) for (AUTO_VAR(it, effects->begin()); it != effects->end(); ++it) { MobEffectInstance* effect = *it; - std::wstring effectString = app.GetString( - effect - ->getDescriptionId()); // I18n.get(effect.getDescriptionId()).trim(); + std::wstring effectString = + app.GetString(effect->getDescriptionId()); + + MobEffect* mobEffect = MobEffect::effects[effect->getId()]; + std::unordered_map* + effectModifiers = mobEffect->getAttributeModifiers(); + + if (effectModifiers != NULL && effectModifiers->size() > 0) { + for (AUTO_VAR(it, effectModifiers->begin()); + it != effectModifiers->end(); ++it) { + // 4J - anonymous modifiers added here are destroyed + // shortly? + AttributeModifier* original = it->second; + AttributeModifier* modifier = new AttributeModifier( + mobEffect->getAttributeModifierValue( + effect->getAmplifier(), original), + original->getOperation()); + modifiers.insert( + std::pair( + it->first->getId(), modifier)); + } + } + + // Don't want to delete this (that's a pointer to mobEffects + // internal vector of modifiers) delete effectModifiers; + if (effect->getAmplifier() > 0) { std::wstring potencyString = L""; switch (effect->getAmplifier()) { @@ -241,44 +293,46 @@ void PotionItem::appendHoverText( effectString += L" (" + MobEffect::formatDuration(effect) + L")"; } - unformattedStrings.push_back(effectString); - wchar_t formatted[256]; - ZeroMemory(formatted, 256 * sizeof(wchar_t)); - eMinecraftColour colour = eMinecraftColour_NOT_SET; - if (MobEffect::effects[effect->getId()]->isHarmful()) { - colour = eHTMLColor_c; - // lines->push_back(L"�c + effectString); //"�c" + + eMinecraftColour color = eMinecraftColour_NOT_SET; + + if (mobEffect->isHarmful()) { + color = eHTMLColor_c; } else { - colour = eHTMLColor_7; - // lines->push_back(L"�7" + effectString); //"�7" + color = eHTMLColor_7; } - swprintf(formatted, 256, L"%ls", - app.GetHTMLColour(colour), effectString.c_str()); - lines->push_back(formatted); + + lines->push_back(HtmlString(effectString, color)); } } else { std::wstring effectString = app.GetString( IDS_POTION_EMPTY); // I18n.get("potion.empty").trim(); - // eHTMLColor_7 - wchar_t formatted[256]; - swprintf(formatted, 256, L"%ls", - app.GetHTMLColour(eHTMLColor_7), effectString.c_str()); - lines->push_back(formatted); //"�7" + + lines->push_back(HtmlString(effectString, eHTMLColor_7)); //"�7" + } + + if (!modifiers.empty()) { + // Add new line + lines->push_back(HtmlString(L"")); + lines->push_back(HtmlString(app.GetString(IDS_POTION_EFFECTS_WHENDRANK), + eHTMLColor_5)); + + // Add modifier descriptions + for (AUTO_VAR(it, modifiers.begin()); it != modifiers.end(); ++it) { + // 4J: Moved modifier string building to AttributeModifier + lines->push_back(it->second->getHoverText(it->first)); + } } } -bool PotionItem::isFoil(std::shared_ptr itemInstance) { +bool PotionItem::isFoistd::l(std::shared_ptr itemInstance) { std::vector* mobEffects = getMobEffects(itemInstance); return mobEffects != NULL && !mobEffects->empty(); } -unsigned int PotionItem::getUseDescriptionId( +unsigned int PotionItem::getUseDescriptionIstd::d( std::shared_ptr instance) { int brew = instance->getAuxValue(); - -#define MACRO_POTION_IS_NIGHTVISION(aux) ((aux & 0x200F) == MASK_NIGHTVISION) -#define MACRO_POTION_IS_INVISIBILITY(aux) ((aux & 0x200F) == MASK_INVISIBILITY) - if (brew == 0) return IDS_POTION_DESC_WATER_BOTTLE; else if (MACRO_POTION_IS_REGENERATION(brew)) @@ -312,7 +366,7 @@ void PotionItem::registerIcons(IconRegister* iconRegister) { iconOverlay = iconRegister->registerIcon(CONTENTS_ICON); } -Icon* PotionItem::getTexture(const std::wstring& name) { +Icon* PotionItem::getTexture(consstd::t std::wstring& name) { if (name.compare(DEFAULT_ICON) == 0) return Item::potion->iconDrinkable; if (name.compare(THROWABLE_ICON) == 0) return Item::potion->iconThrowable; if (name.compare(CONTENTS_ICON) == 0) return Item::potion->iconOverlay; diff --git a/Minecraft.World/Items/PotionItem.h b/Minecraft.World/Items/PotionItem.h index 60d34f247..84c11a9fd 100644 --- a/Minecraft.World/Items/PotionItem.h +++ b/Minecraft.World/Items/PotionItem.h @@ -34,7 +34,8 @@ public: virtual std::shared_ptr use( std::shared_ptr instance, Level* level, std::shared_ptr player); - virtual bool TestUse(Level* level, std::shared_ptr player); + virtual bool TestUse(std::shared_ptr itemInstance, + Level* level, std::shared_ptr player); virtual bool useOn(std::shared_ptr itemInstance, std::shared_ptr player, Level* level, int x, int y, int z, int face, float clickX, float clickY, @@ -50,9 +51,7 @@ public: std::shared_ptr itemInstance); virtual void appendHoverText(std::shared_ptr itemInstance, std::shared_ptr player, - std::vector* lines, - bool advanced, - std::vector& unformattedStrings); + std::vector* lines, bool advanced); virtual bool isFoil(std::shared_ptr itemInstance); virtual unsigned int getUseDescriptionId( diff --git a/Minecraft.World/Items/RecordingItem.cpp b/Minecraft.World/Items/RecordingItem.cpp index 741b3b702..3a9a280d0 100644 --- a/Minecraft.World/Items/RecordingItem.cpp +++ b/Minecraft.World/Items/RecordingItem.cpp @@ -2,14 +2,18 @@ #include "../Headers/net.minecraft.world.entity.player.h" #include "../Headers/net.minecraft.world.level.h" #include "../Headers/net.minecraft.world.level.tile.h" +#include "../Headers/net.minecraft.world.item.h" #include "../Headers/net.minecraft.world.h" #include "ItemInstance.h" #include "RecordingItem.h" #include "../Stats/GenericStats.h" +std::unordered_map RecordingItem::BY_NAME; + RecordingItem::RecordingItem(int id, const std::wstring& recording) : Item(id), recording(recording) { this->maxStackSize = 1; + BY_NAME[recording] = this; } Icon* RecordingItem::getIcon(int auxValue) { return icon; } @@ -19,13 +23,13 @@ bool RecordingItem::useOn(std::shared_ptr itemInstance, int y, int z, int face, float clickX, float clickY, float clickZ, bool bTestUseOnOnly) { // 4J-PB - Adding a test only version to allow tooltips to be displayed - if (level->getTile(x, y, z) == Tile::recordPlayer_Id && + if (level->getTile(x, y, z) == Tile::jukebox_Id && level->getData(x, y, z) == 0) { if (!bTestUseOnOnly) { if (level->isClientSide) return true; - ((RecordPlayerTile*)Tile::recordPlayer) - ->setRecord(level, x, y, z, id); + ((JukeboxTile*)Tile::jukebox) + ->setRecord(level, x, y, z, itemInstance); level->levelEvent(nullptr, LevelEvent::SOUND_PLAY_RECORDING, x, y, z, id); itemInstance->count--; @@ -38,21 +42,16 @@ bool RecordingItem::useOn(std::shared_ptr itemInstance, return false; } -void RecordingItem::appendHoverText( - std::shared_ptr itemInstance, std::shared_ptr player, - std::vector* lines, bool advanced, - std::vector& unformattedStrings) { - eMinecraftColour rarityColour = - getRarity(std::shared_ptr())->color; - int colour = app.GetHTMLColour(rarityColour); - wchar_t formatted[256]; +void RecordingItem::appendHoverText(std::shared_ptr itemInstance, + std::shared_ptr player, + std::vector* lines, + bool advanced) { + eMinecraftColour color = getRarity(std::shared_ptr())->color; - swprintf(formatted, 256, L"%ls", colour, - L"C418 - ", recording.c_str()); + wchar_t text[256]; + swprintf(text, 256, L"%ls %ls", L"C418 -", recording.c_str()); - lines->push_back(formatted); - - unformattedStrings.push_back(recording); + lines->push_back(HtmlString(text, color)); } const Rarity* RecordingItem::getRarity( @@ -63,3 +62,12 @@ const Rarity* RecordingItem::getRarity( void RecordingItem::registerIcons(IconRegister* iconRegister) { icon = iconRegister->registerIcon(L"record_" + recording); } + +RecordingItem* RecordingItem::getByName(const std::wstring& name) { + AUTO_VAR(it, BY_NAME.find(name)); + if (it != BY_NAME.end()) { + return it->second; + } else { + return NULL; + } +} \ No newline at end of file diff --git a/Minecraft.World/Items/RecordingItem.h b/Minecraft.World/Items/RecordingItem.h index e1c1e8235..6207bab53 100644 --- a/Minecraft.World/Items/RecordingItem.h +++ b/Minecraft.World/Items/RecordingItem.h @@ -3,6 +3,9 @@ #include "Item.h" class RecordingItem : public Item { +private: + static std::unordered_map BY_NAME; + public: const std::wstring recording; @@ -10,7 +13,6 @@ public : // 4J Stu - Was protected in Java, but the can't access it where we need RecordingItem(int id, const std::wstring& recording); - //@Override Icon* getIcon(int auxValue); virtual bool useOn(std::shared_ptr itemInstance, std::shared_ptr player, Level* level, int x, @@ -19,11 +21,9 @@ public virtual void appendHoverText(std::shared_ptr itemInstance, std::shared_ptr player, - std::vector* lines, - bool advanced, - std::vector& unformattedStrings); + std::vector* lines, bool advanced); virtual const Rarity* getRarity(std::shared_ptr itemInstance); - //@Override void registerIcons(IconRegister* iconRegister); + static RecordingItem* getByName(const std::wstring& name); }; \ No newline at end of file diff --git a/Minecraft.World/Items/RedstoneItem.cpp b/Minecraft.World/Items/RedstoneItem.cpp index bacfd7d6e..ef8454e08 100644 --- a/Minecraft.World/Items/RedstoneItem.cpp +++ b/Minecraft.World/Items/RedstoneItem.cpp @@ -22,7 +22,7 @@ bool RedStoneItem::useOn(std::shared_ptr itemInstance, if (face == 5) x++; if (!level->isEmptyTile(x, y, z)) return false; } - if (!player->mayBuild(x, y, z)) return false; + if (!player->mayUseItemAt(x, y, z, face, itemInstance)) return false; if (Tile::redStoneDust->mayPlace(level, x, y, z)) { if (!bTestUseOnOnly) { // 4J-JEV: Hook for durango 'BlockPlaced' event. @@ -32,7 +32,7 @@ bool RedStoneItem::useOn(std::shared_ptr itemInstance, Tile::redStoneDust_Id, itemInstance->getAuxValue(), 1)); itemInstance->count--; - level->setTile(x, y, z, Tile::redStoneDust_Id); + level->setTileAndUpdate(x, y, z, Tile::redStoneDust_Id); } } diff --git a/Minecraft.World/Items/SaddleItem.cpp b/Minecraft.World/Items/SaddleItem.cpp index e2ec5a500..811878ba6 100644 --- a/Minecraft.World/Items/SaddleItem.cpp +++ b/Minecraft.World/Items/SaddleItem.cpp @@ -7,8 +7,9 @@ SaddleItem::SaddleItem(int id) : Item(id) { maxStackSize = 1; } bool SaddleItem::interactEnemy(std::shared_ptr itemInstance, - std::shared_ptr mob) { - if (std::dynamic_pointer_cast(mob)) { + std::shared_ptr player, + std::shared_ptr mob) { + if ((mob != NULL) && mob->instanceof(eTYPE_PIG)) { std::shared_ptr pig = std::dynamic_pointer_cast(mob); if (!pig->hasSaddle() && !pig->isBaby()) { pig->setSaddle(true); @@ -20,8 +21,8 @@ bool SaddleItem::interactEnemy(std::shared_ptr itemInstance, } bool SaddleItem::hurtEnemy(std::shared_ptr itemInstance, - std::shared_ptr mob, - std::shared_ptr attacker) { - interactEnemy(itemInstance, mob); + std::shared_ptr mob, + std::shared_ptr attacker) { + interactEnemy(itemInstance, nullptr, mob); return true; } \ No newline at end of file diff --git a/Minecraft.World/Items/SaddleItem.h b/Minecraft.World/Items/SaddleItem.h index 6c124ec88..1da836b0f 100644 --- a/Minecraft.World/Items/SaddleItem.h +++ b/Minecraft.World/Items/SaddleItem.h @@ -7,8 +7,9 @@ public: SaddleItem(int id); virtual bool interactEnemy(std::shared_ptr itemInstance, - std::shared_ptr mob); + std::shared_ptr player, + std::shared_ptr mob); virtual bool hurtEnemy(std::shared_ptr itemInstance, - std::shared_ptr mob, - std::shared_ptr attacker); + std::shared_ptr mob, + std::shared_ptr attacker); }; \ No newline at end of file diff --git a/Minecraft.World/Items/SeedFoodItem.cpp b/Minecraft.World/Items/SeedFoodItem.cpp index b610b00fd..6962b0be1 100644 --- a/Minecraft.World/Items/SeedFoodItem.cpp +++ b/Minecraft.World/Items/SeedFoodItem.cpp @@ -17,13 +17,14 @@ bool SeedFoodItem::useOn(std::shared_ptr instance, float clickZ, bool bTestUseOnOnly) { if (face != Facing::UP) return false; - if (!player->mayBuild(x, y, z) || !player->mayBuild(x, y + 1, z)) + if (!player->mayUseItemAt(x, y, z, face, instance) || + !player->mayUseItemAt(x, y + 1, z, face, instance)) return false; int targetType = level->getTile(x, y, z); if (targetType == targetLand && level->isEmptyTile(x, y + 1, z)) { if (!bTestUseOnOnly) { - level->setTile(x, y + 1, z, resultId); + level->setTileAndUpdate(x, y + 1, z, resultId); instance->count--; } return true; diff --git a/Minecraft.World/Items/SeedItem.cpp b/Minecraft.World/Items/SeedItem.cpp index 841cf12b5..40393294f 100644 --- a/Minecraft.World/Items/SeedItem.cpp +++ b/Minecraft.World/Items/SeedItem.cpp @@ -1,5 +1,4 @@ - #include "../Platform/stdafx.h" #include "Item.h" #include "../Headers/net.minecraft.world.entity.player.h" @@ -20,14 +19,15 @@ bool SeedItem::useOn(std::shared_ptr instance, // 4J-PB - Adding a test only version to allow tooltips to be displayed if (face != 1) return false; - if (!player->mayBuild(x, y, z) || !player->mayBuild(x, y + 1, z)) + if (!player->mayUseItemAt(x, y, z, face, instance) || + !player->mayUseItemAt(x, y + 1, z, face, instance)) return false; int targetType = level->getTile(x, y, z); if (targetType == targetLand && level->isEmptyTile(x, y + 1, z)) { if (!bTestUseOnOnly) { - level->setTile(x, y + 1, z, resultId); + level->setTileAndUpdate(x, y + 1, z, resultId); instance->count--; } return true; diff --git a/Minecraft.World/Items/ShearsItem.cpp b/Minecraft.World/Items/ShearsItem.cpp index 7cd73f72b..e1b4c360d 100644 --- a/Minecraft.World/Items/ShearsItem.cpp +++ b/Minecraft.World/Items/ShearsItem.cpp @@ -10,11 +10,11 @@ ShearsItem::ShearsItem(int itemId) : Item(itemId) { bool ShearsItem::mineBlock(std::shared_ptr itemInstance, Level* level, int tile, int x, int y, int z, - std::shared_ptr owner) { + std::shared_ptr owner) { if (tile == Tile::leaves_Id || tile == Tile::web_Id || tile == Tile::tallgrass_Id || tile == Tile::vine_Id || tile == Tile::tripWire_Id) { - itemInstance->hurt(1, owner); + itemInstance->hurtAndBreak(1, owner); return true; } return Item::mineBlock(itemInstance, level, tile, x, y, z, owner); @@ -30,7 +30,7 @@ float ShearsItem::getDestroySpeed(std::shared_ptr itemInstance, if (tile->id == Tile::web_Id || tile->id == Tile::leaves_Id) { return 15; } - if (tile->id == Tile::cloth_Id) { + if (tile->id == Tile::wool_Id) { return 5; } return Item::getDestroySpeed(itemInstance, tile); diff --git a/Minecraft.World/Items/ShearsItem.h b/Minecraft.World/Items/ShearsItem.h index bbf49dd2f..c89041675 100644 --- a/Minecraft.World/Items/ShearsItem.h +++ b/Minecraft.World/Items/ShearsItem.h @@ -7,7 +7,7 @@ public: ShearsItem(int itemId); virtual bool mineBlock(std::shared_ptr itemInstance, Level* level, int tile, int x, int y, int z, - std::shared_ptr owner); + std::shared_ptr owner); virtual bool canDestroySpecial(Tile* tile); virtual float getDestroySpeed(std::shared_ptr itemInstance, Tile* tile); diff --git a/Minecraft.World/Items/ShovelItem.cpp b/Minecraft.World/Items/ShovelItem.cpp index e4af1a969..a96fa3c47 100644 --- a/Minecraft.World/Items/ShovelItem.cpp +++ b/Minecraft.World/Items/ShovelItem.cpp @@ -15,8 +15,7 @@ void ShovelItem::staticCtor() { diggables->data[5] = Tile::snow; diggables->data[6] = Tile::clay; diggables->data[7] = Tile::farmland; - // 4J - brought forward from 1.2.3 - diggables->data[8] = Tile::hellSand; + diggables->data[8] = Tile::soulsand; diggables->data[9] = Tile::mycel; } diff --git a/Minecraft.World/Items/SignItem.cpp b/Minecraft.World/Items/SignItem.cpp index 6d3a62dc4..eb07576f3 100644 --- a/Minecraft.World/Items/SignItem.cpp +++ b/Minecraft.World/Items/SignItem.cpp @@ -26,16 +26,22 @@ bool SignItem::useOn(std::shared_ptr instance, if (face == 4) x--; if (face == 5) x++; - if (!player->mayBuild(x, y, z)) return false; + if (!player->mayUseItemAt(x, y, z, face, instance)) return false; if (!Tile::sign->mayPlace(level, x, y, z)) return false; + if (level->isClientSide) { + return true; + } + if (!bTestUseOnOnly) { if (face == 1) { int rot = Mth::floor(((player->yRot + 180) * 16) / 360 + 0.5) & 15; - level->setTileAndData(x, y, z, Tile::sign_Id, rot); + level->setTileAndData(x, y, z, Tile::sign_Id, rot, + Tile::UPDATE_ALL); } else { - level->setTileAndData(x, y, z, Tile::wallSign_Id, face); + level->setTileAndData(x, y, z, Tile::wallSign_Id, face, + Tile::UPDATE_ALL); } instance->count--; diff --git a/Minecraft.World/Items/SimpleFoiledItem.cpp b/Minecraft.World/Items/SimpleFoiledItem.cpp new file mode 100644 index 000000000..06a176c12 --- /dev/null +++ b/Minecraft.World/Items/SimpleFoiledItem.cpp @@ -0,0 +1,9 @@ +#include "../Platform/stdafx.h" + +#include "SimpleFoiledItem.h" + +SimpleFoiledItem::SimpleFoiledItem(int id) : Item(id) {} + +bool SimpleFoiledItem::isFoil(std::shared_ptr itemInstance) { + return true; +} diff --git a/Minecraft.World/Items/SimpleFoiledItem.h b/Minecraft.World/Items/SimpleFoiledItem.h new file mode 100644 index 000000000..62479a753 --- /dev/null +++ b/Minecraft.World/Items/SimpleFoiledItem.h @@ -0,0 +1,10 @@ +#pragma once + +#include "Item.h" + +class SimpleFoiledItem : public Item { +public: + SimpleFoiledItem(int id); + + bool isFoil(std::shared_ptr itemInstance); +}; \ No newline at end of file diff --git a/Minecraft.World/Items/SnowItem.cpp b/Minecraft.World/Items/SnowItem.cpp new file mode 100644 index 000000000..b6196253e --- /dev/null +++ b/Minecraft.World/Items/SnowItem.cpp @@ -0,0 +1,49 @@ +#include "../Platform/stdafx.h" +#include "../Headers/net.minecraft.world.entity.player.h" +#include "../Headers/net.minecraft.world.level.tile.h" +#include "../Headers/net.minecraft.world.level.h" +#include "SnowItem.h" + +SnowItem::SnowItem(int id, Tile* parentTile) + : AuxDataTileItem(id, parentTile) {} + +bool SnowItem::useOn(std::shared_ptr instance, + std::shared_ptr player, Level* level, int x, int y, + int z, int face, float clickX, float clickY, float clickZ, + bool bTestUseOnOnly) { + if (instance->count == 0) return false; + if (!player->mayUseItemAt(x, y, z, face, instance)) return false; + + int currentTile = level->getTile(x, y, z); + + // Are we adding extra snow to an existing tile? + if (currentTile == Tile::topSnow_Id) { + Tile* snowTile = Tile::tiles[getTileId()]; + int currentData = level->getData(x, y, z); + int currentHeight = currentData & TopSnowTile::HEIGHT_MASK; + + if (currentHeight <= TopSnowTile::MAX_HEIGHT && + level->isUnobstructed(snowTile->getAABB(level, x, y, z))) { + if (!bTestUseOnOnly) { + // Increase snow tile height + if (level->setData( + x, y, z, + (currentHeight + 1) | + (currentData & ~TopSnowTile::HEIGHT_MASK), + Tile::UPDATE_CLIENTS)) { + level->playSound(x + 0.5f, y + 0.5f, z + 0.5f, + snowTile->soundType->getPlaceSound(), + (snowTile->soundType->getVolume() + 1) / 2, + snowTile->soundType->getPitch() * 0.8f); + instance->count--; + return true; + } + } else { + return true; + } + } + } + + return AuxDataTileItem::useOn(instance, player, level, x, y, z, face, + clickX, clickY, clickZ, bTestUseOnOnly); +} \ No newline at end of file diff --git a/Minecraft.World/Items/SnowItem.h b/Minecraft.World/Items/SnowItem.h new file mode 100644 index 000000000..02b4bca99 --- /dev/null +++ b/Minecraft.World/Items/SnowItem.h @@ -0,0 +1,13 @@ +#pragma once + +#include "TileItems/AuxDataTileItem.h" + +class SnowItem : public AuxDataTileItem { +public: + SnowItem(int id, Tile* parentTile); + + bool useOn(std::shared_ptr instance, + std::shared_ptr player, Level* level, int x, int y, + int z, int face, float clickX, float clickY, float clickZ, + bool bTestUseOnOnly = false); +}; \ No newline at end of file diff --git a/Minecraft.World/Items/SnowballItem.cpp b/Minecraft.World/Items/SnowballItem.cpp index b5799b2d9..fed115d79 100644 --- a/Minecraft.World/Items/SnowballItem.cpp +++ b/Minecraft.World/Items/SnowballItem.cpp @@ -14,8 +14,9 @@ std::shared_ptr SnowballItem::use( if (!player->abilities.instabuild) { instance->count--; } - level->playSound((std::shared_ptr)player, eSoundType_RANDOM_BOW, - 0.5f, 0.4f / (random->nextFloat() * 0.4f + 0.8f)); + level->playEntitySound((std::shared_ptr)player, + eSoundType_RANDOM_BOW, 0.5f, + 0.4f / (random->nextFloat() * 0.4f + 0.8f)); if (!level->isClientSide) level->addEntity( std::shared_ptr(new Snowball(level, player))); diff --git a/Minecraft.World/Items/MonsterPlacerItem.cpp b/Minecraft.World/Items/SpawnEggItem.cpp similarity index 50% rename from Minecraft.World/Items/MonsterPlacerItem.cpp rename to Minecraft.World/Items/SpawnEggItem.cpp index b0a35abad..bf6b24582 100644 --- a/Minecraft.World/Items/MonsterPlacerItem.cpp +++ b/Minecraft.World/Items/SpawnEggItem.cpp @@ -7,17 +7,18 @@ #include "../Headers/net.minecraft.world.entity.h" #include "../Headers/net.minecraft.world.entity.npc.h" #include "../Headers/net.minecraft.world.h" -#include "MonsterPlacerItem.h" +#include "../Util/HitResult.h" +#include "SpawnEggItem.h" #include "../Util/Difficulty.h" -MonsterPlacerItem::MonsterPlacerItem(int id) : Item(id) { +SpawnEggItem::SpawnEggItem(int id) : Item(id) { setMaxStackSize(16); // 4J-PB brought forward. It is 64 on PC, but we'll // never be able to place that many setStackedByData(true); overlay = NULL; } -std::wstring MonsterPlacerItem::getHoverName( +std::wstring SpawnEggItem::getHoverName( std::shared_ptr itemInstance) { std::wstring elementName = getDescription(); @@ -33,8 +34,8 @@ std::wstring MonsterPlacerItem::getHoverName( return elementName; } -int MonsterPlacerItem::getColor(std::shared_ptr item, - int spriteLayer) { +int SpawnEggItem::getColor(std::shared_ptr item, + int spriteLayer) { AUTO_VAR(it, EntityIO::idsSpawnableInCreative.find(item->getAuxValue())); if (it != EntityIO::idsSpawnableInCreative.end()) { EntityIO::SpawnableMobInfo* spawnableMobInfo = it->second; @@ -48,9 +49,9 @@ int MonsterPlacerItem::getColor(std::shared_ptr item, return 0xffffff; } -bool MonsterPlacerItem::hasMultipleSpriteLayers() { return true; } +bool SpawnEggItem::hasMultipleSpriteLayers() { return true; } -Icon* MonsterPlacerItem::getLayerIcon(int auxValue, int spriteLayer) { +Icon* SpawnEggItem::getLayerIcon(int auxValue, int spriteLayer) { if (spriteLayer > 0) { return overlay; } @@ -58,8 +59,8 @@ Icon* MonsterPlacerItem::getLayerIcon(int auxValue, int spriteLayer) { } // 4J-PB - added for dispenser -std::shared_ptr MonsterPlacerItem::canSpawn(int iAuxVal, Level* level, - int* piResult) { +std::shared_ptr SpawnEggItem::canSpawn(int iAuxVal, Level* level, + int* piResult) { std::shared_ptr newEntity = EntityIO::newById(iAuxVal, level); if (newEntity != NULL) { bool canSpawn = false; @@ -103,9 +104,16 @@ std::shared_ptr MonsterPlacerItem::canSpawn(int iAuxVal, Level* level, *piResult = eSpawnResult_FailTooManySquid; } break; + case eTYPE_BAT: + if (level->canCreateMore(eTYPE_BAT, Level::eSpawnType_Egg)) { + canSpawn = true; + } else { + *piResult = eSpawnResult_FailTooManyBats; + } + break; default: - if ((newEntity->GetType() & eTYPE_ANIMALS_SPAWN_LIMIT_CHECK) == - eTYPE_ANIMALS_SPAWN_LIMIT_CHECK) { + if (eTYPE_FLAGSET(eTYPE_ANIMALS_SPAWN_LIMIT_CHECK, + newEntity->GetType())) { if (level->canCreateMore(newEntity->GetType(), Level::eSpawnType_Egg)) { canSpawn = true; @@ -114,8 +122,10 @@ std::shared_ptr MonsterPlacerItem::canSpawn(int iAuxVal, Level* level, *piResult = eSpawnResult_FailTooManyPigsCowsSheepCats; } - } else if ((newEntity->GetType() & eTYPE_MONSTER) == - eTYPE_MONSTER) { + } + // 4J: Use eTYPE_ENEMY instead of monster (slimes and ghasts + // aren't monsters) + else if (newEntity->instanceof(eTYPE_ENEMY)) { // 4J-PB - check if the player is trying to spawn an enemy // in peaceful mode if (level->difficulty == Difficulty::PEACEFUL) { @@ -127,6 +137,11 @@ std::shared_ptr MonsterPlacerItem::canSpawn(int iAuxVal, Level* level, *piResult = eSpawnResult_FailTooManyMonsters; } } +#ifndef _CONTENT_PACKAGE + else if (app.DebugArtToolsOn()) { + canSpawn = true; + } +#endif break; } @@ -138,10 +153,10 @@ std::shared_ptr MonsterPlacerItem::canSpawn(int iAuxVal, Level* level, return nullptr; } -bool MonsterPlacerItem::useOn(std::shared_ptr itemInstance, - std::shared_ptr player, Level* level, - int x, int y, int z, int face, float clickX, - float clickY, float clickZ, bool bTestUseOnOnly) { +bool SpawnEggItem::useOn(std::shared_ptr itemInstance, + std::shared_ptr player, Level* level, int x, + int y, int z, int face, float clickX, float clickY, + float clickZ, bool bTestUseOnOnly) { if (level->isClientSide) { return true; } @@ -149,10 +164,11 @@ bool MonsterPlacerItem::useOn(std::shared_ptr itemInstance, int tile = level->getTile(x, y, z); #ifndef _CONTENT_PACKAGE - if (app.DebugSettingsOn() && tile == Tile::mobSpawner_Id) { + if (app.DebugArtToolsOn() && tile == Tile::mobSpawner_Id) { // 4J Stu - Force adding this as a tile update - level->setTile(x, y, z, 0); - level->setTile(x, y, z, Tile::mobSpawner_Id); + level->removeTile(x, y, z); + level->setTileAndData(x, y, z, Tile::mobSpawner_Id, 0, + Tile::UPDATE_ALL); std::shared_ptr mste = std::dynamic_pointer_cast( level->getTileEntity(x, y, z)); @@ -169,63 +185,95 @@ bool MonsterPlacerItem::useOn(std::shared_ptr itemInstance, z += Facing::STEP_Z[face]; double yOff = 0; - // 4J-PB - missing parentheses added if (face == Facing::UP && - (tile == Tile::fence_Id || tile == Tile::netherFence_Id)) { + (Tile::tiles[tile] != NULL && + Tile::tiles[tile]->getRenderShape() == Tile::SHAPE_FENCE)) { // special case yOff = .5; } int iResult = 0; - bool spawned = spawnMobAt(level, itemInstance->getAuxValue(), x + .5, - y + yOff, z + .5, &iResult) != NULL; + std::shared_ptr result = spawnMobAt( + level, itemInstance->getAuxValue(), x + .5, y + yOff, z + .5, &iResult); if (bTestUseOnOnly) { - return spawned; + return result != NULL; } - if (spawned) { + if (result != NULL) { + // 4J-JEV: SetCustomName is a method for Mob not LivingEntity; so change + // instanceof to check for Mobs. + if (result->instanceof(eTYPE_MOB) && + itemInstance->hasCustomHoverName()) { + std::dynamic_pointer_cast(result)->setCustomName( + itemInstance->getHoverName()); + } if (!player->abilities.instabuild) { itemInstance->count--; } } else { - // some negative sound effect? - // level->levelEvent(LevelEvent::SOUND_CLICK_FAIL, x, y, z, 0); - switch (iResult) { - case eSpawnResult_FailTooManyPigsCowsSheepCats: - player->displayClientMessage( - IDS_MAX_PIGS_SHEEP_COWS_CATS_SPAWNED); - break; - case eSpawnResult_FailTooManyChickens: - player->displayClientMessage(IDS_MAX_CHICKENS_SPAWNED); - break; - case eSpawnResult_FailTooManySquid: - player->displayClientMessage(IDS_MAX_SQUID_SPAWNED); - break; - case eSpawnResult_FailTooManyWolves: - player->displayClientMessage(IDS_MAX_WOLVES_SPAWNED); - break; - case eSpawnResult_FailTooManyMooshrooms: - player->displayClientMessage(IDS_MAX_MOOSHROOMS_SPAWNED); - break; - case eSpawnResult_FailTooManyMonsters: - player->displayClientMessage(IDS_MAX_ENEMIES_SPAWNED); - break; - case eSpawnResult_FailTooManyVillagers: - player->displayClientMessage(IDS_MAX_VILLAGERS_SPAWNED); - break; - case eSpawnResult_FailCantSpawnInPeaceful: - player->displayClientMessage(IDS_CANT_SPAWN_IN_PEACEFUL); - break; - } + DisplaySpawnError(player, iResult); } return true; } -std::shared_ptr MonsterPlacerItem::spawnMobAt(Level* level, int mobId, - double x, double y, - double z, int* piResult) { +std::shared_ptr SpawnEggItem::use( + std::shared_ptr itemInstance, Level* level, + std::shared_ptr player) { + if (level->isClientSide) return itemInstance; + + HitResult* hr = getPlayerPOVHitResult(level, player, true); + if (hr == NULL) { + delete hr; + return itemInstance; + } + + if (hr->type == HitResult::TILE) { + int xt = hr->x; + int yt = hr->y; + int zt = hr->z; + + if (!level->mayInteract(player, xt, yt, zt, 0)) { + delete hr; + return itemInstance; + } + if (!player->mayUseItemAt(xt, yt, zt, hr->f, itemInstance)) + return itemInstance; + + if (level->getMaterial(xt, yt, zt) == Material::water) { + int iResult = 0; + std::shared_ptr result = spawnMobAt( + level, itemInstance->getAuxValue(), xt, yt, zt, &iResult); + if (result != NULL) { + // 4J-JEV: SetCustomName is a method for Mob not LivingEntity; + // so change instanceof to check for Mobs. + if (result->instanceof(eTYPE_MOB) && + itemInstance->hasCustomHoverName()) { + std::dynamic_pointer_cast(result)->setCustomName( + itemInstance->getHoverName()); + } + if (!player->abilities.instabuild) { + itemInstance->count--; + } + } else { + SpawnEggItem::DisplaySpawnError(player, iResult); + } + } + } + return itemInstance; +} + +std::shared_ptr SpawnEggItem::spawnMobAt(Level* level, int auxVal, + double x, double y, double z, + int* piResult) { + int mobId = auxVal; + int extraData = 0; + + // 4J Stu - Enable spawning specific entity sub-types + mobId = auxVal & 0xFFF; + extraData = auxVal >> 12; + if (EntityIO::idsSpawnableInCreative.find(mobId) == EntityIO::idsSpawnableInCreative.end()) { return nullptr; @@ -236,8 +284,11 @@ std::shared_ptr MonsterPlacerItem::spawnMobAt(Level* level, int mobId, for (int i = 0; i < SPAWN_COUNT; i++) { newEntity = canSpawn(mobId, level, piResult); - std::shared_ptr mob = std::dynamic_pointer_cast(newEntity); - if (mob) { + // 4J-JEV: DynCasting to Mob not LivingEntity; so change instanceof to + // check for Mobs. + if (newEntity != NULL && newEntity->instanceof(eTYPE_MOB)) { + std::shared_ptr mob = + std::dynamic_pointer_cast(newEntity); newEntity->moveTo( x, y, z, Mth::wrapDegrees(level->random->nextFloat() * 360), 0); newEntity->setDespawnProtected(); // 4J added, default to being @@ -247,7 +298,7 @@ std::shared_ptr MonsterPlacerItem::spawnMobAt(Level* level, int mobId, mob->yHeadRot = mob->yRot; mob->yBodyRot = mob->yRot; - mob->finalizeMobSpawn(); + mob->finalizeMobSpawn(NULL, extraData); level->addEntity(newEntity); mob->playAmbientSound(); } @@ -256,7 +307,42 @@ std::shared_ptr MonsterPlacerItem::spawnMobAt(Level* level, int mobId, return newEntity; } -void MonsterPlacerItem::registerIcons(IconRegister* iconRegister) { +void SpawnEggItem::registerIcons(IconRegister* iconRegister) { Item::registerIcons(iconRegister); - overlay = iconRegister->registerIcon(L"monsterPlacer_overlay"); + overlay = iconRegister->registerIcon(getIconName() + L"_overlay"); } + +void SpawnEggItem::DisplaySpawnError(std::shared_ptr player, + int result) { + // some negative sound effect? + // level->levelEvent(LevelEvent::SOUND_CLICK_FAIL, x, y, z, 0); + switch (result) { + case eSpawnResult_FailTooManyPigsCowsSheepCats: + player->displayClientMessage(IDS_MAX_PIGS_SHEEP_COWS_CATS_SPAWNED); + break; + case eSpawnResult_FailTooManyChickens: + player->displayClientMessage(IDS_MAX_CHICKENS_SPAWNED); + break; + case eSpawnResult_FailTooManySquid: + player->displayClientMessage(IDS_MAX_SQUID_SPAWNED); + break; + case eSpawnResult_FailTooManyBats: + player->displayClientMessage(IDS_MAX_BATS_SPAWNED); + break; + case eSpawnResult_FailTooManyWolves: + player->displayClientMessage(IDS_MAX_WOLVES_SPAWNED); + break; + case eSpawnResult_FailTooManyMooshrooms: + player->displayClientMessage(IDS_MAX_MOOSHROOMS_SPAWNED); + break; + case eSpawnResult_FailTooManyMonsters: + player->displayClientMessage(IDS_MAX_ENEMIES_SPAWNED); + break; + case eSpawnResult_FailTooManyVillagers: + player->displayClientMessage(IDS_MAX_VILLAGERS_SPAWNED); + break; + case eSpawnResult_FailCantSpawnInPeaceful: + player->displayClientMessage(IDS_CANT_SPAWN_IN_PEACEFUL); + break; + } +} \ No newline at end of file diff --git a/Minecraft.World/Items/MonsterPlacerItem.h b/Minecraft.World/Items/SpawnEggItem.h similarity index 80% rename from Minecraft.World/Items/MonsterPlacerItem.h rename to Minecraft.World/Items/SpawnEggItem.h index bc1c47359..816efea2d 100644 --- a/Minecraft.World/Items/MonsterPlacerItem.h +++ b/Minecraft.World/Items/SpawnEggItem.h @@ -2,7 +2,7 @@ #include "Item.h" -class MonsterPlacerItem : public Item { +class SpawnEggItem : public Item { private: static const int SPAWN_COUNT = 1; @@ -14,6 +14,7 @@ public: eSpawnResult_FailTooManyPigsCowsSheepCats, eSpawnResult_FailTooManyChickens, eSpawnResult_FailTooManySquid, + eSpawnResult_FailTooManyBats, eSpawnResult_FailTooManyWolves, eSpawnResult_FailTooManyMooshrooms, eSpawnResult_FailTooManyAnimals, @@ -22,7 +23,7 @@ public: eSpawnResult_FailCantSpawnInPeaceful, }; - MonsterPlacerItem(int id); + SpawnEggItem(int id); virtual std::wstring getHoverName( std::shared_ptr itemInstance); @@ -33,6 +34,10 @@ public: std::shared_ptr player, Level* level, int x, int y, int z, int face, float clickX, float clickY, float clickZ, bool bTestUseOnOnly = false); + virtual std::shared_ptr use( + std::shared_ptr itemInstance, Level* level, + std::shared_ptr player); + static std::shared_ptr spawnMobAt( Level* level, int mobId, double x, double y, double z, int* piResult); // 4J Added piResult param @@ -41,6 +46,9 @@ public: static std::shared_ptr canSpawn(int iAuxVal, Level* level, int* piResult); + // 4J: Added for neatness + static void DisplaySpawnError(std::shared_ptr player, int result); + //@Override void registerIcons(IconRegister* iconRegister); }; \ No newline at end of file diff --git a/Minecraft.World/Items/TileItems/ClothTileItem.cpp b/Minecraft.World/Items/TileItems/ClothTileItem.cpp deleted file mode 100644 index 44652f138..000000000 --- a/Minecraft.World/Items/TileItems/ClothTileItem.cpp +++ /dev/null @@ -1,43 +0,0 @@ -#include "../../Platform/stdafx.h" -#include "../../Headers/net.minecraft.world.level.tile.h" -#include "../ItemInstance.h" -#include "../DyePowderItem.h" -#include "ClothTileItem.h" - -const unsigned int ClothTileItem::COLOR_DESCS[] = { - IDS_TILE_CLOTH_BLACK, IDS_TILE_CLOTH_RED, IDS_TILE_CLOTH_GREEN, - IDS_TILE_CLOTH_BROWN, IDS_TILE_CLOTH_BLUE, IDS_TILE_CLOTH_PURPLE, - IDS_TILE_CLOTH_CYAN, IDS_TILE_CLOTH_SILVER, IDS_TILE_CLOTH_GRAY, - IDS_TILE_CLOTH_PINK, IDS_TILE_CLOTH_LIME, IDS_TILE_CLOTH_YELLOW, - IDS_TILE_CLOTH_LIGHT_BLUE, IDS_TILE_CLOTH_MAGENTA, IDS_TILE_CLOTH_ORANGE, - IDS_TILE_CLOTH_WHITE}; - -const unsigned int ClothTileItem::CARPET_COLOR_DESCS[] = { - IDS_TILE_CARPET_BLACK, IDS_TILE_CARPET_RED, IDS_TILE_CARPET_GREEN, - IDS_TILE_CARPET_BROWN, IDS_TILE_CARPET_BLUE, IDS_TILE_CARPET_PURPLE, - IDS_TILE_CARPET_CYAN, IDS_TILE_CARPET_SILVER, IDS_TILE_CARPET_GRAY, - IDS_TILE_CARPET_PINK, IDS_TILE_CARPET_LIME, IDS_TILE_CARPET_YELLOW, - IDS_TILE_CARPET_LIGHT_BLUE, IDS_TILE_CARPET_MAGENTA, IDS_TILE_CARPET_ORANGE, - IDS_TILE_CARPET_WHITE}; - -ClothTileItem::ClothTileItem(int id) : TileItem(id) { - setMaxDamage(0); - setStackedByData(true); -} - -Icon* ClothTileItem::getIcon(int itemAuxValue) { - return Tile::cloth->getTexture( - 2, ClothTile::getTileDataForItemAuxValue(itemAuxValue)); -} - -int ClothTileItem::getLevelDataForAuxValue(int auxValue) { return auxValue; } - -unsigned int ClothTileItem::getDescriptionId( - std::shared_ptr instance) { - if (getTileId() == Tile::woolCarpet_Id) - return CARPET_COLOR_DESCS[ClothTile::getTileDataForItemAuxValue( - instance->getAuxValue())]; - else - return COLOR_DESCS[ClothTile::getTileDataForItemAuxValue( - instance->getAuxValue())]; -} diff --git a/Minecraft.World/Items/TileItems/ColoredTileItem.cpp b/Minecraft.World/Items/TileItems/ColoredTileItem.cpp index e0c767032..06cb241e0 100644 --- a/Minecraft.World/Items/TileItems/ColoredTileItem.cpp +++ b/Minecraft.World/Items/TileItems/ColoredTileItem.cpp @@ -45,8 +45,9 @@ unsigned int ColoredTileItem::getDescriptionId( } int id = instance->getAuxValue(); if (id >= 0 && id < descriptionPostfixes.length) { - return descriptionPostfixes[id]; // TileItem::getDescriptionId(instance) - // + "." + descriptionPostfixes[id]; + return descriptionPostfixes + [id]; // TileItem::getDescriptionId(instance) + // + "." + descriptionPostfixes[id]; } return TileItem::getDescriptionId(instance); } \ No newline at end of file diff --git a/Minecraft.World/Items/TileItems/MultiTextureTileItem.cpp b/Minecraft.World/Items/TileItems/MultiTextureTileItem.cpp index 9a702b76c..304b84d75 100644 --- a/Minecraft.World/Items/TileItems/MultiTextureTileItem.cpp +++ b/Minecraft.World/Items/TileItems/MultiTextureTileItem.cpp @@ -1,14 +1,22 @@ #include "../../Platform/stdafx.h" #include "../../Blocks/Tile.h" #include "MultiTextureTileItem.h" +#include "../../Headers/net.minecraft.world.item.crafting.h" MultiTextureTileItem::MultiTextureTileItem(int id, Tile* parentTile, - int* nameExtensions, int iLength) + int* nameExtensions, int iLength, + int anyValueName) : TileItem(id) { this->parentTile = parentTile; this->nameExtensions = nameExtensions; this->m_iNameExtensionsLength = iLength; + if (anyValueName != -1) { + m_anyValueName = anyValueName; + } else { + m_anyValueName = nameExtensions[0]; + } + setMaxDamage(0); setStackedByData(true); } @@ -25,16 +33,15 @@ unsigned int MultiTextureTileItem::getDescriptionId(int iData) { if (iData < 0 || iData >= m_iNameExtensionsLength) { iData = 0; } - // return super.getDescriptionId() + "." + nameExtensions[auxValue]; return nameExtensions[iData]; } unsigned int MultiTextureTileItem::getDescriptionId( std::shared_ptr instance) { int auxValue = instance->getAuxValue(); - if (auxValue < 0 || auxValue >= m_iNameExtensionsLength) { - auxValue = 0; + if (auxValue == Recipes::ANY_AUX_VALUE || auxValue < 0 || + auxValue >= m_iNameExtensionsLength) { + return m_anyValueName; } - // return super.getDescriptionId() + "." + nameExtensions[auxValue]; return nameExtensions[auxValue]; -} +} \ No newline at end of file diff --git a/Minecraft.World/Items/TileItems/MultiTextureTileItem.h b/Minecraft.World/Items/TileItems/MultiTextureTileItem.h index 13e271811..2e463d3ac 100644 --- a/Minecraft.World/Items/TileItems/MultiTextureTileItem.h +++ b/Minecraft.World/Items/TileItems/MultiTextureTileItem.h @@ -10,10 +10,12 @@ private: // private final String[] nameExtensions; int* nameExtensions; int m_iNameExtensionsLength; + int m_anyValueName; // 4J Added public: MultiTextureTileItem(int id, Tile* parentTile, int* nameExtensions, - int iLength); + int iLength, + int anyValueName = -1); // 4J Added anyValueName virtual Icon* getIcon(int itemAuxValue); virtual int getLevelDataForAuxValue(int auxValue); diff --git a/Minecraft.World/Items/TileItems/PlanterTileItem.cpp b/Minecraft.World/Items/TileItems/PlanterTileItem.cpp index a5454ae64..34e01312d 100644 --- a/Minecraft.World/Items/TileItems/PlanterTileItem.cpp +++ b/Minecraft.World/Items/TileItems/PlanterTileItem.cpp @@ -20,7 +20,8 @@ bool TilePlanterItem::useOn(std::shared_ptr instance, float clickZ, bool bTestUseOnOnly) { // 4J-PB - Adding a test only version to allow tooltips to be displayed int currentTile = level->getTile(x, y, z); - if (currentTile == Tile::topSnow_Id) { + if (currentTile == Tile::topSnow_Id && + (level->getData(x, y, z) & TopSnowTile::HEIGHT_MASK) < 1) { face = Facing::UP; } else if (currentTile == Tile::vine_Id || currentTile == Tile::tallgrass_Id || @@ -34,15 +35,16 @@ bool TilePlanterItem::useOn(std::shared_ptr instance, if (face == 5) x++; } - if (!player->mayBuild(x, y, z)) return false; + if (!player->mayUseItemAt(x, y, z, face, instance)) return false; if (instance->count == 0) return false; - if (level->mayPlace(tileId, x, y, z, false, face, nullptr)) { + if (level->mayPlace(tileId, x, y, z, false, face, nullptr, instance)) { if (!bTestUseOnOnly) { Tile* tile = Tile::tiles[tileId]; int dataValue = tile->getPlacedOnFaceDataValue( level, x, y, z, face, clickX, clickY, clickZ, 0); - if (level->setTileAndData(x, y, z, tileId, dataValue)) { + if (level->setTileAndData(x, y, z, tileId, dataValue, + Tile::UPDATE_ALL)) { // 4J-JEV: Hook for durango 'BlockPlaced' event. player->awardStat(GenericStats::blocksPlaced(tileId), GenericStats::param_blocksPlaced( @@ -53,12 +55,13 @@ bool TilePlanterItem::useOn(std::shared_ptr instance, // placed block to become something else before these methods // are called if (level->getTile(x, y, z) == tileId) { - Tile::tiles[tileId]->setPlacedBy(level, x, y, z, player); + Tile::tiles[tileId]->setPlacedBy(level, x, y, z, player, + instance); Tile::tiles[tileId]->finalizePlacement(level, x, y, z, dataValue); } level->playSound(x + 0.5f, y + 0.5f, z + 0.5f, - tile->soundType->getStepSound(), + tile->soundType->getPlaceSound(), (tile->soundType->getVolume() + 1) / 2, tile->soundType->getPitch() * 0.8f); // 4J-PB - If we have the debug option on, don't reduce the diff --git a/Minecraft.World/Items/TileItems/SkullItem.cpp b/Minecraft.World/Items/TileItems/SkullItem.cpp index d092da5b6..23e2a0609 100644 --- a/Minecraft.World/Items/TileItems/SkullItem.cpp +++ b/Minecraft.World/Items/TileItems/SkullItem.cpp @@ -12,8 +12,7 @@ const unsigned int SkullItem::NAMES[SKULL_COUNT] = { IDS_ITEM_SKULL_CHARACTER, IDS_ITEM_SKULL_CREEPER}; std::wstring SkullItem::ICON_NAMES[SKULL_COUNT] = { - L"skull_skeleton", L"skull_wither", L"skull_zombie", L"skull_char", - L"skull_creeper"}; + L"skeleton", L"wither", L"zombie", L"char", L"creeper"}; SkullItem::SkullItem(int id) : Item(id) { // setItemCategory(CreativeModeTab.TAB_DECORATIONS); @@ -38,13 +37,13 @@ bool SkullItem::useOn( if (face == 5) x++; // if (!player->mayUseItemAt(x, y, z, face, instance)) return false; - if (!player->mayBuild(x, y, z)) return false; + if (!player->mayUseItemAt(x, y, z, face, instance)) return false; if (!Tile::skull->mayPlace(level, x, y, z)) return false; if (!bTestUseOnOnly) { - level->setTileAndData(x, y, z, Tile::skull_Id, - face); //, Tile.UPDATE_CLIENTS); + level->setTileAndData(x, y, z, Tile::skull_Id, face, + Tile::UPDATE_CLIENTS); int rot = 0; if (face == Facing::UP) { @@ -88,8 +87,7 @@ bool SkullItem::mayPlace(Level* level, int x, int y, int z, int face, if (face == 5) x++; } - return level->mayPlace(Tile::skull_Id, x, y, z, false, face, - nullptr); //, item); + return level->mayPlace(Tile::skull_Id, x, y, z, false, face, nullptr, item); } Icon* SkullItem::getIcon(int itemAuxValue) { @@ -133,6 +131,7 @@ std::wstring SkullItem::getHoverName( void SkullItem::registerIcons(IconRegister* iconRegister) { for (int i = 0; i < SKULL_COUNT; i++) { - icons[i] = iconRegister->registerIcon(ICON_NAMES[i]); + icons[i] = + iconRegister->registerIcon(getIconName() + L"_" + ICON_NAMES[i]); } } \ No newline at end of file diff --git a/Minecraft.World/Items/TileItems/SmoothStoneBrickTileItem.cpp b/Minecraft.World/Items/TileItems/SmoothStoneBrickTileItem.cpp deleted file mode 100644 index 295a447aa..000000000 --- a/Minecraft.World/Items/TileItems/SmoothStoneBrickTileItem.cpp +++ /dev/null @@ -1,30 +0,0 @@ -#include "../../Platform/stdafx.h" -#include "../../Headers/net.minecraft.world.item.h" -#include "../../Headers/net.minecraft.world.level.tile.h" -#include "SmoothStoneBrickTileItem.h" - -SmoothStoneBrickTileItem::SmoothStoneBrickTileItem(int id, Tile* parentTile) - : TileItem(id) { - this->parentTile = parentTile; - - setMaxDamage(0); - setStackedByData(true); -} - -Icon* SmoothStoneBrickTileItem::getIcon(int itemAuxValue) { - return parentTile->getTexture(2, itemAuxValue); -} - -int SmoothStoneBrickTileItem::getLevelDataForAuxValue(int auxValue) { - return auxValue; -} - -unsigned int SmoothStoneBrickTileItem::getDescriptionId( - std::shared_ptr instance) { - int auxValue = instance->getAuxValue(); - if (auxValue < 0 || - auxValue >= SmoothStoneBrickTile::SMOOTH_STONE_BRICK_NAMES_LENGTH) { - auxValue = 0; - } - return SmoothStoneBrickTile::SMOOTH_STONE_BRICK_NAMES[auxValue]; -} \ No newline at end of file diff --git a/Minecraft.World/Items/TileItems/SmoothStoneBrickTileItem.h b/Minecraft.World/Items/TileItems/SmoothStoneBrickTileItem.h deleted file mode 100644 index c5d989d7c..000000000 --- a/Minecraft.World/Items/TileItems/SmoothStoneBrickTileItem.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include "TileItem.h" - -class SmoothStoneBrickTileItem : public TileItem { -private: - Tile* parentTile; - -public: - SmoothStoneBrickTileItem(int id, Tile* parentTile); - - virtual Icon* getIcon(int itemAuxValue); - virtual int getLevelDataForAuxValue(int auxValue); - virtual unsigned int getDescriptionId( - std::shared_ptr instance); -}; \ No newline at end of file diff --git a/Minecraft.World/Items/TileItems/StoneMonsterTileItem.cpp b/Minecraft.World/Items/TileItems/StoneMonsterTileItem.cpp deleted file mode 100644 index e44b16749..000000000 --- a/Minecraft.World/Items/TileItems/StoneMonsterTileItem.cpp +++ /dev/null @@ -1,27 +0,0 @@ -#include "../../Platform/stdafx.h" -#include "../../Headers/net.minecraft.world.item.h" -#include "../../Headers/net.minecraft.world.level.tile.h" -#include "StoneMonsterTileItem.h" - -StoneMonsterTileItem::StoneMonsterTileItem(int id) : TileItem(id) { - setMaxDamage(0); - setStackedByData(true); -} - -int StoneMonsterTileItem::getLevelDataForAuxValue(int auxValue) { - return auxValue; -} - -Icon* StoneMonsterTileItem::getIcon(int itemAuxValue) { - return Tile::monsterStoneEgg->getTexture(0, itemAuxValue); -} - -unsigned int StoneMonsterTileItem::getDescriptionId( - std::shared_ptr instance) { - int auxValue = instance->getAuxValue(); - if (auxValue < 0 || - auxValue >= StoneMonsterTile::STONE_MONSTER_NAMES_LENGTH) { - auxValue = 0; - } - return StoneMonsterTile::STONE_MONSTER_NAMES[auxValue]; -} \ No newline at end of file diff --git a/Minecraft.World/Items/TileItems/StoneMonsterTileItem.h b/Minecraft.World/Items/TileItems/StoneMonsterTileItem.h deleted file mode 100644 index 3a2b755e6..000000000 --- a/Minecraft.World/Items/TileItems/StoneMonsterTileItem.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include "TileItem.h" - -// 4J Stu - Class brought forward from 12w36 to fix stacking problem with -// silverfish stones - -class StoneMonsterTileItem : public TileItem { -public: - StoneMonsterTileItem(int id); - - virtual int getLevelDataForAuxValue(int auxValue); - virtual Icon* getIcon(int itemAuxValue); - virtual unsigned int getDescriptionId( - std::shared_ptr instance); -}; \ No newline at end of file diff --git a/Minecraft.World/Items/TileItems/StoneSlabTileItem.cpp b/Minecraft.World/Items/TileItems/StoneSlabTileItem.cpp index 3e2eecbb5..86940cbff 100644 --- a/Minecraft.World/Items/TileItems/StoneSlabTileItem.cpp +++ b/Minecraft.World/Items/TileItems/StoneSlabTileItem.cpp @@ -13,7 +13,7 @@ StoneSlabTileItem::StoneSlabTileItem(int id, HalfSlabTile* halfTile, this->halfTile = halfTile; this->fullTile = fullTile; - this->isFull = full; + isFull = full; setMaxDamage(0); setStackedByData(true); } @@ -41,7 +41,7 @@ bool StoneSlabTileItem::useOn(std::shared_ptr instance, } if (instance->count == 0) return false; - if (!player->mayBuild(x, y, z)) return false; + if (!player->mayUseItemAt(x, y, z, face, instance)) return false; int currentTile = level->getTile(x, y, z); int currentData = level->getData(x, y, z); @@ -56,13 +56,10 @@ bool StoneSlabTileItem::useOn(std::shared_ptr instance, } if (level->isUnobstructed(fullTile->getAABB(level, x, y, z)) && - level->setTileAndData(x, y, z, fullTile->id, slabType)) { - // level.playSound(x + 0.5f, y + 0.5f, z + 0.5f, - // fullTile.soundType.getPlaceSound(), - // (fullTile.soundType.getVolume() + 1) / 2, - // fullTile.soundType.getPitch() * 0.8f); instance.count--; + level->setTileAndData(x, y, z, fullTile->id, slabType, + Tile::UPDATE_ALL)) { level->playSound(x + 0.5f, y + 0.5f, z + 0.5f, - fullTile->soundType->getStepSound(), + fullTile->soundType->getPlaceSound(), (fullTile->soundType->getVolume() + 1) / 2, fullTile->soundType->getPitch() * 0.8f); instance->count--; @@ -131,13 +128,10 @@ bool StoneSlabTileItem::tryConvertTargetTile( return true; } if (level->isUnobstructed(fullTile->getAABB(level, x, y, z)) && - level->setTileAndData(x, y, z, fullTile->id, slabType)) { - // level.playSound(x + 0.5f, y + 0.5f, z + 0.5f, - // fullTile.soundType.getPlaceSound(), - // (fullTile.soundType.getVolume() + 1) / 2, - // fullTile.soundType.getPitch() * 0.8f); + level->setTileAndData(x, y, z, fullTile->id, slabType, + Tile::UPDATE_ALL)) { level->playSound(x + 0.5f, y + 0.5f, z + 0.5f, - fullTile->soundType->getStepSound(), + fullTile->soundType->getPlaceSound(), (fullTile->soundType->getVolume() + 1) / 2, fullTile->soundType->getPitch() * 0.8f); instance->count--; diff --git a/Minecraft.World/Items/TileItems/TileItem.cpp b/Minecraft.World/Items/TileItems/TileItem.cpp index 8e4481b6f..97af95d78 100644 --- a/Minecraft.World/Items/TileItems/TileItem.cpp +++ b/Minecraft.World/Items/TileItems/TileItem.cpp @@ -43,7 +43,8 @@ bool TileItem::useOn(std::shared_ptr instance, bool bTestUseOnOnly) { // 4J-PB - Adding a test only version to allow tooltips to be displayed int currentTile = level->getTile(x, y, z); - if (currentTile == Tile::topSnow_Id) { + if (currentTile == Tile::topSnow_Id && + (level->getData(x, y, z) & TopSnowTile::HEIGHT_MASK) < 1) { face = Facing::UP; } else if (currentTile == Tile::vine_Id || currentTile == Tile::tallgrass_Id || @@ -58,7 +59,7 @@ bool TileItem::useOn(std::shared_ptr instance, } if (instance->count == 0) return false; - if (!player->mayBuild(x, y, z)) return false; + if (!player->mayUseItemAt(x, y, z, face, instance)) return false; if (y == Level::maxBuildHeight - 1 && Tile::tiles[tileId]->material->isSolid()) @@ -67,14 +68,15 @@ bool TileItem::useOn(std::shared_ptr instance, int undertile = level->getTile(x, y - 1, z); // For 'BodyGuard' achievement. - if (level->mayPlace(tileId, x, y, z, false, face, player)) { + if (level->mayPlace(tileId, x, y, z, false, face, player, instance)) { if (!bTestUseOnOnly) { Tile* tile = Tile::tiles[tileId]; // 4J - Adding this from 1.6 int itemValue = getLevelDataForAuxValue(instance->getAuxValue()); int dataValue = Tile::tiles[tileId]->getPlacedOnFaceDataValue( level, x, y, z, face, clickX, clickY, clickZ, itemValue); - if (level->setTileAndData(x, y, z, tileId, dataValue)) { + if (level->setTileAndData(x, y, z, tileId, dataValue, + Tile::UPDATE_ALL)) { // 4J-JEV: Snow/Iron Golems do not have owners apparently. int newTileId = level->getTile(x, y, z); if ((tileId == Tile::pumpkin_Id || @@ -110,7 +112,8 @@ bool TileItem::useOn(std::shared_ptr instance, // placed block to become something else before these methods // are called if (level->getTile(x, y, z) == tileId) { - Tile::tiles[tileId]->setPlacedBy(level, x, y, z, player); + Tile::tiles[tileId]->setPlacedBy(level, x, y, z, player, + instance); Tile::tiles[tileId]->finalizePlacement(level, x, y, z, dataValue); } @@ -190,7 +193,7 @@ bool TileItem::mayPlace(Level* level, int x, int y, int z, int face, if (face == 5) x++; } - return level->mayPlace(getTileId(), x, y, z, false, face, nullptr); + return level->mayPlace(getTileId(), x, y, z, false, face, nullptr, item); } // 4J Added to colourise some tile types in the hint popups diff --git a/Minecraft.World/Items/TileItems/TreeTileItem.cpp b/Minecraft.World/Items/TileItems/TreeTileItem.cpp deleted file mode 100644 index 29e403e08..000000000 --- a/Minecraft.World/Items/TileItems/TreeTileItem.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#include "../../Platform/stdafx.h" -#include "../../Headers/net.minecraft.world.level.tile.h" -#include "TreeTileItem.h" - -TreeTileItem::TreeTileItem(int id, Tile* parentTile) : TileItem(id) { - this->parentTile = parentTile; - - setMaxDamage(0); - setStackedByData(true); -} - -Icon* TreeTileItem::getIcon(int itemAuxValue) { - return parentTile->getTexture(2, itemAuxValue); -} - -int TreeTileItem::getLevelDataForAuxValue(int auxValue) { return auxValue; } - -unsigned int TreeTileItem::getDescriptionId( - std::shared_ptr instance) { - int auxValue = instance->getAuxValue(); - if (auxValue < 0 || auxValue >= TreeTile::TREE_NAMES_LENGTH) { - auxValue = 0; - } - return TreeTile::TREE_NAMES[auxValue]; -} \ No newline at end of file diff --git a/Minecraft.World/Items/TileItems/TreeTileItem.h b/Minecraft.World/Items/TileItems/TreeTileItem.h deleted file mode 100644 index 6ecbc6995..000000000 --- a/Minecraft.World/Items/TileItems/TreeTileItem.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#include "TileItem.h" - -class TreeTileItem : public TileItem { -private: - Tile* parentTile; - -public: - TreeTileItem(int id, Tile* parentTile); - - virtual Icon* getIcon(int itemAuxValue); - virtual int getLevelDataForAuxValue(int auxValue); - - virtual unsigned int getDescriptionId( - std::shared_ptr instance); -}; \ No newline at end of file diff --git a/Minecraft.World/Items/TileItems/WaterLilyTileItem.cpp b/Minecraft.World/Items/TileItems/WaterLilyTileItem.cpp index 3e5134b2f..8cc59b628 100644 --- a/Minecraft.World/Items/TileItems/WaterLilyTileItem.cpp +++ b/Minecraft.World/Items/TileItems/WaterLilyTileItem.cpp @@ -8,7 +8,8 @@ WaterLilyTileItem::WaterLilyTileItem(int id) : ColoredTileItem(id, false) {} -bool WaterLilyTileItem::TestUse(Level* level, std::shared_ptr player) { +bool WaterLilyTileItem::TestUse(std::shared_ptr itemInstance, + Level* level, std::shared_ptr player) { HitResult* hr = getPlayerPOVHitResult(level, player, true); if (hr == NULL) return false; @@ -16,12 +17,16 @@ bool WaterLilyTileItem::TestUse(Level* level, std::shared_ptr player) { int xt = hr->x; int yt = hr->y; int zt = hr->z; - delete hr; if (!level->mayInteract(player, xt, yt, zt, 0)) { + delete hr; + return false; + } + if (!player->mayUseItemAt(xt, yt, zt, hr->f, itemInstance)) { + delete hr; return false; } - if (!player->mayBuild(xt, yt, zt)) return false; + delete hr; if (level->getMaterial(xt, yt, zt) == Material::water && level->getData(xt, yt, zt) == 0 && level->isEmptyTile(xt, yt + 1, zt)) { @@ -43,16 +48,20 @@ std::shared_ptr WaterLilyTileItem::use( int xt = hr->x; int yt = hr->y; int zt = hr->z; - delete hr; if (!level->mayInteract(player, xt, yt, zt, 0)) { + delete hr; + return itemInstance; + } + if (!player->mayUseItemAt(xt, yt, zt, hr->f, itemInstance)) { + delete hr; return itemInstance; } - if (!player->mayBuild(xt, yt, zt)) return itemInstance; + delete hr; if (level->getMaterial(xt, yt, zt) == Material::water && level->getData(xt, yt, zt) == 0 && level->isEmptyTile(xt, yt + 1, zt)) { - level->setTile(xt, yt + 1, zt, Tile::waterLily->id); + level->setTileAndUpdate(xt, yt + 1, zt, Tile::waterLily->id); if (!player->abilities.instabuild) { itemInstance->count--; } diff --git a/Minecraft.World/Items/TileItems/WaterLilyTileItem.h b/Minecraft.World/Items/TileItems/WaterLilyTileItem.h index 8a8db8b80..31ca008e4 100644 --- a/Minecraft.World/Items/TileItems/WaterLilyTileItem.h +++ b/Minecraft.World/Items/TileItems/WaterLilyTileItem.h @@ -10,6 +10,7 @@ public: virtual std::shared_ptr use( std::shared_ptr itemInstance, Level* level, std::shared_ptr player); - virtual bool TestUse(Level* level, std::shared_ptr player); + virtual bool TestUse(std::shared_ptr itemInstance, + Level* level, std::shared_ptr player); virtual int getColor(int data, int spriteLayer); }; diff --git a/Minecraft.World/Items/TileItems/WoolTileItem.cpp b/Minecraft.World/Items/TileItems/WoolTileItem.cpp new file mode 100644 index 000000000..7f7f6ec05 --- /dev/null +++ b/Minecraft.World/Items/TileItems/WoolTileItem.cpp @@ -0,0 +1,95 @@ +#include "../../Platform/stdafx.h" +#include "../../Headers/net.minecraft.world.level.tile.h" +#include "../ItemInstance.h" +#include "../DyePowderItem.h" +#include "WoolTileItem.h" + +const unsigned int WoolTileItem::COLOR_DESCS[] = { + IDS_TILE_CLOTH_BLACK, IDS_TILE_CLOTH_RED, IDS_TILE_CLOTH_GREEN, + IDS_TILE_CLOTH_BROWN, IDS_TILE_CLOTH_BLUE, IDS_TILE_CLOTH_PURPLE, + IDS_TILE_CLOTH_CYAN, IDS_TILE_CLOTH_SILVER, IDS_TILE_CLOTH_GRAY, + IDS_TILE_CLOTH_PINK, IDS_TILE_CLOTH_LIME, IDS_TILE_CLOTH_YELLOW, + IDS_TILE_CLOTH_LIGHT_BLUE, IDS_TILE_CLOTH_MAGENTA, IDS_TILE_CLOTH_ORANGE, + IDS_TILE_CLOTH_WHITE}; + +const unsigned int WoolTileItem::CARPET_COLOR_DESCS[] = { + IDS_TILE_CARPET_BLACK, IDS_TILE_CARPET_RED, IDS_TILE_CARPET_GREEN, + IDS_TILE_CARPET_BROWN, IDS_TILE_CARPET_BLUE, IDS_TILE_CARPET_PURPLE, + IDS_TILE_CARPET_CYAN, IDS_TILE_CARPET_SILVER, IDS_TILE_CARPET_GRAY, + IDS_TILE_CARPET_PINK, IDS_TILE_CARPET_LIME, IDS_TILE_CARPET_YELLOW, + IDS_TILE_CARPET_LIGHT_BLUE, IDS_TILE_CARPET_MAGENTA, IDS_TILE_CARPET_ORANGE, + IDS_TILE_CARPET_WHITE}; + +const unsigned int WoolTileItem::CLAY_COLOR_DESCS[] = { + IDS_TILE_STAINED_CLAY_BLACK, IDS_TILE_STAINED_CLAY_RED, + IDS_TILE_STAINED_CLAY_GREEN, IDS_TILE_STAINED_CLAY_BROWN, + IDS_TILE_STAINED_CLAY_BLUE, IDS_TILE_STAINED_CLAY_PURPLE, + IDS_TILE_STAINED_CLAY_CYAN, IDS_TILE_STAINED_CLAY_SILVER, + IDS_TILE_STAINED_CLAY_GRAY, IDS_TILE_STAINED_CLAY_PINK, + IDS_TILE_STAINED_CLAY_LIME, IDS_TILE_STAINED_CLAY_YELLOW, + IDS_TILE_STAINED_CLAY_LIGHT_BLUE, IDS_TILE_STAINED_CLAY_MAGENTA, + IDS_TILE_STAINED_CLAY_ORANGE, IDS_TILE_STAINED_CLAY_WHITE}; + +const unsigned int WoolTileItem::GLASS_COLOR_DESCS[] = { + IDS_TILE_STAINED_GLASS_BLACK, IDS_TILE_STAINED_GLASS_RED, + IDS_TILE_STAINED_GLASS_GREEN, IDS_TILE_STAINED_GLASS_BROWN, + IDS_TILE_STAINED_GLASS_BLUE, IDS_TILE_STAINED_GLASS_PURPLE, + IDS_TILE_STAINED_GLASS_CYAN, IDS_TILE_STAINED_GLASS_SILVER, + IDS_TILE_STAINED_GLASS_GRAY, IDS_TILE_STAINED_GLASS_PINK, + IDS_TILE_STAINED_GLASS_LIME, IDS_TILE_STAINED_GLASS_YELLOW, + IDS_TILE_STAINED_GLASS_LIGHT_BLUE, IDS_TILE_STAINED_GLASS_MAGENTA, + IDS_TILE_STAINED_GLASS_ORANGE, IDS_TILE_STAINED_GLASS_WHITE}; + +const unsigned int WoolTileItem::GLASS_PANE_COLOR_DESCS[] = { + IDS_TILE_STAINED_GLASS_PANE_BLACK, IDS_TILE_STAINED_GLASS_PANE_RED, + IDS_TILE_STAINED_GLASS_PANE_GREEN, IDS_TILE_STAINED_GLASS_PANE_BROWN, + IDS_TILE_STAINED_GLASS_PANE_BLUE, IDS_TILE_STAINED_GLASS_PANE_PURPLE, + IDS_TILE_STAINED_GLASS_PANE_CYAN, IDS_TILE_STAINED_GLASS_PANE_SILVER, + IDS_TILE_STAINED_GLASS_PANE_GRAY, IDS_TILE_STAINED_GLASS_PANE_PINK, + IDS_TILE_STAINED_GLASS_PANE_LIME, IDS_TILE_STAINED_GLASS_PANE_YELLOW, + IDS_TILE_STAINED_GLASS_PANE_LIGHT_BLUE, IDS_TILE_STAINED_GLASS_PANE_MAGENTA, + IDS_TILE_STAINED_GLASS_PANE_ORANGE, IDS_TILE_STAINED_GLASS_PANE_WHITE}; + +WoolTileItem::WoolTileItem(int id) : TileItem(id) { + setMaxDamage(0); + setStackedByData(true); +} + +Icon* WoolTileItem::getIcon(int itemAuxValue) { +#ifndef _CONTENT_PACKAGE + if (Tile::tiles[id]) { + return Tile::tiles[id]->getTexture( + 2, ColoredTile::getTileDataForItemAuxValue(itemAuxValue)); + } else +#endif + { + return Tile::wool->getTexture( + 2, ColoredTile::getTileDataForItemAuxValue(itemAuxValue)); + } +} + +int WoolTileItem::getLevelDataForAuxValue(int auxValue) { return auxValue; } + +unsigned int WoolTileItem::getDescriptionId( + std::shared_ptr instance) { + int tileId = getTileId(); + switch (getTileId()) { + case Tile::stained_glass_Id: + return GLASS_COLOR_DESCS[ColoredTile::getTileDataForItemAuxValue( + instance->getAuxValue())]; + case Tile::stained_glass_pane_Id: + return GLASS_PANE_COLOR_DESCS + [ColoredTile::getTileDataForItemAuxValue( + instance->getAuxValue())]; + case Tile::clayHardened_colored_Id: + return CLAY_COLOR_DESCS[ColoredTile::getTileDataForItemAuxValue( + instance->getAuxValue())]; + case Tile::woolCarpet_Id: + return CARPET_COLOR_DESCS[ColoredTile::getTileDataForItemAuxValue( + instance->getAuxValue())]; + case Tile::wool_Id: + default: + return COLOR_DESCS[ColoredTile::getTileDataForItemAuxValue( + instance->getAuxValue())]; + }; +} diff --git a/Minecraft.World/Items/TileItems/ClothTileItem.h b/Minecraft.World/Items/TileItems/WoolTileItem.h similarity index 60% rename from Minecraft.World/Items/TileItems/ClothTileItem.h rename to Minecraft.World/Items/TileItems/WoolTileItem.h index b9a72291c..cc4735969 100644 --- a/Minecraft.World/Items/TileItems/ClothTileItem.h +++ b/Minecraft.World/Items/TileItems/WoolTileItem.h @@ -2,12 +2,15 @@ #include "TileItem.h" -class ClothTileItem : public TileItem { +class WoolTileItem : public TileItem { public: static const unsigned int COLOR_DESCS[]; static const unsigned int CARPET_COLOR_DESCS[]; + static const unsigned int CLAY_COLOR_DESCS[]; + static const unsigned int GLASS_COLOR_DESCS[]; + static const unsigned int GLASS_PANE_COLOR_DESCS[]; - ClothTileItem(int id); + WoolTileItem(int id); virtual Icon* getIcon(int itemAuxValue); virtual int getLevelDataForAuxValue(int auxValue); diff --git a/Minecraft.World/Items/WeaponItem.cpp b/Minecraft.World/Items/WeaponItem.cpp index 3d54e8f14..d6ec87a90 100644 --- a/Minecraft.World/Items/WeaponItem.cpp +++ b/Minecraft.World/Items/WeaponItem.cpp @@ -1,7 +1,9 @@ #include "../Platform/stdafx.h" #include "../Headers/net.minecraft.world.item.h" #include "../Headers/net.minecraft.world.entity.h" +#include "../Headers/net.minecraft.world.entity.ai.attributes.h" #include "../Headers/net.minecraft.world.entity.player.h" +#include "../Headers/net.minecraft.world.entity.monster.h" #include "../Headers/net.minecraft.world.level.tile.h" #include "WeaponItem.h" @@ -12,35 +14,42 @@ WeaponItem::WeaponItem(int id, const Tier* tier) : Item(id), tier(tier) { damage = 4 + tier->getAttackDamageBonus(); } +float WeaponItem::getTierDamage() { return tier->getAttackDamageBonus(); } + float WeaponItem::getDestroySpeed(std::shared_ptr itemInstance, Tile* tile) { if (tile->id == Tile::web_Id) { // swords can quickly cut web return 15; } - return 1.5f; + // this change modifies which tiles the swords can destroy in creative + // mode (>1 == yes) + Material* material = tile->material; + if (material == Material::plant || + material == Material::replaceable_plant || + material == Material::coral || material == Material::leaves || + material == Material::vegetable) { + return 1.5f; + } + return 1.0f; } bool WeaponItem::hurtEnemy(std::shared_ptr itemInstance, - std::shared_ptr mob, - std::shared_ptr attacker) { - itemInstance->hurt(1, attacker); + std::shared_ptr mob, + std::shared_ptr attacker) { + itemInstance->hurtAndBreak(1, attacker); return true; } bool WeaponItem::mineBlock(std::shared_ptr itemInstance, Level* level, int tile, int x, int y, int z, - std::shared_ptr owner) { + std::shared_ptr owner) { // Don't damage weapons if the tile can be destroyed in one hit. if (Tile::tiles[tile]->getDestroySpeed(level, x, y, z) != 0.0) - itemInstance->hurt(2, owner); + itemInstance->hurtAndBreak(2, owner); return true; } -int WeaponItem::getAttackDamage(std::shared_ptr entity) { - return damage; -} - bool WeaponItem::isHandEquipped() { return true; } UseAnim WeaponItem::getUseAnimation( @@ -73,4 +82,15 @@ bool WeaponItem::isValidRepairItem(std::shared_ptr source, return true; } return Item::isValidRepairItem(source, repairItem); +} + +attrAttrModMap* WeaponItem::getDefaultAttributeModifiers() { + attrAttrModMap* result = Item::getDefaultAttributeModifiers(); + + result->insert(attrAttrModMap::value_type( + SharedMonsterAttributes::ATTACK_DAMAGE->getId(), + new AttributeModifier(eModifierId_ITEM_BASEDAMAGE, damage, + AttributeModifier::OPERATION_ADDITION))); + + return result; } \ No newline at end of file diff --git a/Minecraft.World/Items/WeaponItem.h b/Minecraft.World/Items/WeaponItem.h index d2ecda71a..009b79280 100644 --- a/Minecraft.World/Items/WeaponItem.h +++ b/Minecraft.World/Items/WeaponItem.h @@ -4,21 +4,20 @@ class WeaponItem : public Item { private: - int damage; + float damage; const Tier* tier; public: WeaponItem(int id, const Tier* tier); - + virtual float getTierDamage(); virtual float getDestroySpeed(std::shared_ptr itemInstance, Tile* tile); virtual bool hurtEnemy(std::shared_ptr itemInstance, - std::shared_ptr mob, - std::shared_ptr attacker); + std::shared_ptr mob, + std::shared_ptr attacker); virtual bool mineBlock(std::shared_ptr itemInstance, Level* level, int tile, int x, int y, int z, - std::shared_ptr owner); - virtual int getAttackDamage(std::shared_ptr entity); + std::shared_ptr owner); virtual bool isHandEquipped(); virtual UseAnim getUseAnimation(std::shared_ptr itemInstance); virtual int getUseDuration(std::shared_ptr itemInstance); @@ -31,4 +30,5 @@ public: const Tier* getTier(); bool isValidRepairItem(std::shared_ptr source, std::shared_ptr repairItem); + attrAttrModMap* getDefaultAttributeModifiers(); }; \ No newline at end of file diff --git a/Minecraft.World/Items/WrittenBookItem.h b/Minecraft.World/Items/WrittenBookItem.h new file mode 100644 index 000000000..513947863 --- /dev/null +++ b/Minecraft.World/Items/WrittenBookItem.h @@ -0,0 +1,81 @@ +#pragma once + +/* +class WrittenBookItem extends Item { + + public static final int TITLE_LENGTH = 16; + public static final int PAGE_LENGTH = 256; + public static final int MAX_PAGES = 50; + public static final String TAG_TITLE = "title"; + public static final String TAG_AUTHOR = "author"; + public static final String TAG_PAGES = "pages"; + + public WrittenBookItem(int id) { + super(id); + setMaxStackSize(1); + } + + public static boolean makeSureTagIsValid(CompoundTag bookTag) { + + if (!WritingBookItem.makeSureTagIsValid(bookTag)) { + return false; + } + + if (!bookTag.contains(TAG_TITLE)) { + return false; + } + String title = bookTag.getString(TAG_TITLE); + if (title == null || title.length() > TITLE_LENGTH) { + return false; + } + + if (!bookTag.contains(TAG_AUTHOR)) { + return false; + } + + return true; + } + + @Override + public String getHoverName(ItemInstance itemInstance) { + if (itemInstance.hasTag()) { + CompoundTag itemTag = itemInstance.getTag(); + + StringTag titleTag = (StringTag) +itemTag.get(TAG_TITLE); if (titleTag != null) { return titleTag.toString(); + } + } + return super.getHoverName(itemInstance); + } + + @Override + public void appendHoverText(ItemInstance itemInstance, Player +player, List lines, boolean advanced) { + + if (itemInstance.hasTag()) { + CompoundTag itemTag = itemInstance.getTag(); + + StringTag authorTag = (StringTag) +itemTag.get(TAG_AUTHOR); if (authorTag != null) { lines.add(ChatFormatting.GRAY ++ String.format(I18n.get("book.byAuthor", authorTag.data))); + } + } + } + + @Override + public ItemInstance use(ItemInstance itemInstance, Level level, +Player player) { player.openItemInstanceGui(itemInstance); return itemInstance; + } + + @Override + public boolean shouldOverrideMultiplayerNBT() { + return true; + } + + @Override + public boolean isFoil(ItemInstance itemInstance) { + return true; + } + +}; +*/ \ No newline at end of file