TU19: merge Minecraft.World/Items

This commit is contained in:
Tropical 2026-03-21 16:39:12 -05:00
parent 3d3fa566c7
commit 29522d1ac9
98 changed files with 2460 additions and 1192 deletions

View file

@ -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<ItemInstance> ArmorItem::ArmorDispenseItemBehavior::execute(
BlockSource* source, std::shared_ptr<ItemInstance> 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<std::shared_ptr<Entity> >* entities =
source->getWorld()->getEntitiesOfClass(typeid(LivingEntity), bb,
selector);
delete selector;
if (entities->size() > 0) {
std::shared_ptr<LivingEntity> target =
std::dynamic_pointer_cast<LivingEntity>(entities->at(0));
int offset = target->instanceof(eTYPE_PLAYER) ? 1 : 0;
int slot = Mob::getEquipmentSlotForItem(dispensed);
std::shared_ptr<ItemInstance> equip = dispensed->copy();
equip->count = 1;
target->setEquippedSlot(slot - offset, equip);
if (target->instanceof(eTYPE_MOB))
std::dynamic_pointer_cast<Mob>(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<ItemInstance> item, int spriteLayer) {
@ -88,7 +129,6 @@ int ArmorItem::getColor(std::shared_ptr<ItemInstance> item, int spriteLayer) {
return color;
}
//@Override
bool ArmorItem::hasMultipleSpriteLayers() {
return armorType == ArmorMaterial::CLOTH;
}
@ -129,7 +169,6 @@ int ArmorItem::getColor(std::shared_ptr<ItemInstance> item) {
}
}
//@Override
Icon* ArmorItem::getLayerIcon(int auxValue, int spriteLayer) {
if (spriteLayer == 1) {
return overlayIcon;
@ -175,7 +214,6 @@ bool ArmorItem::isValidRepairItem(std::shared_ptr<ItemInstance> source,
return Item::isValidRepairItem(source, repairItem);
}
//@Override
void ArmorItem::registerIcons(IconRegister* iconRegister) {
Item::registerIcons(iconRegister);

View file

@ -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<ItemInstance> execute(
BlockSource* source, std::shared_ptr<ItemInstance> 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<ItemInstance> item, int spriteLayer);
//@Override
bool hasMultipleSpriteLayers();
virtual int getColor(std::shared_ptr<ItemInstance> item, int spriteLayer);
virtual bool hasMultipleSpriteLayers();
virtual int getEnchantmentValue();
virtual const ArmorMaterial* getMaterial();
virtual bool hasCustomColor(std::shared_ptr<ItemInstance> item);
virtual int getColor(std::shared_ptr<ItemInstance> item);
const ArmorMaterial* getMaterial();
bool hasCustomColor(std::shared_ptr<ItemInstance> item);
int getColor(std::shared_ptr<ItemInstance> item);
virtual Icon* getLayerIcon(int auxValue, int spriteLayer);
virtual void clearColor(std::shared_ptr<ItemInstance> item);
virtual void setColor(std::shared_ptr<ItemInstance> item, int color);
//@Override
Icon* getLayerIcon(int auxValue, int spriteLayer);
void clearColor(std::shared_ptr<ItemInstance> item);
void setColor(std::shared_ptr<ItemInstance> item, int color);
bool isValidRepairItem(std::shared_ptr<ItemInstance> source,
std::shared_ptr<ItemInstance> repairItem);
//@Override
void registerIcons(IconRegister* iconRegister);
virtual bool isValidRepairItem(std::shared_ptr<ItemInstance> source,
std::shared_ptr<ItemInstance> repairItem);
virtual void registerIcons(IconRegister* iconRegister);
static Icon* getEmptyIcon(int slot);
};

View file

@ -14,6 +14,8 @@ bool BedItem::useOn(std::shared_ptr<ItemInstance> itemInstance,
std::shared_ptr<Player> 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> 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> 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> 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--;

View file

@ -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> player) {
bool BoatItem::TestUse(std::shared_ptr<ItemInstance> itemInstance, Level* level,
std::shared_ptr<Player> 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<ItemInstance> 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<Boat>(
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> boat = std::shared_ptr<Boat>(
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;

View file

@ -9,7 +9,8 @@ class BoatItem : public Item {
public:
BoatItem(int id);
virtual bool TestUse(Level* level, std::shared_ptr<Player> player);
virtual bool TestUse(std::shared_ptr<ItemInstance> itemInstance,
Level* level, std::shared_ptr<Player> player);
virtual std::shared_ptr<ItemInstance> use(
std::shared_ptr<ItemInstance> itemInstance, Level* level,
std::shared_ptr<Player> player);

View file

@ -25,7 +25,7 @@ std::shared_ptr<ItemInstance> 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<ItemInstance> BottleItem::use(
}
// 4J-PB - added to allow tooltips
bool BottleItem::TestUse(Level* level, std::shared_ptr<Player> player) {
bool BottleItem::TestUse(std::shared_ptr<ItemInstance> itemInstance,
Level* level, std::shared_ptr<Player> 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> 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) {

View file

@ -14,7 +14,8 @@ public:
virtual std::shared_ptr<ItemInstance> use(
std::shared_ptr<ItemInstance> itemInstance, Level* level,
std::shared_ptr<Player> player);
virtual bool TestUse(Level* level, std::shared_ptr<Player> player);
virtual bool TestUse(std::shared_ptr<ItemInstance> itemInstance,
Level* level, std::shared_ptr<Player> player);
//@Override
void registerIcons(IconRegister* iconRegister);

View file

@ -50,10 +50,11 @@ void BowItem::releaseUsing(std::shared_ptr<ItemInstance> 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;

View file

@ -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> 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> itemInstance,
Level* level, std::shared_ptr<Player> 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> 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> 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<ItemInstance> 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<ItemInstance> 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<ItemInstance> 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<ItemInstance>(
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<ItemInstance>(
new ItemInstance(Item::milk));
} else {
if (!player->inventory->add(std::shared_ptr<ItemInstance>(
new ItemInstance(Item::milk)))) {
player->drop(std::shared_ptr<ItemInstance>(
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;

View file

@ -12,22 +12,11 @@ private:
public:
BucketItem(int id, int content);
virtual bool TestUse(Level* level, std::shared_ptr<Player> player);
virtual bool TestUse(std::shared_ptr<ItemInstance> itemInstance,
Level* level, std::shared_ptr<Player> player);
virtual std::shared_ptr<ItemInstance> use(
std::shared_ptr<ItemInstance> itemInstance, Level* level,
std::shared_ptr<Player> 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);
};

View file

@ -25,7 +25,7 @@ std::shared_ptr<ItemInstance> 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<ItemInstance> replacement =

View file

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

View file

@ -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<ItemInstance> instance);
Icon* getIcon(int auxValue);
void registerIcons(IconRegister* iconRegister);
};

View file

@ -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> itemInstance,
}
bool DiggerItem::hurtEnemy(std::shared_ptr<ItemInstance> itemInstance,
std::shared_ptr<Mob> mob,
std::shared_ptr<Mob> attacker) {
itemInstance->hurt(2, attacker);
std::shared_ptr<LivingEntity> mob,
std::shared_ptr<LivingEntity> attacker) {
itemInstance->hurtAndBreak(2, attacker);
return true;
}
bool DiggerItem::mineBlock(std::shared_ptr<ItemInstance> itemInstance,
Level* level, int tile, int x, int y, int z,
std::shared_ptr<Mob> owner) {
std::shared_ptr<LivingEntity> 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> entity) {
return attackDamage;
}
bool DiggerItem::isHandEquipped() { return true; }
int DiggerItem::getEnchantmentValue() { return tier->getEnchantmentValue(); }
@ -54,4 +52,14 @@ bool DiggerItem::isValidRepairItem(std::shared_ptr<ItemInstance> 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;
}

View file

@ -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> itemInstance,
Tile* tile);
virtual bool hurtEnemy(std::shared_ptr<ItemInstance> itemInstance,
std::shared_ptr<Mob> mob,
std::shared_ptr<Mob> attacker);
std::shared_ptr<LivingEntity> mob,
std::shared_ptr<LivingEntity> attacker);
virtual bool mineBlock(std::shared_ptr<ItemInstance> itemInstance,
Level* level, int tile, int x, int y, int z,
std::shared_ptr<Mob> owner);
virtual int getAttackDamage(std::shared_ptr<Entity> entity);
std::shared_ptr<LivingEntity> owner);
virtual bool isHandEquipped();
virtual int getEnchantmentValue();
const Tier* getTier();
bool isValidRepairItem(std::shared_ptr<ItemInstance> source,
std::shared_ptr<ItemInstance> repairItem);
virtual attrAttrModMap* getDefaultAttributeModifiers();
};

View file

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

View file

@ -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> itemInstance,
std::shared_ptr<Player> 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> 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> itemInstance,
return false;
}
bool DyePowderItem::growCrop(std::shared_ptr<ItemInstance> 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> itemInstance,
std::shared_ptr<Mob> mob) {
std::shared_ptr<Player> player,
std::shared_ptr<LivingEntity> mob) {
if (std::dynamic_pointer_cast<Sheep>(mob) != NULL) {
std::shared_ptr<Sheep> sheep = std::dynamic_pointer_cast<Sheep>(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]);
}
}

View file

@ -46,8 +46,14 @@ public:
std::shared_ptr<Player> 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> 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> itemInstance,
std::shared_ptr<Mob> mob);
std::shared_ptr<Player> player,
std::shared_ptr<LivingEntity> mob);
//@Override
void registerIcons(IconRegister* iconRegister);

View file

@ -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<ItemInstance> EggItem::use(
std::shared_ptr<ItemInstance> instance, Level* level,
@ -21,11 +20,10 @@ std::shared_ptr<ItemInstance> EggItem::use(
if (!player->abilities.instabuild) {
instance->count--;
}
level->playSound(std::dynamic_pointer_cast<Entity>(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<ThrownEgg>(
new ThrownEgg(level, std::dynamic_pointer_cast<Mob>(player))));
level->addEntity(
std::shared_ptr<ThrownEgg>(new ThrownEgg(level, player)));
return instance;
}

View file

@ -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<ItemInstance> EmptyMapItem::use(
std::shared_ptr<ItemInstance> itemInstance, Level* level,
std::shared_ptr<Player> player) {
// shared_ptr<ItemInstance> map = shared_ptr<ItemInstance>( 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<ItemInstance> map =
std::shared_ptr<ItemInstance>(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;
}

View file

@ -0,0 +1,12 @@
#pragma once
#include "ComplexItem.h"
class EmptyMapItem : public ComplexItem {
public:
EmptyMapItem(int id);
std::shared_ptr<ItemInstance> use(
std::shared_ptr<ItemInstance> itemInstance, Level* level,
std::shared_ptr<Player> player);
};

View file

@ -41,10 +41,8 @@ ListTag<CompoundTag>* EnchantedBookItem::getEnchantments(
void EnchantedBookItem::appendHoverText(
std::shared_ptr<ItemInstance> itemInstance, std::shared_ptr<Player> player,
std::vector<std::wstring>* lines, bool advanced,
std::vector<std::wstring>& unformattedStrings) {
Item::appendHoverText(itemInstance, player, lines, advanced,
unformattedStrings);
std::vector<HtmlString>* lines, bool advanced) {
Item::appendHoverText(itemInstance, player, lines, advanced);
ListTag<CompoundTag>* 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));
}
}
}

View file

@ -16,8 +16,7 @@ public:
ListTag<CompoundTag>* getEnchantments(std::shared_ptr<ItemInstance> item);
void appendHoverText(std::shared_ptr<ItemInstance> itemInstance,
std::shared_ptr<Player> player,
std::vector<std::wstring>* lines, bool advanced,
std::vector<std::wstring>& unformattedStrings);
std::vector<HtmlString>* lines, bool advanced);
void addEnchantment(std::shared_ptr<ItemInstance> item,
EnchantmentInstance* enchantment);
std::shared_ptr<ItemInstance> createForEnchantment(

View file

@ -18,12 +18,15 @@ bool EnderEyeItem::useOn(std::shared_ptr<ItemInstance> 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<ItemInstance> 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<ItemInstance> instance,
return false;
}
bool EnderEyeItem::TestUse(Level* level, std::shared_ptr<Player> player) {
bool EnderEyeItem::TestUse(std::shared_ptr<ItemInstance> itemInstance,
Level* level, std::shared_ptr<Player> 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> 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<ItemInstance> 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> eyeOfEnderSignal =
std::shared_ptr<EyeOfEnderSignal>( 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;
}

View file

@ -10,7 +10,8 @@ public:
std::shared_ptr<Player> 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> player);
virtual bool TestUse(std::shared_ptr<ItemInstance> itemInstance,
Level* level, std::shared_ptr<Player> player);
virtual std::shared_ptr<ItemInstance> use(
std::shared_ptr<ItemInstance> instance, Level* level,
std::shared_ptr<Player> player);

View file

@ -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> player) {
bool EnderpearlItem::TestUse(std::shared_ptr<ItemInstance> itemInstance,
Level* level, std::shared_ptr<Player> player) {
return true;
}
@ -22,8 +23,8 @@ std::shared_ptr<ItemInstance> 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<ThrownEnderpearl>(
new ThrownEnderpearl(level, player)));

View file

@ -10,5 +10,6 @@ public:
std::shared_ptr<ItemInstance> instance, Level* level,
std::shared_ptr<Player> player);
// 4J added
virtual bool TestUse(Level* level, std::shared_ptr<Player> player);
virtual bool TestUse(std::shared_ptr<ItemInstance> instance, Level* level,
std::shared_ptr<Player> player);
};

View file

@ -12,7 +12,8 @@ bool ExperienceItem::isFoil(std::shared_ptr<ItemInstance> itemInstance) {
return true;
}
bool ExperienceItem::TestUse(Level* level, std::shared_ptr<Player> player) {
bool ExperienceItem::TestUse(std::shared_ptr<ItemInstance> itemInstance,
Level* level, std::shared_ptr<Player> player) {
return true;
}
@ -22,8 +23,8 @@ std::shared_ptr<ItemInstance> 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<ThrownExpBottle>(
new ThrownExpBottle(level, player)));

View file

@ -12,5 +12,6 @@ public:
virtual std::shared_ptr<ItemInstance> use(
std::shared_ptr<ItemInstance> itemInstance, Level* level,
std::shared_ptr<Player> player);
virtual bool TestUse(Level* level, std::shared_ptr<Player> player);
virtual bool TestUse(std::shared_ptr<ItemInstance> itemInstance,
Level* level, std::shared_ptr<Player> player);
};

View file

@ -12,7 +12,7 @@ FireChargeItem::FireChargeItem(int id) : Item(id) {
m_dragonFireballIcon = NULL;
}
bool FireChargeItem::useOn(std::shared_ptr<ItemInstance> itemInstance,
bool FireChargeItem::useOn(std::shared_ptr<ItemInstance> instance,
std::shared_ptr<Player> 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> 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> 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;
}

View file

@ -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<ItemInstance> 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<ItemInstance> 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> itemInstance, std::shared_ptr<Player> player,
std::vector<HtmlString>* 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<HtmlString>* 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");
}

View file

@ -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<ItemInstance> item, int spriteLayer);
virtual bool hasMultipleSpriteLayers();
static Tag* getExplosionTagField(std::shared_ptr<ItemInstance> instance,
const std::wstring& field);
virtual void appendHoverText(std::shared_ptr<ItemInstance> itemInstance,
std::shared_ptr<Player> player,
std::vector<HtmlString>* lines, bool advanced);
static void appendHoverText(CompoundTag* expTag,
std::vector<HtmlString>* lines);
virtual void registerIcons(IconRegister* iconRegister);
};

View file

@ -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<ItemInstance> instance,
std::shared_ptr<Player> 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<FireworksRocketEntity> f =
std::shared_ptr<FireworksRocketEntity>(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> itemInstance,
std::shared_ptr<Player> player,
std::vector<HtmlString>* 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<int>((fireTag->getByte(TAG_FLIGHT))));
}
ListTag<CompoundTag>* explosions =
(ListTag<CompoundTag>*)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<HtmlString> 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());
}
}
}
}

View file

@ -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<ItemInstance> instance,
std::shared_ptr<Player> 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> itemInstance,
std::shared_ptr<Player> player,
std::vector<HtmlString>* lines, bool advanced);
};

View file

@ -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<ItemInstance> FishingRodItem::use(
std::shared_ptr<Player> 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<ItemInstance> 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; }

View file

@ -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<ItemInstance> instance, Level* level,
std::shared_ptr<Player> player);
//@Override
void registerIcons(IconRegister* iconRegister);
Icon* getEmptyIcon();
};

View file

@ -26,7 +26,7 @@ bool FlintAndSteelItem::useOn(std::shared_ptr<ItemInstance> 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<ItemInstance> 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;

View file

@ -42,8 +42,8 @@ std::shared_ptr<ItemInstance> 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);

View file

@ -26,11 +26,16 @@ const Rarity* GoldenAppleItem::getRarity(
void GoldenAppleItem::addEatEffect(std::shared_ptr<ItemInstance> instance,
Level* level,
std::shared_ptr<Player> 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));

View file

@ -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<ItemInstance> instance,
@ -26,7 +24,7 @@ bool HangingEntityItem::useOn(std::shared_ptr<ItemInstance> 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<ItemInstance> instance,
int dir = Direction::FACING_DIRECTION[face];
std::shared_ptr<HangingEntity> 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<ItemInstance> instance,
return true;
}
std::shared_ptr<HangingEntity> HangingEntityItem::createEntity(Level* level,
int x, int y,
int z, int dir) {
std::shared_ptr<HangingEntity> 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> painting =
std::shared_ptr<Painting>(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<HangingEntity>(painting);
} else if (eType == eTYPE_ITEM_FRAME) {
@ -84,3 +90,29 @@ std::shared_ptr<HangingEntity> HangingEntityItem::createEntity(Level* level,
return nullptr;
}
}
// 4J Adding overrides for art tools
void HangingEntityItem::appendHoverText(
std::shared_ptr<ItemInstance> itemInstance, std::shared_ptr<Player> player,
std::vector<HtmlString>* 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);
}
}

View file

@ -19,6 +19,12 @@ public:
bool bTestUseOnOnly); //, float clickX, float clickY, float clickZ);
private:
std::shared_ptr<HangingEntity> createEntity(Level* level, int x, int y,
int z, int dir);
std::shared_ptr<HangingEntity> 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> itemInstance,
std::shared_ptr<Player> player,
std::vector<HtmlString>* lines, bool advanced);
};

View file

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

View file

@ -15,15 +15,13 @@ bool HoeItem::useOn(std::shared_ptr<ItemInstance> instance,
std::shared_ptr<Player> 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<ItemInstance> 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;
}

File diff suppressed because it is too large Load diff

View file

@ -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<Item> {
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> itemInstance);
const bool useOn(std::shared_ptr<ItemInstance> itemInstance, Level* level,
int x, int y, int z, int face,
bool bTestUseOnOnly = false);
virtual bool useOn(std::shared_ptr<ItemInstance> itemInstance,
std::shared_ptr<Player> 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> itemInstance,
Tile* tile);
virtual bool TestUse(Level* level, std::shared_ptr<Player> player);
virtual bool TestUse(std::shared_ptr<ItemInstance> itemInstance,
Level* level, std::shared_ptr<Player> player);
virtual std::shared_ptr<ItemInstance> use(
std::shared_ptr<ItemInstance> itemInstance, Level* level,
std::shared_ptr<Player> player);
@ -653,8 +694,8 @@ public:
* @return
*/
virtual bool hurtEnemy(std::shared_ptr<ItemInstance> itemInstance,
std::shared_ptr<Mob> mob,
std::shared_ptr<Mob> attacker);
std::shared_ptr<LivingEntity> mob,
std::shared_ptr<LivingEntity> attacker);
/**
* Returns true when the item was used to mine more efficiently
@ -669,17 +710,18 @@ public:
*/
virtual bool mineBlock(std::shared_ptr<ItemInstance> itemInstance,
Level* level, int tile, int x, int y, int z,
std::shared_ptr<Mob> owner);
std::shared_ptr<LivingEntity> owner);
virtual int getAttackDamage(std::shared_ptr<Entity> entity);
virtual bool canDestroySpecial(Tile* tile);
virtual bool interactEnemy(std::shared_ptr<ItemInstance> itemInstance,
std::shared_ptr<Mob> mob);
std::shared_ptr<Player> player,
std::shared_ptr<LivingEntity> 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<ItemInstance> instance);
LPCWSTR getDescription();
LPCWSTR getDescription(std::shared_ptr<ItemInstance> instance);
virtual unsigned int getDescriptionId(int iData = -1);
virtual unsigned int getDescriptionId(
std::shared_ptr<ItemInstance> instance);
@ -715,12 +757,9 @@ protected:
public:
virtual std::wstring getPotionBrewingFormula();
virtual bool hasPotionBrewingFormula();
virtual void appendHoverText(
std::shared_ptr<ItemInstance> itemInstance,
std::shared_ptr<Player> player, std::vector<std::wstring>* lines,
bool advanced,
std::vector<std::wstring>&
unformattedStrings); // 4J Added unformattedStrings
virtual void appendHoverText(std::shared_ptr<ItemInstance> itemInstance,
std::shared_ptr<Player> player,
std::vector<HtmlString>* lines, bool advanced);
virtual std::wstring getHoverName(
std::shared_ptr<ItemInstance> itemInstance);
virtual bool isFoil(std::shared_ptr<ItemInstance> 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<ItemInstance> source,
std::shared_ptr<ItemInstance> repairItem);
virtual void registerIcons(IconRegister* iconRegister);
virtual attrAttrModMap* getDefaultAttributeModifiers();
};

View file

@ -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> 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> player) {
return getItem()->TestUse(level, player);
bool ItemInstance::TestUse(std::shared_ptr<ItemInstance> itemInstance,
Level* level, std::shared_ptr<Player> player) {
return getItem()->TestUse(itemInstance, level, player);
}
std::shared_ptr<ItemInstance> 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<Mob> owner) {
bool ItemInstance::hurt(int dmg, Random* random) {
if (!isDamageableItem()) {
return;
return false;
}
std::shared_ptr<Player> player = std::dynamic_pointer_cast<Player>(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<LivingEntity> owner) {
std::shared_ptr<Player> player = std::dynamic_pointer_cast<Player>(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<BowItem*>(getItem()) != NULL) {
player->removeSelectedItem();
}
}
if (count < 0) count = 0;
auxValue = 0;
}
}
void ItemInstance::hurtEnemy(std::shared_ptr<Mob> mob,
void ItemInstance::hurtEnemy(std::shared_ptr<LivingEntity> mob,
std::shared_ptr<Player> 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> 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> mob) {
return Item::items[id]->interactEnemy(shared_from_this(), mob);
bool ItemInstance::interactEnemy(std::shared_ptr<Player> player,
std::shared_ptr<LivingEntity> mob) {
return Item::items[id]->interactEnemy(shared_from_this(), player, mob);
}
std::shared_ptr<ItemInstance> ItemInstance::copy() const {
@ -379,7 +408,10 @@ ListTag<CompoundTag>* ItemInstance::getEnchantmentTags() {
return (ListTag<CompoundTag>*)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<std::wstring>* ItemInstance::getHoverText(
std::shared_ptr<Player> player, bool advanced,
std::vector<std::wstring>& unformattedStrings) {
std::vector<std::wstring>* lines = new std::vector<std::wstring>();
std::vector<HtmlString>* ItemInstance::getHoverText(
std::shared_ptr<Player> player, bool advanced) {
std::vector<HtmlString>* lines = new std::vector<HtmlString>();
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"<i>" + title + L"</i>";
//}
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<CompoundTag>* list = getEnchantmentTags();
@ -465,25 +508,87 @@ std::vector<std::wstring>* 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<StringTag> *lore = (ListTag<StringTag> *)
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<int>((getMaxDamage()) - getDamageValue()) + L" / " +
_toString<int>(getMaxDamage());
lines->push_back(HtmlString(damageStr));
}
}
return lines;
}
// 4J Added
std::vector<std::wstring>* ItemInstance::getHoverTextOnly(
std::shared_ptr<Player> player, bool advanced,
std::vector<std::wstring>& unformattedStrings) {
std::vector<std::wstring>* lines = new std::vector<std::wstring>();
std::vector<HtmlString>* ItemInstance::getHoverTextOnly(
std::shared_ptr<Player> player, bool advanced) {
std::vector<HtmlString>* lines = new std::vector<HtmlString>();
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<CompoundTag>* list = getEnchantmentTags();
@ -495,9 +600,7 @@ std::vector<std::wstring>* 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<ItemFrame> frame) {
this->frame = frame;
}
std::shared_ptr<ItemFrame> 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<CompoundTag>* entries =
(ListTag<CompoundTag>*)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<eATTRIBUTE_ID, AttributeModifier*>(
static_cast<eATTRIBUTE_ID>(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<ItemFrame> frame) {
this->frame = frame;
}
std::shared_ptr<ItemFrame> 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);
}
}

View file

@ -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<ItemInstance> {
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> 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> player);
bool TestUse(std::shared_ptr<ItemInstance> itemInstance, Level* level,
std::shared_ptr<Player> player);
std::shared_ptr<ItemInstance> use(Level* level,
std::shared_ptr<Player> player);
std::shared_ptr<ItemInstance> useTimeDepleted(
@ -89,13 +96,15 @@ public:
int getAuxValue() const;
void setAuxValue(int value);
int getMaxDamage();
void hurt(int i, std::shared_ptr<Mob> owner);
void hurtEnemy(std::shared_ptr<Mob> mob, std::shared_ptr<Player> attacker);
bool hurt(int dmg, Random* random);
void hurtAndBreak(int dmg, std::shared_ptr<LivingEntity> owner);
void hurtEnemy(std::shared_ptr<LivingEntity> mob,
std::shared_ptr<Player> attacker);
void mineBlock(Level* level, int tile, int x, int y, int z,
std::shared_ptr<Player> owner);
int getAttackDamage(std::shared_ptr<Entity> entity);
bool canDestroySpecial(Tile* tile);
bool interactEnemy(std::shared_ptr<Mob> mob);
bool interactEnemy(std::shared_ptr<Player> player,
std::shared_ptr<LivingEntity> mob);
std::shared_ptr<ItemInstance> 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<std::wstring>* getHoverText(
std::shared_ptr<Player> player, bool advanced,
std::vector<std::wstring>& unformattedStrings);
std::vector<std::wstring>* getHoverTextOnly(
std::shared_ptr<Player> player, bool advanced,
std::vector<std::wstring>& unformattedStrings); // 4J Added
std::vector<HtmlString>* getHoverText(std::shared_ptr<Player> player,
bool advanced);
std::vector<HtmlString>* getHoverTextOnly(std::shared_ptr<Player> 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<ItemFrame> frame);
std::shared_ptr<ItemFrame> 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<ItemFrame> frame);
std::shared_ptr<ItemFrame> getFrame();
int getBaseRepairCost();
void setRepairCost(int cost);
};
};

View file

@ -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> itemInstance,
std::shared_ptr<Player> 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> player, Level* level,
int x, int y, int z) {
// check if there is a knot at the given coordinate
std::shared_ptr<LeashFenceKnotEntity> 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<std::shared_ptr<Entity> >* 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> mob = std::dynamic_pointer_cast<Mob>(*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> player, Level* level,
int x, int y, int z) {
// look for entities that can be attached to the fence
double range = 7;
std::vector<std::shared_ptr<Entity> >* 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> mob = std::dynamic_pointer_cast<Mob>(*it);
if (mob->isLeashed() && mob->getLeashHolder() == player)
return true;
}
}
return false;
}

View file

@ -0,0 +1,17 @@
#pragma once
#include "Item.h"
class LeashItem : public Item {
public:
LeashItem(int id);
bool useOn(std::shared_ptr<ItemInstance> itemInstance,
std::shared_ptr<Player> 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> player, Level* level,
int x, int y, int z);
static bool bindPlayerMobsTest(std::shared_ptr<Player> player, Level* level,
int x, int y, int z);
};

View file

@ -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<MapItemSavedData> MapItem::getSavedData(short idNum,
Level* level) {
@ -94,7 +94,8 @@ std::shared_ptr<MapItemSavedData> MapItem::getSavedData(
void MapItem::update(Level* level, std::shared_ptr<Entity> player,
std::shared_ptr<MapItemSavedData> 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<Entity> player,
if (level->dimension->hasCeiling) {
rad /= 2;
}
data->step++;
std::shared_ptr<MapItemSavedData::HoldingPlayer> hp =
data->getHoldingPlayer(std::dynamic_pointer_cast<Player>(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<Entity> 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<Entity> 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<Entity> 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> itemInstance,
if (level->isClientSide) return;
std::shared_ptr<MapItemSavedData> data = getSavedData(itemInstance, level);
if (std::dynamic_pointer_cast<Player>(owner) != NULL) {
if (owner->instanceof(eTYPE_PLAYER)) {
std::shared_ptr<Player> player =
std::dynamic_pointer_cast<Player>(owner);
@ -293,6 +289,21 @@ void MapItem::inventoryTick(std::shared_ptr<ItemInstance> itemInstance,
}
}
std::shared_ptr<Packet> MapItem::getUpdatePacket(
std::shared_ptr<ItemInstance> itemInstance, Level* level,
std::shared_ptr<Player> player) {
charArray data = MapItem::getSavedData(itemInstance, level)
->getUpdatePacket(itemInstance, level, player);
if (data.data == NULL || data.length == 0) return nullptr;
std::shared_ptr<Packet> retval =
std::shared_ptr<Packet>(new ComplexItemDataPacket(
(short)Item::map->id, (short)itemInstance->getAuxValue(), data));
delete data.data;
return retval;
}
void MapItem::onCraftedBy(std::shared_ptr<ItemInstance> itemInstance,
Level* level, std::shared_ptr<Player> player) {
wchar_t buf[64];
@ -333,17 +344,20 @@ void MapItem::onCraftedBy(std::shared_ptr<ItemInstance> itemInstance,
data->setDirty();
}
std::shared_ptr<Packet> MapItem::getUpdatePacket(
std::shared_ptr<ItemInstance> itemInstance, Level* level,
std::shared_ptr<Player> player) {
charArray data = MapItem::getSavedData(itemInstance, level)
->getUpdatePacket(itemInstance, level, player);
// 4J - Don't want
/*
void appendHoverText(ItemInstance itemInstance, Player player, List<String>
lines, boolean advanced) { MapItemSavedData data = getSavedData(itemInstance,
player.level);
if (data.data == NULL || data.length == 0) return nullptr;
std::shared_ptr<Packet> retval =
std::shared_ptr<Packet>(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 + ")");
}
}
}
*/

View file

@ -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> itemInstance,
Level* level, std::shared_ptr<Entity> owner,
int slot, bool selected);
virtual void onCraftedBy(std::shared_ptr<ItemInstance> itemInstance,
Level* level, std::shared_ptr<Player> player);
std::shared_ptr<Packet> getUpdatePacket(
std::shared_ptr<ItemInstance> itemInstance, Level* level,
std::shared_ptr<Player> player);
virtual void onCraftedBy(std::shared_ptr<ItemInstance> itemInstance,
Level* level, std::shared_ptr<Player> player);
};

View file

@ -6,9 +6,64 @@
#include "ItemInstance.h"
#include "MinecartItem.h"
std::shared_ptr<ItemInstance> MinecartItem::MinecartDispenseBehavior::execute(
BlockSource* source, std::shared_ptr<ItemInstance> 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 =
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<ItemInstance> instance,
@ -18,11 +73,15 @@ bool MinecartItem::useOn(std::shared_ptr<ItemInstance> 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<Minecart>(
new Minecart(level, x + 0.5f, y + 0.5f, z + 0.5f, type)));
std::shared_ptr<Minecart> 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--;
}

View file

@ -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<ItemInstance> execute(
BlockSource* source, std::shared_ptr<ItemInstance> dispensed,
eOUTCOME& outcome);
protected:
virtual void playSound(BlockSource* source);
};
public:
int type;

View file

@ -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> itemInstance,
std::shared_ptr<Player> player,
std::shared_ptr<LivingEntity> target) {
if (!itemInstance->hasCustomHoverName()) return false;
if ((target != NULL) && target->instanceof(eTYPE_MOB)) {
std::shared_ptr<Mob> mob = std::dynamic_pointer_cast<Mob>(target);
mob->setCustomName(itemInstance->getHoverName());
mob->setPersistenceRequired();
itemInstance->count--;
return true;
}
return Item::interactEnemy(itemInstance, player, target);
}

View file

@ -0,0 +1,12 @@
#pragma once
#include "Item.h"
class NameTagItem : public Item {
public:
NameTagItem(int id);
bool interactEnemy(std::shared_ptr<ItemInstance> itemInstance,
std::shared_ptr<Player> player,
std::shared_ptr<LivingEntity> target);
};

View file

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

View file

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

View file

@ -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<MobEffectInstance*>* PotionItem::getMobEffects(
std::shared_ptr<ItemInstance> potion) {
return getMobEffects(potion->getAuxValue());
if (!potion->hasTag() ||
!potion->getTag()->contains(L"CustomPotionEffects")) {
std::vector<MobEffectInstance*>* 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<MobEffectInstance*>(*effects);
} else {
std::vector<MobEffectInstance*>* effects =
new std::vector<MobEffectInstance*>();
ListTag<CompoundTag>* customList =
(ListTag<CompoundTag>*)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<MobEffectInstance*>* PotionItem::getMobEffects(int auxValue) {
@ -84,7 +111,8 @@ UseAnim PotionItem::getUseAnimation(
return UseAnim_drink;
}
bool PotionItem::TestUse(Level* level, std::shared_ptr<Player> player) {
bool PotionItem::TestUse(std::shared_ptr<ItemInstance> itemInstance,
Level* level, std::shared_ptr<Player> player) {
return true;
}
@ -93,8 +121,8 @@ std::shared_ptr<ItemInstance> PotionItem::use(
std::shared_ptr<Player> 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<ThrownPotion>(
new ThrownPotion(level, player, instance->getAuxValue())));
@ -198,22 +226,46 @@ std::wstring PotionItem::getHoverName(
return elementName;
}
void PotionItem::appendHoverText(
std::shared_ptr<ItemInstance> itemInstance, std::shared_ptr<Player> player,
std::vector<std::wstring>* lines, bool advanced,
std::vector<std::wstring>& unformattedStrings) {
void PotionItem::appendHoverText(std::shared_ptr<ItemInstance> itemInstance,
std::shared_ptr<Player> player,
std::vector<HtmlString>* lines,
bool advanced) {
if (itemInstance->getAuxValue() == 0) {
return;
}
std::vector<MobEffectInstance*>* 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<Attribute*, AttributeModifier*>*
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<eATTRIBUTE_ID, AttributeModifier*>(
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"<22>c + effectString); //"<22>c"
eMinecraftColour color = eMinecraftColour_NOT_SET;
if (mobEffect->isHarmful()) {
color = eHTMLColor_c;
} else {
colour = eHTMLColor_7;
// lines->push_back(L"<22>7" + effectString); //"<22>7"
color = eHTMLColor_7;
}
swprintf(formatted, 256, L"<font color=\"#%08x\">%ls</font>",
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"<font color=\"#%08x\">%ls</font>",
app.GetHTMLColour(eHTMLColor_7), effectString.c_str());
lines->push_back(formatted); //"<22>7"
lines->push_back(HtmlString(effectString, eHTMLColor_7)); //"<22>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> itemInstance) {
bool PotionItem::isFoistd::l(std::shared_ptr<ItemInstance> itemInstance) {
std::vector<MobEffectInstance*>* mobEffects = getMobEffects(itemInstance);
return mobEffects != NULL && !mobEffects->empty();
}
unsigned int PotionItem::getUseDescriptionId(
unsigned int PotionItem::getUseDescriptionIstd::d(
std::shared_ptr<ItemInstance> 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;

View file

@ -34,7 +34,8 @@ public:
virtual std::shared_ptr<ItemInstance> use(
std::shared_ptr<ItemInstance> instance, Level* level,
std::shared_ptr<Player> player);
virtual bool TestUse(Level* level, std::shared_ptr<Player> player);
virtual bool TestUse(std::shared_ptr<ItemInstance> itemInstance,
Level* level, std::shared_ptr<Player> player);
virtual bool useOn(std::shared_ptr<ItemInstance> itemInstance,
std::shared_ptr<Player> player, Level* level, int x,
int y, int z, int face, float clickX, float clickY,
@ -50,9 +51,7 @@ public:
std::shared_ptr<ItemInstance> itemInstance);
virtual void appendHoverText(std::shared_ptr<ItemInstance> itemInstance,
std::shared_ptr<Player> player,
std::vector<std::wstring>* lines,
bool advanced,
std::vector<std::wstring>& unformattedStrings);
std::vector<HtmlString>* lines, bool advanced);
virtual bool isFoil(std::shared_ptr<ItemInstance> itemInstance);
virtual unsigned int getUseDescriptionId(

View file

@ -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<std::wstring, RecordingItem*> 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> 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> itemInstance,
return false;
}
void RecordingItem::appendHoverText(
std::shared_ptr<ItemInstance> itemInstance, std::shared_ptr<Player> player,
std::vector<std::wstring>* lines, bool advanced,
std::vector<std::wstring>& unformattedStrings) {
eMinecraftColour rarityColour =
getRarity(std::shared_ptr<ItemInstance>())->color;
int colour = app.GetHTMLColour(rarityColour);
wchar_t formatted[256];
void RecordingItem::appendHoverText(std::shared_ptr<ItemInstance> itemInstance,
std::shared_ptr<Player> player,
std::vector<HtmlString>* lines,
bool advanced) {
eMinecraftColour color = getRarity(std::shared_ptr<ItemInstance>())->color;
swprintf(formatted, 256, L"<font color=\"#%08x\">%ls</font>", 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;
}
}

View file

@ -3,6 +3,9 @@
#include "Item.h"
class RecordingItem : public Item {
private:
static std::unordered_map<std::wstring, RecordingItem*> 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> itemInstance,
std::shared_ptr<Player> player, Level* level, int x,
@ -19,11 +21,9 @@ public
virtual void appendHoverText(std::shared_ptr<ItemInstance> itemInstance,
std::shared_ptr<Player> player,
std::vector<std::wstring>* lines,
bool advanced,
std::vector<std::wstring>& unformattedStrings);
std::vector<HtmlString>* lines, bool advanced);
virtual const Rarity* getRarity(std::shared_ptr<ItemInstance> itemInstance);
//@Override
void registerIcons(IconRegister* iconRegister);
static RecordingItem* getByName(const std::wstring& name);
};

View file

@ -22,7 +22,7 @@ bool RedStoneItem::useOn(std::shared_ptr<ItemInstance> 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> 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);
}
}

View file

@ -7,8 +7,9 @@
SaddleItem::SaddleItem(int id) : Item(id) { maxStackSize = 1; }
bool SaddleItem::interactEnemy(std::shared_ptr<ItemInstance> itemInstance,
std::shared_ptr<Mob> mob) {
if (std::dynamic_pointer_cast<Pig>(mob)) {
std::shared_ptr<Player> player,
std::shared_ptr<LivingEntity> mob) {
if ((mob != NULL) && mob->instanceof(eTYPE_PIG)) {
std::shared_ptr<Pig> pig = std::dynamic_pointer_cast<Pig>(mob);
if (!pig->hasSaddle() && !pig->isBaby()) {
pig->setSaddle(true);
@ -20,8 +21,8 @@ bool SaddleItem::interactEnemy(std::shared_ptr<ItemInstance> itemInstance,
}
bool SaddleItem::hurtEnemy(std::shared_ptr<ItemInstance> itemInstance,
std::shared_ptr<Mob> mob,
std::shared_ptr<Mob> attacker) {
interactEnemy(itemInstance, mob);
std::shared_ptr<LivingEntity> mob,
std::shared_ptr<LivingEntity> attacker) {
interactEnemy(itemInstance, nullptr, mob);
return true;
}

View file

@ -7,8 +7,9 @@ public:
SaddleItem(int id);
virtual bool interactEnemy(std::shared_ptr<ItemInstance> itemInstance,
std::shared_ptr<Mob> mob);
std::shared_ptr<Player> player,
std::shared_ptr<LivingEntity> mob);
virtual bool hurtEnemy(std::shared_ptr<ItemInstance> itemInstance,
std::shared_ptr<Mob> mob,
std::shared_ptr<Mob> attacker);
std::shared_ptr<LivingEntity> mob,
std::shared_ptr<LivingEntity> attacker);
};

View file

@ -17,13 +17,14 @@ bool SeedFoodItem::useOn(std::shared_ptr<ItemInstance> 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;

View file

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

View file

@ -10,11 +10,11 @@ ShearsItem::ShearsItem(int itemId) : Item(itemId) {
bool ShearsItem::mineBlock(std::shared_ptr<ItemInstance> itemInstance,
Level* level, int tile, int x, int y, int z,
std::shared_ptr<Mob> owner) {
std::shared_ptr<LivingEntity> 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> 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);

View file

@ -7,7 +7,7 @@ public:
ShearsItem(int itemId);
virtual bool mineBlock(std::shared_ptr<ItemInstance> itemInstance,
Level* level, int tile, int x, int y, int z,
std::shared_ptr<Mob> owner);
std::shared_ptr<LivingEntity> owner);
virtual bool canDestroySpecial(Tile* tile);
virtual float getDestroySpeed(std::shared_ptr<ItemInstance> itemInstance,
Tile* tile);

View file

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

View file

@ -26,16 +26,22 @@ bool SignItem::useOn(std::shared_ptr<ItemInstance> 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--;

View file

@ -0,0 +1,9 @@
#include "../Platform/stdafx.h"
#include "SimpleFoiledItem.h"
SimpleFoiledItem::SimpleFoiledItem(int id) : Item(id) {}
bool SimpleFoiledItem::isFoil(std::shared_ptr<ItemInstance> itemInstance) {
return true;
}

View file

@ -0,0 +1,10 @@
#pragma once
#include "Item.h"
class SimpleFoiledItem : public Item {
public:
SimpleFoiledItem(int id);
bool isFoil(std::shared_ptr<ItemInstance> itemInstance);
};

View file

@ -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<ItemInstance> instance,
std::shared_ptr<Player> 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);
}

View file

@ -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<ItemInstance> instance,
std::shared_ptr<Player> player, Level* level, int x, int y,
int z, int face, float clickX, float clickY, float clickZ,
bool bTestUseOnOnly = false);
};

View file

@ -14,8 +14,9 @@ std::shared_ptr<ItemInstance> SnowballItem::use(
if (!player->abilities.instabuild) {
instance->count--;
}
level->playSound((std::shared_ptr<Entity>)player, eSoundType_RANDOM_BOW,
0.5f, 0.4f / (random->nextFloat() * 0.4f + 0.8f));
level->playEntitySound((std::shared_ptr<Entity>)player,
eSoundType_RANDOM_BOW, 0.5f,
0.4f / (random->nextFloat() * 0.4f + 0.8f));
if (!level->isClientSide)
level->addEntity(
std::shared_ptr<Snowball>(new Snowball(level, player)));

View file

@ -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> itemInstance) {
std::wstring elementName = getDescription();
@ -33,8 +34,8 @@ std::wstring MonsterPlacerItem::getHoverName(
return elementName;
}
int MonsterPlacerItem::getColor(std::shared_ptr<ItemInstance> item,
int spriteLayer) {
int SpawnEggItem::getColor(std::shared_ptr<ItemInstance> 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<ItemInstance> 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<Entity> MonsterPlacerItem::canSpawn(int iAuxVal, Level* level,
int* piResult) {
std::shared_ptr<Entity> SpawnEggItem::canSpawn(int iAuxVal, Level* level,
int* piResult) {
std::shared_ptr<Entity> newEntity = EntityIO::newById(iAuxVal, level);
if (newEntity != NULL) {
bool canSpawn = false;
@ -103,9 +104,16 @@ std::shared_ptr<Entity> 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<Entity> 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<Entity> 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<Entity> MonsterPlacerItem::canSpawn(int iAuxVal, Level* level,
return nullptr;
}
bool MonsterPlacerItem::useOn(std::shared_ptr<ItemInstance> itemInstance,
std::shared_ptr<Player> 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> itemInstance,
std::shared_ptr<Player> 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> 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<MobSpawnerTileEntity> mste =
std::dynamic_pointer_cast<MobSpawnerTileEntity>(
level->getTileEntity(x, y, z));
@ -169,63 +185,95 @@ bool MonsterPlacerItem::useOn(std::shared_ptr<ItemInstance> 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<Entity> 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<Mob>(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<Entity> MonsterPlacerItem::spawnMobAt(Level* level, int mobId,
double x, double y,
double z, int* piResult) {
std::shared_ptr<ItemInstance> SpawnEggItem::use(
std::shared_ptr<ItemInstance> itemInstance, Level* level,
std::shared_ptr<Player> 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<Entity> 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<Mob>(result)->setCustomName(
itemInstance->getHoverName());
}
if (!player->abilities.instabuild) {
itemInstance->count--;
}
} else {
SpawnEggItem::DisplaySpawnError(player, iResult);
}
}
}
return itemInstance;
}
std::shared_ptr<Entity> 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<Entity> MonsterPlacerItem::spawnMobAt(Level* level, int mobId,
for (int i = 0; i < SPAWN_COUNT; i++) {
newEntity = canSpawn(mobId, level, piResult);
std::shared_ptr<Mob> mob = std::dynamic_pointer_cast<Mob>(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> mob =
std::dynamic_pointer_cast<Mob>(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<Entity> 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<Entity> 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> 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;
}
}

View file

@ -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> itemInstance);
@ -33,6 +34,10 @@ public:
std::shared_ptr<Player> player, Level* level, int x,
int y, int z, int face, float clickX, float clickY,
float clickZ, bool bTestUseOnOnly = false);
virtual std::shared_ptr<ItemInstance> use(
std::shared_ptr<ItemInstance> itemInstance, Level* level,
std::shared_ptr<Player> player);
static std::shared_ptr<Entity> 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<Entity> canSpawn(int iAuxVal, Level* level,
int* piResult);
// 4J: Added for neatness
static void DisplaySpawnError(std::shared_ptr<Player> player, int result);
//@Override
void registerIcons(IconRegister* iconRegister);
};

View file

@ -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<ItemInstance> instance) {
if (getTileId() == Tile::woolCarpet_Id)
return CARPET_COLOR_DESCS[ClothTile::getTileDataForItemAuxValue(
instance->getAuxValue())];
else
return COLOR_DESCS[ClothTile::getTileDataForItemAuxValue(
instance->getAuxValue())];
}

View file

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

View file

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

View file

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

View file

@ -20,7 +20,8 @@ bool TilePlanterItem::useOn(std::shared_ptr<ItemInstance> 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<ItemInstance> 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<ItemInstance> 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

View file

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

View file

@ -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<ItemInstance> instance) {
int auxValue = instance->getAuxValue();
if (auxValue < 0 ||
auxValue >= SmoothStoneBrickTile::SMOOTH_STONE_BRICK_NAMES_LENGTH) {
auxValue = 0;
}
return SmoothStoneBrickTile::SMOOTH_STONE_BRICK_NAMES[auxValue];
}

View file

@ -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<ItemInstance> instance);
};

View file

@ -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<ItemInstance> instance) {
int auxValue = instance->getAuxValue();
if (auxValue < 0 ||
auxValue >= StoneMonsterTile::STONE_MONSTER_NAMES_LENGTH) {
auxValue = 0;
}
return StoneMonsterTile::STONE_MONSTER_NAMES[auxValue];
}

View file

@ -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<ItemInstance> instance);
};

View file

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

View file

@ -43,7 +43,8 @@ bool TileItem::useOn(std::shared_ptr<ItemInstance> 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<ItemInstance> 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<ItemInstance> 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<ItemInstance> 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

View file

@ -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<ItemInstance> instance) {
int auxValue = instance->getAuxValue();
if (auxValue < 0 || auxValue >= TreeTile::TREE_NAMES_LENGTH) {
auxValue = 0;
}
return TreeTile::TREE_NAMES[auxValue];
}

View file

@ -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<ItemInstance> instance);
};

View file

@ -8,7 +8,8 @@
WaterLilyTileItem::WaterLilyTileItem(int id) : ColoredTileItem(id, false) {}
bool WaterLilyTileItem::TestUse(Level* level, std::shared_ptr<Player> player) {
bool WaterLilyTileItem::TestUse(std::shared_ptr<ItemInstance> itemInstance,
Level* level, std::shared_ptr<Player> 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> 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<ItemInstance> 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--;
}

View file

@ -10,6 +10,7 @@ public:
virtual std::shared_ptr<ItemInstance> use(
std::shared_ptr<ItemInstance> itemInstance, Level* level,
std::shared_ptr<Player> player);
virtual bool TestUse(Level* level, std::shared_ptr<Player> player);
virtual bool TestUse(std::shared_ptr<ItemInstance> itemInstance,
Level* level, std::shared_ptr<Player> player);
virtual int getColor(int data, int spriteLayer);
};

View file

@ -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<ItemInstance> 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())];
};
}

View file

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

View file

@ -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> 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> itemInstance,
std::shared_ptr<Mob> mob,
std::shared_ptr<Mob> attacker) {
itemInstance->hurt(1, attacker);
std::shared_ptr<LivingEntity> mob,
std::shared_ptr<LivingEntity> attacker) {
itemInstance->hurtAndBreak(1, attacker);
return true;
}
bool WeaponItem::mineBlock(std::shared_ptr<ItemInstance> itemInstance,
Level* level, int tile, int x, int y, int z,
std::shared_ptr<Mob> owner) {
std::shared_ptr<LivingEntity> 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> entity) {
return damage;
}
bool WeaponItem::isHandEquipped() { return true; }
UseAnim WeaponItem::getUseAnimation(
@ -73,4 +82,15 @@ bool WeaponItem::isValidRepairItem(std::shared_ptr<ItemInstance> 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;
}

View file

@ -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> itemInstance,
Tile* tile);
virtual bool hurtEnemy(std::shared_ptr<ItemInstance> itemInstance,
std::shared_ptr<Mob> mob,
std::shared_ptr<Mob> attacker);
std::shared_ptr<LivingEntity> mob,
std::shared_ptr<LivingEntity> attacker);
virtual bool mineBlock(std::shared_ptr<ItemInstance> itemInstance,
Level* level, int tile, int x, int y, int z,
std::shared_ptr<Mob> owner);
virtual int getAttackDamage(std::shared_ptr<Entity> entity);
std::shared_ptr<LivingEntity> owner);
virtual bool isHandEquipped();
virtual UseAnim getUseAnimation(std::shared_ptr<ItemInstance> itemInstance);
virtual int getUseDuration(std::shared_ptr<ItemInstance> itemInstance);
@ -31,4 +30,5 @@ public:
const Tier* getTier();
bool isValidRepairItem(std::shared_ptr<ItemInstance> source,
std::shared_ptr<ItemInstance> repairItem);
attrAttrModMap* getDefaultAttributeModifiers();
};

View file

@ -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<String> 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;
}
};
*/