the whole game

This commit is contained in:
Kolyah35
2026-03-02 22:04:18 +03:00
parent 816e9060b4
commit f0617a5d22
2069 changed files with 581500 additions and 0 deletions

77
src/world/item/ArmorItem.cpp Executable file
View File

@@ -0,0 +1,77 @@
#include "ArmorItem.h"
//
// ArmorMaterial
//
ArmorItem::ArmorMaterial::ArmorMaterial( int durabilityMultiplier, int p0, int p1, int p2, int p3 )
: durabilityMultiplier(durabilityMultiplier)
{
slotProtections[0] = p0;
slotProtections[1] = p1;
slotProtections[2] = p2;
slotProtections[3] = p3;
//this->enchantmentValue = enchantmentValue;
}
int ArmorItem::ArmorMaterial::getHealthForSlot( int slot ) const {
return healthPerSlot[slot] * durabilityMultiplier;
}
int ArmorItem::ArmorMaterial::getDefenseForSlot( int slot ) const {
return slotProtections[slot];
}
//
// ArmorItem
//
const int ArmorItem::healthPerSlot[4] = {
11, 16, 15, 13
};
ArmorItem::ArmorItem( int id, const ArmorMaterial& armorType, int icon, int slot ) : super(id),
armorType(armorType),
slot(slot),
modelIndex(icon),
defense(armorType.getDefenseForSlot(slot))
{
setMaxDamage(armorType.getHealthForSlot(slot));
maxStackSize = 1;
}
bool ArmorItem::isArmor() const {
return true;
}
//
// Singleton ArmorMaterials
//
const ArmorItem::ArmorMaterial ArmorItem::CLOTH(
5, // durability
1, 3, 2, 1 // protection values
//15, // enchantment
);
const ArmorItem::ArmorMaterial ArmorItem::CHAIN(
15,
2, 5, 4, 1
//12,
);
const ArmorItem::ArmorMaterial ArmorItem::IRON(
15,
2, 6, 5, 2
//9
);
const ArmorItem::ArmorMaterial ArmorItem::GOLD(
7,
2, 5, 3, 1
//25
);
const ArmorItem::ArmorMaterial ArmorItem::DIAMOND(
33,
3, 8, 6, 3
//10
);

58
src/world/item/ArmorItem.h Executable file
View File

@@ -0,0 +1,58 @@
#ifndef NET_MINECRAFT_WORLD_ITEM__ArmorItem_H__
#define NET_MINECRAFT_WORLD_ITEM__ArmorItem_H__
//package net.minecraft.world.item;
#include "Item.h"
class ArmorItem: public Item
{
typedef Item super;
public:
static const int SLOT_HEAD = 0;
static const int SLOT_TORSO = 1;
static const int SLOT_LEGS = 2;
static const int SLOT_FEET = 3;
static const int healthPerSlot[4];
class ArmorMaterial
{
public:
/// p0-p3 are slot protection values
ArmorMaterial(int durabilityMultiplier, int p0, int p1, int p2, int p3);//, int enchantmentValue);
int getHealthForSlot(int slot) const;
int getDefenseForSlot(int slot) const;
/* int getEnchantmentValue() const {
return enchantmentValue;
} */
private:
int durabilityMultiplier;
int slotProtections[4];
//int enchantmentValue;
};
static const ArmorMaterial CLOTH;
static const ArmorMaterial CHAIN;
static const ArmorMaterial IRON;
static const ArmorMaterial GOLD;
static const ArmorMaterial DIAMOND;
const int slot;
const int defense;
const int modelIndex;
const ArmorMaterial& armorType;
ArmorItem(int id, const ArmorMaterial& armorType, int icon, int slot);
bool isArmor() const;
/*
int getEnchantmentValue() const {
return armorType.getEnchantmentValue();
}
*/
};
#endif /*NET_MINECRAFT_WORLD_ITEM__ArmorItem_H__*/

View File

@@ -0,0 +1,34 @@
#ifndef NET_MINECRAFT_WORLD_ITEM__AuxDataTileItem_H__
#define NET_MINECRAFT_WORLD_ITEM__AuxDataTileItem_H__
//package net.minecraft.world.item;
#include "TileItem.h"
#include "../level/tile/Tile.h"
class AuxDataTileItem: public TileItem
{
typedef TileItem super;
public:
AuxDataTileItem(int id, Tile* parentTile)
: super(id),
parentTile(parentTile)
{
setMaxDamage(0);
setStackedByData(true);
}
/*@Override*/
int getIcon(int itemAuxValue) {
return parentTile->getTexture(2, itemAuxValue);
}
/*@Override*/
int getLevelDataForAuxValue(int auxValue) {
return auxValue;
}
private:
Tile* parentTile;
};
#endif /*NET_MINECRAFT_WORLD_ITEM__AuxDataTileItem_H__*/

36
src/world/item/BedItem.cpp Executable file
View File

@@ -0,0 +1,36 @@
#include "BedItem.h"
#include "../level/Level.h"
#include "../level/tile/BedTile.h"
#include "../entity/player/Player.h"
#include "../Direction.h"
#include "../Facing.h"
bool BedItem::useOn( ItemInstance* itemInstance, Player* player, Level* level, int x, int y, int z, int face, float clickX, float clickY, float clickZ ) {
if(face != Facing::UP) {
return false;
}
y += 1;
BedTile *tile = (BedTile*) Tile::bed;
int dir = (Mth::floor(player->yRot * 4 / (360) + 0.5f)) & 3;
int xra = 0;
int zra = 0;
if (dir == Direction::SOUTH) zra = 1;
if (dir == Direction::WEST) xra = -1;
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)) return false;
if (level->isEmptyTile(x, y, z) && level->isEmptyTile(x + xra, y, z + zra) && level->isSolidBlockingTile(x, y - 1, z) && level->isSolidBlockingTile(x + xra, y - 1, z + zra)) {
level->setTileAndData(x, y, z, tile->id, dir);
// double-check that the bed was successfully placed
if (level->getTile(x, y, z) == tile->id) {
level->setTileAndData(x + xra, y, z + zra, tile->id, dir + BedTile::HEAD_PIECE_DATA);
}
itemInstance->count--;
return true;
}
return false;
}

14
src/world/item/BedItem.h Executable file
View File

@@ -0,0 +1,14 @@
#ifndef NET_MINECRAFT_WORLD_ITEM__BedItem_H__
#define NET_MINECRAFT_WORLD_ITEM__BedItem_H__
#include "Item.h"
class Player;
class ItemInstance;
class Level;
class BedItem : public Item{
typedef Item super;
public:
BedItem(int id) : super(id) {}
bool useOn(ItemInstance* itemInstance, Player* player, Level* level, int x, int y, int z, int face, float clickX, float clickY, float clickZ);
};
#endif /* NET_MINECRAFT_WORLD_ITEM__BedItem_H__ */

64
src/world/item/BowItem.h Executable file
View File

@@ -0,0 +1,64 @@
#ifndef NET_MINECRAFT_WORLD_ITEM__BowItem_H__
#define NET_MINECRAFT_WORLD_ITEM__BowItem_H__
//package net.minecraft.world.item;
#include "Item.h"
#include "../entity/player/Player.h"
#include "../entity/projectile/Arrow.h"
#include "../level/Level.h"
#include "../entity/player/Inventory.h"
class BowItem: public Item
{
typedef Item super;
public:
static const int MAX_DRAW_DURATION = 20 * 1;
BowItem(int id)
: super(id)
{
maxStackSize = 1;
this->setMaxDamage(384);
}
void releaseUsing( ItemInstance* itemInstance, Level* level, Player* player, int durationLeft ) {
int timeHeld = getUseDuration(itemInstance) - durationLeft;
float pow = timeHeld / (float) MAX_DRAW_DURATION;
pow = ((pow * pow) + pow * 2) / 3;
if (pow < 0.1) return;
if (pow > 1) pow = 1;
itemInstance->hurt(1);
level->playSound(player, "random.bow", 1.0f, 1.0f / (random.nextFloat() * 0.4f + 1.2f) + pow * 0.5f);
player->inventory->removeResource(Item::arrow->id);
if (!level->isClientSide) {
Arrow* arrow = new Arrow(level, player, pow * 2.0f);
if (pow == 1)
arrow->critArrow = true;
level->addEntity(arrow);
}
}
int getUseDuration(ItemInstance* itemInstance) {
return 20 * 60 * 60;
}
ItemInstance* use(ItemInstance* instance, Level* level, Player* player) {
if(player->abilities.instabuild || player->hasResource(Item::arrow->id)) {
player->startUsingItem(*instance, getUseDuration(instance));
}
return instance;
}
UseAnim::UseAnimation getUseAnimation() {return UseAnim::bow;}
// /*public*/ ItemInstance use(ItemInstance instance, Level* level, Player* player) {
// level->playSound(player, "random.bow", 1.0f, 1 / (random.nextFloat() * 0.4f + 0.8f));
// if (!level->isOnline) level->addEntity(/*new*/ Arrow(level, player));
// }
// return instance;
// }
};
#endif /*NET_MINECRAFT_WORLD_ITEM__BowItem_H__*/

25
src/world/item/BowlFoodItem.h Executable file
View File

@@ -0,0 +1,25 @@
#ifndef NET_MINECRAFT_WORLD_ITEM__BowlFoodItem_H__
#define NET_MINECRAFT_WORLD_ITEM__BowlFoodItem_H__
//package net.minecraft.world.item;
#include "FoodItem.h"
class BowlFoodItem: public FoodItem
{
typedef FoodItem super;
public:
BowlFoodItem(int id, int nutrition)
: super(id, nutrition, false)
{
setMaxStackSize(1);
}
ItemInstance useTimeDepleted(ItemInstance* instance, Level* level, Player* player) {
super::useTimeDepleted(instance, level, player);
*instance = ItemInstance(Item::bowl);
return *instance;
}
};
#endif /*NET_MINECRAFT_WORLD_ITEM__BowlFoodItem_H__*/

26
src/world/item/CameraItem.h Executable file
View File

@@ -0,0 +1,26 @@
#ifndef NET_MINECRAFT_WORLD_ITEM__CameraItem_H__
#define NET_MINECRAFT_WORLD_ITEM__CameraItem_H__
#include "Item.h"
#include "ItemInstance.h"
#include "../level/Level.h"
#include "../entity/player/Player.h"
#include "../entity/item/TripodCamera.h"
class CameraItem: public Item
{
typedef Item super;
public:
CameraItem(int id)
: super(id)
{
}
ItemInstance* use(ItemInstance* itemInstance, Level* level, Player* player) {
level->addEntity( new TripodCamera(level, player, player->x, player->y, player->z) );
return itemInstance;
}
};
#endif /*NET_MINECRAFT_WORLD_ITEM__CameraItem_H__*/

37
src/world/item/ClothTileItem.h Executable file
View File

@@ -0,0 +1,37 @@
#ifndef NET_MINECRAFT_WORLD_ITEM__ClothTileItem_H__
#define NET_MINECRAFT_WORLD_ITEM__ClothTileItem_H__
//package net.minecraft.world.item;
#include "TileItem.h"
#include "DyePowderItem.h"
#include "../level/tile/ClothTile.h"
class ClothTileItem: public TileItem
{
typedef TileItem super;
public:
ClothTileItem(int id)
: super(id)
{
setMaxDamage(0);
setStackedByData(true);
}
/*@Override*/
int getIcon(int itemAuxValue) {
return Tile::cloth->getTexture(2, ClothTile::getTileDataForItemAuxValue(itemAuxValue));
}
/*@Override*/
int getLevelDataForAuxValue(int auxValue) {
return auxValue;
}
/*@Override*/
std::string getDescriptionId(const ItemInstance* instance) const {
return super::getDescriptionId() + "." + DyePowderItem::COLOR_DESCS[ClothTile::getTileDataForItemAuxValue(instance->getAuxValue())];
}
};
#endif /*NET_MINECRAFT_WORLD_ITEM__ClothTileItem_H__*/

29
src/world/item/CoalItem.h Executable file
View File

@@ -0,0 +1,29 @@
#ifndef NET_MINECRAFT_WORLD_ITEM__CoalItem_H__
#define NET_MINECRAFT_WORLD_ITEM__CoalItem_H__
//package net.minecraft.world.item;
class CoalItem: public Item
{
typedef Item super;
public:
static const int STONE_COAL = 0;
static const int CHAR_COAL = 1;
CoalItem(int id)
: super(id)
{
setStackedByData(true);
setMaxDamage(0);
}
/*@Override*/
std::string getDescriptionId(ItemInstance* instance) {
if (instance->getAuxValue() == CHAR_COAL) {
return ICON_DESCRIPTION_PREFIX + "charcoal";
}
return ICON_DESCRIPTION_PREFIX + "coal";
}
};
#endif /*NET_MINECRAFT_WORLD_ITEM__CoalItem_H__*/

85
src/world/item/DiggerItem.h Executable file
View File

@@ -0,0 +1,85 @@
#ifndef NET_MINECRAFT_WORLD_ITEM__DiggerItem_H__
#define NET_MINECRAFT_WORLD_ITEM__DiggerItem_H__
//package net.minecraft.world.item;
#include "../level/tile/Tile.h"
#include "Item.h"
#include "ItemInstance.h"
class DiggerItem: public Item
{
typedef Item super;
protected:
typedef std::vector<Tile*> TileList;
public:
float getDestroySpeed(ItemInstance* itemInstance, Tile* tile) {
if (hasTile(tile))
return speed;
return 1;
}
//@Override
void hurtEnemy(ItemInstance* itemInstance, Mob* mob/*, Mob* attacker*/) {
itemInstance->hurt(2);//, attacker); //@todo
//return true;
}
//@Override
bool mineBlock(ItemInstance* itemInstance, int tile, int x, int y, int z/*, Mob* owner*/) {
itemInstance->hurt(1);//, owner);
return true;
}
int getAttackDamage(Entity* entity) {
return attackDamage;
}
bool isHandEquipped() const {
return true;
}
void setTiles(const TileList& tiles) {
for (int i = 0; i < 256; ++i) {
_bTiles[i] = false;
}
for (unsigned int i = 0; i < tiles.size(); ++i) {
_bTiles[tiles[i]->id] = true;
}
this->tiles = tiles;
}
//@Override
//int getEnchantmentValue() {
// return tier.getEnchantmentValue();
//}
protected:
float speed;
const Tier& tier;
DiggerItem(int id, int attackDamage, const Tier& tier, const TileList& tiles = TileList())
: super(id),
speed(tier.getSpeed()),
tier(tier)
{
setTiles(tiles);
maxStackSize = 1;
setMaxDamage(tier.getUses());
this->attackDamage = attackDamage + tier.getAttackDamageBonus();
}
bool hasTile(Tile* tile) {
return tile && _bTiles[tile->id];
}
private:
int attackDamage;
TileList tiles;
bool _bTiles[256];
};
#endif /*NET_MINECRAFT_WORLD_ITEM__DiggerItem_H__*/

73
src/world/item/DoorItem.h Executable file
View File

@@ -0,0 +1,73 @@
#ifndef NET_MINECRAFT_WORLD_ITEM__DoorItem_H__
#define NET_MINECRAFT_WORLD_ITEM__DoorItem_H__
//package net.minecraft.world.item;
#include "Item.h"
#include "ItemInstance.h"
#include "../Facing.h"
#include "../entity/player/Player.h"
#include "../level/Level.h"
#include "../level/material/Material.h"
#include "../level/tile/Tile.h"
#include "../../util/Mth.h"
class DoorItem: public Item
{
typedef Item super;
const Material* material;
public:
DoorItem(int id, const Material* material)
: super(id),
material(material)
{
maxDamage = 64;
maxStackSize = 1;
}
bool useOn(ItemInstance* instance, Player* player, Level* level, int x, int y, int z, int face, float clickX, float clickY, float clickZ) {
if (face != Facing::UP) return false;
y++;
Tile* tile;
if (material == Material::wood) tile = Tile::door_wood;
else tile = Tile::door_iron;
//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;
int dir = Mth::floor(((player->yRot + 180) * 4) / 360 - 0.5f) & 3;
place(level, x, y, z, dir, tile);
instance->count--;
return true;
}
static void place(Level* level, int x, int y, int z, int dir, Tile* tile) {
int xra = 0;
int zra = 0;
if (dir == 0) zra = +1;
if (dir == 1) xra = -1;
if (dir == 2) zra = -1;
if (dir == 3) xra = +1;
int solidLeft = (level->isSolidBlockingTile(x - xra, y, z - zra) ? 1 : 0) + (level->isSolidBlockingTile(x - xra, y + 1, z - zra) ? 1 : 0);
int solidRight = (level->isSolidBlockingTile(x + xra, y, z + zra) ? 1 : 0) + (level->isSolidBlockingTile(x + xra, y + 1, z + zra) ? 1 : 0);
bool doorLeft = (level->getTile(x - xra, y, z - zra) == tile->id) || (level->getTile(x - xra, y + 1, z - zra) == tile->id);
bool doorRight = (level->getTile(x + xra, y, z + zra) == tile->id) || (level->getTile(x + xra, y + 1, z + zra) == tile->id);
bool flip = false;
if (doorLeft && !doorRight) flip = true;
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->updateNeighborsAt(x, y, z, tile->id);
level->updateNeighborsAt(x, y + 1, z, tile->id);
}
};
#endif /*NET_MINECRAFT_WORLD_ITEM__DoorItem_H__*/

122
src/world/item/DyePowderItem.cpp Executable file
View File

@@ -0,0 +1,122 @@
#include "DyePowderItem.h"
#include "../entity/Mob.h"
#include "../entity/animal/Sheep.h"
#include "../entity/player/Player.h"
#include "../level/Level.h"
#include "../level/tile/Tile.h"
#include "../level/tile/Sapling.h"
#include "../level/tile/GrassTile.h"
#include "../../util/Mth.h"
#include "../level/tile/ClothTile.h"
#include "../level/tile/CropTile.h"
#include "../level/tile/StemTile.h"
const std::string DyePowderItem::COLOR_DESCS[] = {
"black", "red", "green", "brown", "blue", "purple", "cyan", "silver", "gray", "pink", "lime", "yellow", "lightBlue", "magenta", "orange", "white"
};
const int DyePowderItem::COLOR_RGB[] = {
0x1e1b1b, 0xb3312c, 0x3b511a, 0x51301a, 0x253192, 0x7b2fbe, 0x287697, 0x287697, 0x434343, 0xd88198, 0x41cd34, 0xdecf2a, 0x6689d3, 0xc354cd, 0xeb8844, 0xf0f0f0
};
DyePowderItem::DyePowderItem( int id )
: super(id)
{
setStackedByData(true);
setMaxDamage(0);
}
int DyePowderItem::getIcon( int itemAuxValue )
{
int colorValue = Mth::clamp(itemAuxValue, 0, 15);
return icon + (colorValue % 8) * ICON_COLUMNS + (colorValue / 8);
}
std::string DyePowderItem::getDescriptionId( const ItemInstance* itemInstance ) const
{
int colorValue = Mth::clamp(itemInstance->getAuxValue(), 0, 15);
return super::getDescriptionId() + "." + COLOR_DESCS[colorValue];
}
bool DyePowderItem::useOn( ItemInstance* itemInstance, Player* player, Level* level, int x, int y, int z, int face, float clickX, float clickY, float clickZ )
{
//if (!player->mayBuild(x, y, z)) return false;
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 (!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 (!level->isOnline) {
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->isClientSide) {
((StemTile*) Tile::tiles[tile])->growCropsToMax(level, x, y, z);
}
itemInstance->count--;
return true;
} else if (tile == Tile::crops->id) {
if (!level->isClientSide) {
((CropTile*) Tile::crops)->growCropsToMax(level, x, y, z);
}
itemInstance->count--;
} else if (tile == Tile::grass->id) {
if (!level->isClientSide) {
for (int j = 0; j < 32; j++) {
int xx = x;
int yy = y + 1;
int zz = z;
bool continueMainLoop = false;
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)) {
continueMainLoop = true;
break;
}
}
if(continueMainLoop)
continue;
if (level->getTile(xx, yy, zz) == 0) {
/*if (random.nextInt(10) != 0) {
level->setTileAndData(xx, yy, zz, Tile::tallgrass.id, TallGrass.TALL_GRASS);
} else*/ if (random.nextInt(3) != 0) {
level->setTile(xx, yy, zz, Tile::flower->id);
} else {
level->setTile(xx, yy, zz, Tile::rose->id);
}
}
}
}
itemInstance->count--;
return true;
}
}
return false;
}
void DyePowderItem::interactEnemy( ItemInstance* itemInstance, Mob* mob )
{
if (mob->getEntityTypeId() == MobTypes::Sheep) {
Sheep* sheep = (Sheep*) mob;
// convert to tile-based color value (0 is white instead of black)
int newColor = ClothTile::getTileDataForItemAuxValue(itemInstance->getAuxValue());
if (!sheep->isSheared() && sheep->getColor() != newColor) {
sheep->setColor(newColor);
itemInstance->count--;
}
}
}

53
src/world/item/DyePowderItem.h Executable file
View File

@@ -0,0 +1,53 @@
#ifndef NET_MINECRAFT_WORLD_ITEM__DyePowderItem_H__
#define NET_MINECRAFT_WORLD_ITEM__DyePowderItem_H__
//package net.minecraft.world.item;
#include "Item.h"
#include <string>
class ItemInstance;
class Level;
class Mob;
class Player;
class DyePowderItem: public Item
{
typedef Item super;
public:
static const std::string COLOR_DESCS[];
static const int COLOR_RGB[];
static const int BLACK = 0;
static const int RED = 1;
static const int GREEN = 2;
static const int BROWN = 3;
static const int BLUE = 4;
static const int PURPLE = 5;
static const int CYAN = 6;
static const int SILVER = 7;
static const int GRAY = 8;
static const int PINK = 9;
static const int LIME = 10;
static const int YELLOW = 11;
static const int LIGHT_BLUE = 12;
static const int MAGENTA = 13;
static const int ORANGE = 14;
static const int WHITE = 15;
DyePowderItem(int id);
///*@Override*/
int getIcon(int itemAuxValue);
///*@Override*/
std::string getDescriptionId(const ItemInstance* itemInstance) const;
///*@Override*/
bool useOn(ItemInstance* itemInstance, Player* player, Level* level, int x, int y, int z, int face, float clickX, float clickY, float clickZ);
///*@Override*/
void interactEnemy(ItemInstance* itemInstance, Mob* mob);
};
#endif /*NET_MINECRAFT_WORLD_ITEM__DyePowderItem_H__*/

32
src/world/item/EggItem.h Executable file
View File

@@ -0,0 +1,32 @@
#ifndef NET_MINECRAFT_WORLD_ITEM__EggItem_H__
#define NET_MINECRAFT_WORLD_ITEM__EggItem_H__
//package net.minecraft.world.item;
#include "Item.h"
#include "../entity/player/Player.h"
#include "../entity/projectile/ThrownEgg.h"
#include "../level/Level.h"
class EggItem: public Item
{
typedef Item super;
public:
EggItem(int id)
: super(id)
{
maxStackSize = 16;
}
ItemInstance* use(ItemInstance* instance, Level* level, Player* player) {
if (!player->abilities.instabuild)
instance->count--;
level->playSound(player, "random.bow", 0.5f, 0.4f / (random.nextFloat() * 0.4f + 0.8f));
if (!level->isClientSide) level->addEntity(new ThrownEgg(level, player));
return instance;
}
};
#endif /*NET_MINECRAFT_WORLD_ITEM__EggItem_H__*/

View File

@@ -0,0 +1,43 @@
#ifndef NET_MINECRAFT_WORLD_ITEM__FlintAndSteelItem_H__
#define NET_MINECRAFT_WORLD_ITEM__FlintAndSteelItem_H__
//package net.minecraft.world.item;
#include "Item.h"
#include "../level/Level.h"
#include "../level/tile/Tile.h"
#include "../entity/player/Player.h"
class FlintAndSteelItem: public Item
{
typedef Item super;
public:
FlintAndSteelItem(int id)
: super(id)
{
setMaxStackSize(1);
setMaxDamage(64);
}
/*
bool useOn(ItemInstance* instance, Player* player, Level* level, int x, int y, int z, int face, float clickX, float clickY, float clickZ) {
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->playSound(x + 0.5, y + 0.5, z + 0.5, "fire.ignite", 1, sharedRandom.nextFloat() * 0.4f + 0.8f);
level->setTile(x, y, z, Tile::fire->id);
}
instance->hurt(1);
return true;
}
*/
};
#endif /*NET_MINECRAFT_WORLD_ITEM__FlintAndSteelItem_H__*/

95
src/world/item/FoodItem.h Executable file
View File

@@ -0,0 +1,95 @@
#ifndef NET_MINECRAFT_WORLD_ITEM__FoodItem_H__
#define NET_MINECRAFT_WORLD_ITEM__FoodItem_H__
//package net.minecraft.world.item;
#include "Item.h"
#include "../level/Level.h"
#include "../entity/player/Player.h"
#include "../../SharedConstants.h"
#include "../../network/packet/SetHealthPacket.h"
//#include "../effect/MobEffectInstance.h"
//#include "../food/FoodConstants.h"
class FoodItem: public Item
{
typedef Item super;
static const int EAT_DURATION = (int) (20 * 1.6);
public:
FoodItem(int id, int nutrition, bool isMeat, float saturationMod = 0.6f)
: super(id),
nutrition(nutrition),
_isMeat(isMeat),
saturationModifier(saturationMod)
{
}
bool isFood() const {
return true;
}
ItemInstance useTimeDepleted(ItemInstance* instance, Level* level, Player* player) {
instance->count--;
player->foodData.eat(this);
level->playSound(player, "random.burp", 0.5f, level->random.nextFloat() * 0.1f + 0.9f);
return *instance;
}
int getUseDuration(ItemInstance* itemInstance) {
return EAT_DURATION;
}
UseAnim::UseAnimation getUseAnimation() {
return UseAnim::eat;
}
ItemInstance* use(ItemInstance* instance, Level* level, Player* player) {
if (!player->abilities.invulnerable && player->isHurt()) {
player->startUsingItem(*instance, getUseDuration(instance));
}
return instance;
}
int getNutrition() {
return nutrition;
}
/*
float getSaturationModifier() {
return saturationModifier;
}
*/
bool isMeat() {
return _isMeat;
}
/*
FoodItem* setEatEffect(int id, int durationInSecods, int amplifier, float effectProbability) {
effectId = id;
effectDurationSeconds = durationInSecods;
effectAmplifier = amplifier;
this->effectProbability = effectProbability;
return this;
}
*/
FoodItem* setCanAlwaysEat() {
canAlwaysEat = true;
return this;
}
private:
const int nutrition;
const float saturationModifier;
const bool _isMeat;
bool canAlwaysEat;
/*
int effectId;
int effectDurationSeconds;
int effectAmplifier;
float effectProbability;
*/
};
#endif /*NET_MINECRAFT_WORLD_ITEM__FoodItem_H__*/

View File

@@ -0,0 +1,43 @@
#include "HangingEntityItem.h"
#include "../entity/HangingEntity.h"
#include "../Facing.h"
#include "../Direction.h"
#include "../level/Level.h"
#include "../entity/EntityFactory.h"
#include "../entity/Painting.h"
HangingEntityItem::HangingEntityItem( int id, int type ) : super(id), entityType(type) {
}
bool HangingEntityItem::useOn( ItemInstance* itemInstance, Player* player, Level* level, int x, int y, int z, int face, float clickX, float clickY, float clickZ ) {
if (face == Facing::DOWN) return false;
if (face == Facing::UP) return false;
int dir = Direction::FACING_DIRECTION[face];
HangingEntity* entity = createEntity(level, x, y, z, dir);
//if (!player->mayUseItemAt(xt, yt, zt, face, instance)) return false;
if(entity != NULL) {
if (entity->survives()) {
if (!level->isClientSide) {
level->addEntity(entity);
}
else {
delete entity;
}
itemInstance->count--;
}
else {
delete entity;
}
}
return true;
}
HangingEntity* HangingEntityItem::createEntity( Level* level, int x, int y, int z, int dir ) {
switch(entityType) {
case EntityTypes::IdPainting: return new Painting(level, x, y, z, dir);
}
return NULL;
}

View File

@@ -0,0 +1,16 @@
#ifndef NET_MINECRAFT_WORLD_ITEM__HangingEntityItem_H__
#define NET_MINECRAFT_WORLD_ITEM__HangingEntityItem_H__
#include "Item.h"
class HangingEntity;
class HangingEntityItem : public Item {
typedef Item super;
public:
HangingEntityItem(int id, int type);
bool useOn(ItemInstance* itemInstance, Player* player, Level* level, int x, int y, int z, int face, float clickX, float clickY, float clickZ);
private:
HangingEntity* createEntity(Level* level, int x, int y, int z, int dir);
private:
int entityType;
};
#endif /* NET_MINECRAFT_WORLD_ITEM__HangingEntityItem_H__ */

27
src/world/item/HatchetItem.cpp Executable file
View File

@@ -0,0 +1,27 @@
#include "HatchetItem.h"
#include "../level/material/Material.h"
#include "../level/tile/Tile.h"
HatchetItem::HatchetItem( int id, const Tier& tier ) : super(id, 3, tier)
{
TileList d;
d.push_back(Tile::wood);
d.push_back(Tile::bookshelf);
d.push_back(Tile::treeTrunk);
d.push_back(Tile::chest);
d.push_back(Tile::stoneSlab);
d.push_back(Tile::stoneSlabHalf);
//d.push_back(Tile::pumpkin);
//d.push_back(Tile::litPumpkin);
setTiles(d);
}
float HatchetItem::getDestroySpeed( ItemInstance* itemInstance, Tile* tile )
{
if (tile != NULL && tile->material == Material::wood) {
return speed;
}
return super::getDestroySpeed(itemInstance, tile);
}

23
src/world/item/HatchetItem.h Executable file
View File

@@ -0,0 +1,23 @@
#ifndef NET_MINECRAFT_WORLD_ITEM__HatchetItem_H__
#define NET_MINECRAFT_WORLD_ITEM__HatchetItem_H__
//package net.minecraft.world.item;
#include "DiggerItem.h"
#include <vector>
class Tile;
class Tier;
class Material;
class HatchetItem: public DiggerItem
{
typedef DiggerItem super;
public:
HatchetItem(int id, const Tier& tier);
//@Override
float getDestroySpeed(ItemInstance* itemInstance, Tile* tile);
};
#endif /*NET_MINECRAFT_WORLD_ITEM__HatchetItem_H__*/

40
src/world/item/HoeItem.cpp Executable file
View File

@@ -0,0 +1,40 @@
#include "HoeItem.h"
#include "../level/tile/Tile.h"
#include "../level/Level.h"
#include "../entity/item/ItemEntity.h"
HoeItem::HoeItem( int id, Tier tier ) : super(id), tier(tier) {
maxStackSize = 1;
setMaxDamage(tier.getUses());
}
bool HoeItem::useOn( ItemInstance* itemInstance, Player* player, Level* level, int x, int y, int z, int face, float clickX, float clickY, float clickZ ) {
//if (!player.mayBuild(x, y, z)) return false;
int targetType = level->getTile(x, y, z);
int above = level->getTile(x, y + 1, z);
if (face != 0 && above == 0 && targetType == Tile::grass->id || targetType == Tile::dirt->id) {
Tile* tile = Tile::farmland;
level->playSound(x + 0.5f, y + 0.5f, z + 0.5f, tile->soundType->getStepSound(), (tile->soundType->getVolume() + 1) / 2, tile->soundType->getPitch() * 0.8f);
itemInstance->hurt(1/*, player*/);
if (level->isClientSide) return true;
level->setTile(x, y, z, tile->id);
if(targetType == Tile::grass->id && level->random.nextInt( 8 ) == 0) {
float s = 0.7f;
float xo = level->random.nextFloat() * s + (1 - s) * 0.5f;
float yo = level->random.nextFloat() * s + (1 - s) * 2.5f;
float zo = level->random.nextFloat() * s + (1 - s) * 0.5f;
ItemEntity* item = new ItemEntity(level, float(x) + xo, float(y) + yo, float(z) + zo, ItemInstance(Item::seeds_wheat));
item->throwTime = 10;
level->addEntity(item);
}
return true;
}
return false;
}
bool HoeItem::isHandEquipped() const {
return true;
}

17
src/world/item/HoeItem.h Executable file
View File

@@ -0,0 +1,17 @@
#ifndef NET_MINECRAFT_WORLD_ITEM__HoeItem_H__
#define NET_MINECRAFT_WORLD_ITEM__HoeItem_H__
#include "Item.h"
class HoeItem : public Item
{
typedef Item super;
public:
HoeItem(int id, Tier tier);
bool useOn(ItemInstance* itemInstance, Player* player, Level* level, int x, int y, int z, int face, float clickX, float clickY, float clickZ);
bool isHandEquipped() const;
protected:
Tier tier;
};
#endif /* NET_MINECRAFT_WORLD_ITEM__HoeItem_H__ */

308
src/world/item/Item.cpp Executable file
View File

@@ -0,0 +1,308 @@
#include "ItemInclude.h"
#include "ItemCategory.h"
#include "../level/tile/Tile.h"
#include "ItemInstance.h"
const std::string Item::ICON_DESCRIPTION_PREFIX("item.");
Random Item::random;
Item* Item::items[MAX_ITEMS] = {NULL};
Item::Tier const Item::Tier::WOOD(0, 59, 2, 0);
Item::Tier const Item::Tier::STONE(1, 131, 4, 1);
Item::Tier const Item::Tier::IRON(2, 250, 6, 2);
Item::Tier const Item::Tier::EMERALD(3, 1561, 8, 3);
Item::Tier const Item::Tier::GOLD(0, 32, 12, 0);
// Static Item Definitions
Item* Item::shovel_iron = NULL;
Item* Item::pickAxe_iron = NULL;
Item* Item::hatchet_iron = NULL;
Item* Item::flintAndSteel = NULL;
Item* Item::apple = NULL;
Item* Item::bow = NULL;
Item* Item::arrow = NULL;
Item* Item::coal = NULL;
Item* Item::emerald = NULL;
Item* Item::ironIngot = NULL;
Item* Item::goldIngot = NULL;
Item* Item::sword_iron = NULL;
Item* Item::sword_wood = NULL;
Item* Item::shovel_wood = NULL;
Item* Item::pickAxe_wood = NULL;
Item* Item::hatchet_wood = NULL;
Item* Item::sword_stone = NULL;
Item* Item::shovel_stone = NULL;
Item* Item::pickAxe_stone = NULL;
Item* Item::hatchet_stone = NULL;
Item* Item::sword_emerald = NULL;
Item* Item::shovel_emerald = NULL;
Item* Item::pickAxe_emerald = NULL;
Item* Item::hatchet_emerald = NULL;
Item* Item::stick = NULL;
Item* Item::bowl = NULL;
Item* Item::mushroomStew = NULL;
Item* Item::sword_gold = NULL;
Item* Item::shovel_gold = NULL;
Item* Item::pickAxe_gold = NULL;
Item* Item::hatchet_gold = NULL;
Item* Item::string = NULL;
Item* Item::feather = NULL;
Item* Item::sulphur = NULL;
Item* Item::hoe_wood = NULL;
Item* Item::hoe_stone = NULL;
Item* Item::hoe_iron = NULL;
Item* Item::hoe_emerald = NULL;
Item* Item::hoe_gold = NULL;
Item* Item::seeds_wheat = NULL;
Item* Item::wheat = NULL;
Item* Item::bread = NULL;
Item* Item::helmet_cloth = NULL;
Item* Item::chestplate_cloth = NULL;
Item* Item::leggings_cloth = NULL;
Item* Item::boots_cloth = NULL;
Item* Item::helmet_chain = NULL;
Item* Item::chestplate_chain = NULL;
Item* Item::leggings_chain = NULL;
Item* Item::boots_chain = NULL;
Item* Item::helmet_iron = NULL;
Item* Item::chestplate_iron = NULL;
Item* Item::leggings_iron = NULL;
Item* Item::boots_iron = NULL;
Item* Item::helmet_diamond = NULL;
Item* Item::chestplate_diamond = NULL;
Item* Item::leggings_diamond = NULL;
Item* Item::boots_diamond = NULL;
Item* Item::helmet_gold = NULL;
Item* Item::chestplate_gold = NULL;
Item* Item::leggings_gold = NULL;
Item* Item::boots_gold = NULL;
Item* Item::flint = NULL;
Item* Item::porkChop_raw = NULL;
Item* Item::porkChop_cooked = NULL;
Item* Item::painting = NULL;
//Item* Item::apple_gold = NULL;
Item* Item::sign = NULL;
Item* Item::door_wood = NULL;
//Item* Item::bucket_empty = NULL;
//Item* Item::bucket_water = NULL;
//Item* Item::bucket_lava = NULL;
//Item* Item::minecart = NULL;
//Item* Item::saddle = NULL;
Item* Item::door_iron = NULL;
//Item* Item::redStone = NULL;
Item* Item::snowBall = NULL;
//Item* Item::boat = NULL;
Item* Item::leather = NULL;
//Item* Item::milk = NULL;
Item* Item::brick = NULL;
Item* Item::clay = NULL;
Item* Item::reeds = NULL;
Item* Item::paper = NULL;
Item* Item::book = NULL;
Item* Item::slimeBall = NULL;
//Item* Item::minecart_chest = NULL;
//Item* Item::minecart_furnace = NULL;
Item* Item::egg = NULL;
Item* Item::compass = NULL;
//Item* Item::fishingRod = NULL;
Item* Item::clock = NULL;
Item* Item::yellowDust = NULL;
//Item* Item::fish_raw = NULL;
//Item* Item::fish_cooked = NULL;
Item* Item::melon = NULL;
Item* Item::seeds_melon = NULL;
Item* Item::dye_powder = NULL;
Item* Item::bone = NULL;
Item* Item::sugar = NULL;
//Item* Item::cake = NULL;
Item* Item::bed = NULL;
//Item* Item::diode = NULL;
ShearsItem* Item::shears = NULL;
Item* Item::beef_raw = NULL;
Item* Item::beef_cooked = NULL;
Item* Item::chicken_raw = NULL;
Item* Item::chicken_cooked = NULL;
Item* Item::netherbrick = NULL;
Item* Item::netherQuartz = NULL;
//Item* Item::record_01 = NULL;
//Item* Item::record_02 = NULL;
Item* Item::camera = NULL;
/*static*/
void Item::initItems() {
static bool isInited = false;
if (isInited)
return;
isInited = true;
Item::shovel_iron = (new ShovelItem(0, Tier::IRON))->setIcon(2, 5)->setCategory(ItemCategory::Tools)->setDescriptionId("shovelIron");
Item::pickAxe_iron = (new PickaxeItem(1, Tier::IRON))->setIcon(2, 6)->setCategory(ItemCategory::Tools)->setDescriptionId("pickaxeIron");
Item::hatchet_iron = (new HatchetItem(2, Tier::IRON))->setIcon(2, 7)->setCategory(ItemCategory::Tools)->setDescriptionId("hatchetIron");
Item::flintAndSteel = (new FlintAndSteelItem(3))->setIcon(5, 0)->setCategory(ItemCategory::Tools)->setDescriptionId("flintAndSteel");
Item::apple = (new FoodItem(4, 4, false))->setIcon(10, 0)->setCategory(ItemCategory::FoodArmor)->setDescriptionId("apple");
Item::bow = (new BowItem(5))->setIcon(5, 1)->setCategory(ItemCategory::Tools)->setDescriptionId("bow");
Item::arrow = (new Item(6))->setIcon(5, 2)->setCategory(ItemCategory::Tools)->setDescriptionId("arrow");
Item::coal = (new CoalItem(7))->setIcon(7, 0)->setCategory(ItemCategory::Tools)->setDescriptionId("coal");
Item::emerald = (new Item(8))->setIcon(7, 3)->setCategory(ItemCategory::Decorations)->setDescriptionId("emerald");
Item::ironIngot = (new Item(9))->setIcon(7, 1)->setCategory(ItemCategory::Decorations)->setDescriptionId("ingotIron");
Item::goldIngot = (new Item(10))->setIcon(7, 2)->setCategory(ItemCategory::Decorations)->setDescriptionId("ingotGold");
Item::sword_iron = (new WeaponItem(11, Tier::IRON))->setIcon(2, 4)->setCategory(ItemCategory::Tools)->setDescriptionId("swordIron");
Item::sword_wood = (new WeaponItem(12, Tier::WOOD))->setIcon(0, 4)->setCategory(ItemCategory::Tools)->setDescriptionId("swordWood");
Item::shovel_wood = (new ShovelItem(13, Tier::WOOD))->setIcon(0, 5)->setCategory(ItemCategory::Tools)->setDescriptionId("shovelWood");
Item::pickAxe_wood = (new PickaxeItem(14, Tier::WOOD))->setIcon(0, 6)->setCategory(ItemCategory::Tools)->setDescriptionId("pickaxeWood");
Item::hatchet_wood = (new HatchetItem(15, Tier::WOOD))->setIcon(0, 7)->setCategory(ItemCategory::Tools)->setDescriptionId("hatchetWood");
Item::sword_stone = (new WeaponItem(16, Tier::STONE))->setIcon(1, 4)->setCategory(ItemCategory::Tools)->setDescriptionId("swordStone");
Item::shovel_stone = (new ShovelItem(17, Tier::STONE))->setIcon(1, 5)->setCategory(ItemCategory::Tools)->setDescriptionId("shovelStone");
Item::pickAxe_stone = (new PickaxeItem(18, Tier::STONE))->setIcon(1, 6)->setCategory(ItemCategory::Tools)->setDescriptionId("pickaxeStone");
Item::hatchet_stone = (new HatchetItem(19, Tier::STONE))->setIcon(1, 7)->setCategory(ItemCategory::Tools)->setDescriptionId("hatchetStone");
Item::sword_emerald = (new WeaponItem(20, Tier::EMERALD))->setIcon(3, 4)->setCategory(ItemCategory::Tools)->setDescriptionId("swordDiamond");
Item::shovel_emerald = (new ShovelItem(21, Tier::EMERALD))->setIcon(3, 5)->setCategory(ItemCategory::Tools)->setDescriptionId("shovelDiamond");
Item::pickAxe_emerald = (new PickaxeItem(22, Tier::EMERALD))->setIcon(3, 6)->setCategory(ItemCategory::Tools)->setDescriptionId("pickaxeDiamond");
Item::hatchet_emerald = (new HatchetItem(23, Tier::EMERALD))->setIcon(3, 7)->setCategory(ItemCategory::Tools)->setDescriptionId("hatchetDiamond");
Item::stick = (new Item(24))->setIcon(5, 3)->handEquipped()->setCategory(ItemCategory::Structures)->setDescriptionId("stick");
Item::bowl = (new Item(25))->setIcon(7, 4)->setCategory(ItemCategory::FoodArmor)->setDescriptionId("bowl");
Item::mushroomStew = (new BowlFoodItem(26, 8))->setIcon(8, 4)->setCategory(ItemCategory::FoodArmor)->setDescriptionId("mushroomStew");
Item::sword_gold = (new WeaponItem(27, Tier::GOLD))->setIcon(4, 4)->setCategory(ItemCategory::Tools)->setDescriptionId("swordGold");
Item::shovel_gold = (new ShovelItem(28, Tier::GOLD))->setIcon(4, 5)->setCategory(ItemCategory::Tools)->setDescriptionId("shovelGold");
Item::pickAxe_gold = (new PickaxeItem(29, Tier::GOLD))->setIcon(4, 6)->setCategory(ItemCategory::Tools)->setDescriptionId("pickaxeGold");
Item::hatchet_gold = (new HatchetItem(30, Tier::GOLD))->setIcon(4, 7)->setCategory(ItemCategory::Tools)->setDescriptionId("hatchetGold");
Item::string = (new Item(31))->setIcon(8, 0)->setCategory(ItemCategory::Tools)->setDescriptionId("string");
Item::feather = (new Item(32))->setIcon(8, 1)->setCategory(ItemCategory::Tools)->setDescriptionId("feather");
Item::sulphur = (new Item(33))->setIcon(8, 2)->setCategory(ItemCategory::Tools)->setDescriptionId("sulphur");
Item::hoe_wood = (new HoeItem(34, Tier::WOOD))->setIcon(0, 8)->setCategory(ItemCategory::Tools)->setDescriptionId("hoeWood");
Item::hoe_stone = (new HoeItem(35, Tier::STONE))->setIcon(1, 8)->setCategory(ItemCategory::Tools)->setDescriptionId("hoeStone");
Item::hoe_iron = (new HoeItem(36, Tier::IRON))->setIcon(2, 8)->setCategory(ItemCategory::Tools)->setDescriptionId("hoeIron");
Item::hoe_emerald = (new HoeItem(37, Tier::EMERALD))->setIcon(3, 8)->setCategory(ItemCategory::Tools)->setDescriptionId("hoeDiamond");
Item::hoe_gold = (new HoeItem(38, Tier::GOLD))->setIcon(4, 8)->setCategory(ItemCategory::Tools)->setDescriptionId("hoeGold");
Item::seeds_wheat = (new SeedItem(39, Tile::crops->id, Tile::farmland->id))->setIcon(9, 0)->setCategory(ItemCategory::FoodArmor)->setDescriptionId("seeds");
Item::wheat = (new Item(40))->setIcon(9, 1)->setCategory(ItemCategory::FoodArmor)->setDescriptionId("wheat");
Item::bread = (new FoodItem(41, 5, false))->setIcon(9, 2)->setCategory(ItemCategory::FoodArmor)->setDescriptionId("bread");
Item::helmet_cloth = (new ArmorItem(42, ArmorItem::CLOTH, 0, ArmorItem::SLOT_HEAD))->setIcon(0, 0)->setCategory(ItemCategory::FoodArmor)->setDescriptionId("helmetCloth");
Item::chestplate_cloth = (new ArmorItem(43, ArmorItem::CLOTH, 0, ArmorItem::SLOT_TORSO))->setIcon(0, 1)->setCategory(ItemCategory::FoodArmor)->setDescriptionId("chestplateCloth");
Item::leggings_cloth = (new ArmorItem(44, ArmorItem::CLOTH, 0, ArmorItem::SLOT_LEGS))->setIcon(0, 2)->setCategory(ItemCategory::FoodArmor)->setDescriptionId("leggingsCloth");
Item::boots_cloth = (new ArmorItem(45, ArmorItem::CLOTH, 0, ArmorItem::SLOT_FEET))->setIcon(0, 3)->setCategory(ItemCategory::FoodArmor)->setDescriptionId("bootsCloth");
Item::helmet_chain = (new ArmorItem(46, ArmorItem::CHAIN, 1, ArmorItem::SLOT_HEAD))->setIcon(1, 0)->setCategory(ItemCategory::FoodArmor)->setDescriptionId("helmetChain");
Item::chestplate_chain = (new ArmorItem(47, ArmorItem::CHAIN, 1, ArmorItem::SLOT_TORSO))->setIcon(1, 1)->setCategory(ItemCategory::FoodArmor)->setDescriptionId("chestplateChain");
Item::leggings_chain = (new ArmorItem(48, ArmorItem::CHAIN, 1, ArmorItem::SLOT_LEGS))->setIcon(1, 2)->setCategory(ItemCategory::FoodArmor)->setDescriptionId("leggingsChain");
Item::boots_chain = (new ArmorItem(49, ArmorItem::CHAIN, 1, 3))->setIcon(1, 3)->setCategory(ItemCategory::FoodArmor)->setDescriptionId("bootsChain");
Item::helmet_iron = (new ArmorItem(50, ArmorItem::IRON, 2, ArmorItem::SLOT_HEAD))->setIcon(2, 0)->setCategory(ItemCategory::FoodArmor)->setDescriptionId("helmetIron");
Item::chestplate_iron = (new ArmorItem(51, ArmorItem::IRON, 2, ArmorItem::SLOT_TORSO))->setIcon(2, 1)->setCategory(ItemCategory::FoodArmor)->setDescriptionId("chestplateIron");
Item::leggings_iron = (new ArmorItem(52, ArmorItem::IRON, 2, ArmorItem::SLOT_LEGS))->setIcon(2, 2)->setCategory(ItemCategory::FoodArmor)->setDescriptionId("leggingsIron");
Item::boots_iron = (new ArmorItem(53, ArmorItem::IRON, 2, ArmorItem::SLOT_FEET))->setIcon(2, 3)->setCategory(ItemCategory::FoodArmor)->setDescriptionId("bootsIron");
Item::helmet_diamond = (new ArmorItem(54, ArmorItem::DIAMOND, 3, ArmorItem::SLOT_HEAD))->setIcon(3, 0)->setCategory(ItemCategory::FoodArmor)->setDescriptionId("helmetDiamond");
Item::chestplate_diamond=(new ArmorItem(55, ArmorItem::DIAMOND, 3, ArmorItem::SLOT_TORSO))->setIcon(3, 1)->setCategory(ItemCategory::FoodArmor)->setDescriptionId("chestplateDiamond");
Item::leggings_diamond = (new ArmorItem(56, ArmorItem::DIAMOND, 3, ArmorItem::SLOT_LEGS))->setIcon(3, 2)->setCategory(ItemCategory::FoodArmor)->setDescriptionId("leggingsDiamond");
Item::boots_diamond = (new ArmorItem(57, ArmorItem::DIAMOND, 3, ArmorItem::SLOT_FEET))->setIcon(3, 3)->setCategory(ItemCategory::FoodArmor)->setDescriptionId("bootsDiamond");
Item::helmet_gold = (new ArmorItem(58, ArmorItem::GOLD, 4, ArmorItem::SLOT_HEAD))->setIcon(4, 0)->setCategory(ItemCategory::FoodArmor)->setDescriptionId("helmetGold");
Item::chestplate_gold = (new ArmorItem(59, ArmorItem::GOLD, 4, ArmorItem::SLOT_TORSO))->setIcon(4, 1)->setCategory(ItemCategory::FoodArmor)->setDescriptionId("chestplateGold");
Item::leggings_gold = (new ArmorItem(60, ArmorItem::GOLD, 4, ArmorItem::SLOT_LEGS))->setIcon(4, 2)->setCategory(ItemCategory::FoodArmor)->setDescriptionId("leggingsGold");
Item::boots_gold = (new ArmorItem(61, ArmorItem::GOLD, 4, ArmorItem::SLOT_FEET))->setIcon(4, 3)->setCategory(ItemCategory::FoodArmor)->setDescriptionId("bootsGold");
Item::flint = (new Item(62))->setIcon(6, 0)->setCategory(ItemCategory::Tools)->setDescriptionId("flint");
Item::porkChop_raw = (new FoodItem(63, 3, true))->setIcon(7, 5)->setCategory(ItemCategory::FoodArmor)->setDescriptionId("porkchopRaw");
Item::porkChop_cooked = (new FoodItem(64, 8, true))->setIcon(8, 5)->setCategory(ItemCategory::FoodArmor)->setDescriptionId("porkchopCooked");
Item::painting = (new HangingEntityItem(65, EntityTypes::IdPainting))->setIcon(10, 1)->setCategory(ItemCategory::Decorations)->setDescriptionId("painting");
//Item::apple_gold = (new FoodItem(66, 42, false))->setIcon(11, 0)->setCategory(ItemCategory::FoodArmor)->setDescriptionId("appleGold");
Item::sign = (new SignItem(67))->setIcon(10, 2)->setCategory(ItemCategory::Decorations)->setDescriptionId("sign");
Item::door_wood = (new DoorItem(68, Material::wood))->setIcon(11, 2)->setCategory(ItemCategory::Structures)->setDescriptionId("doorWood");
//Item::bucket_empty = (new BucketItem(69, 0))->setIcon(10, 4)->setCategory(ItemCategory::Tools)->setDescriptionId("bucket");
//Item::bucket_water = (new BucketItem(70, Tile::water.id))->setIcon(11, 4)->setCategory(ItemCategory::Tools)->setDescriptionId("bucketWater")->setCraftingRemainingItem(Item.bucket_empty);
//Item::bucket_lava = (new BucketItem(71, Tile::lava.id))->setIcon(12, 4)->setCategory(ItemCategory::Tools)->setDescriptionId("bucketLava")->setCraftingRemainingItem(Item.bucket_empty);
//Item::minecart = (new MinecartItem(72, Minecart.RIDEABLE))->setIcon(7, 8)->setCategory(ItemCategory::Mechanisms)->setDescriptionId("minecart");
//Item::saddle = (new SaddleItem(73))->setIcon(8, 6)->setCategory(ItemCategory::Mechanisms)->setDescriptionId("saddle");
Item::door_iron = (new DoorItem(74, Material::metal))->setIcon(12, 2)->setCategory(ItemCategory::Structures)->setDescriptionId("doorIron");
//Item::redStone = (new RedStoneItem(75))->setIcon(8, 3)->setCategory(ItemCategory::Mechanisms)->setDescriptionId("redstone");
Item::snowBall = (new SnowballItem(76))->setIcon(14, 0)->setCategory(ItemCategory::Decorations)->setDescriptionId("snowball");
//Item::boat = (new BoatItem(77))->setIcon(8, 8)->setCategory(ItemCategory::Mechanisms)->setDescriptionId("boat");
Item::leather = (new Item(78))->setIcon(7, 6)->setCategory(ItemCategory::Tools)->setDescriptionId("leather");
//Item::milk = (new BucketItem(79, -1))->setIcon(13, 4)->setCategory(ItemCategory::FoodArmor)->setDescriptionId("milk")->setCraftingRemainingItem(Item.bucket_empty);
Item::brick = (new Item(80))->setIcon(6, 1)->setCategory(ItemCategory::Structures)->setDescriptionId("brick");
Item::clay = (new Item(81))->setIcon(9, 3)->setCategory(ItemCategory::Structures)->setDescriptionId("clay");
Item::reeds = (new TilePlanterItem(82, Tile::reeds))->setIcon(11, 1)->setCategory(ItemCategory::FoodArmor)->setDescriptionId("reeds");
Item::paper = (new Item(83))->setIcon(10, 3)->setCategory(ItemCategory::Decorations)->setDescriptionId("paper");
Item::book = (new Item(84))->setIcon(11, 3)->setCategory(ItemCategory::Decorations)->setDescriptionId("book");
Item::slimeBall = (new Item(85))->setIcon(14, 1)->setCategory(ItemCategory::Decorations)->setDescriptionId("slimeball");
//Item::minecart_chest = (new MinecartItem(86, Minecart::CHEST))->setIcon(7, 9)->setCategory(ItemCategory::Mechanisms)->setDescriptionId("minecartChest");
//Item::minecart_furnace = (new MinecartItem(87, Minecart::FURNACE))->setIcon(7, 10)->setCategory(ItemCategory::Mechanisms)->setDescriptionId("minecartFurnace");
Item::egg = (new EggItem(88))->setIcon(12, 0)->setCategory(ItemCategory::FoodArmor)->setDescriptionId("egg");
Item::compass = (new Item(89))->setIcon(6, 3)->setCategory(ItemCategory::Tools)->setDescriptionId("compass");
//Item::fishingRod = (new FishingRodItem(90))->setIcon(5, 4)->setCategory(ItemCategory::Tools)->setDescriptionId("fishingRod");
Item::clock = (new Item(91))->setIcon(6, 4)->setCategory(ItemCategory::Tools)->setDescriptionId("clock");
Item::yellowDust = (new Item(92))->setIcon(9, 4)->setCategory(ItemCategory::Tools)->setDescriptionId("yellowDust");
//Item::fish_raw = (new FoodItem(93, 2, false))->setIcon(9, 5)->setCategory(ItemCategory::Tools)->setDescriptionId("fishRaw");
//Item::fish_cooked = (new FoodItem(94, 5, false))->setIcon(10, 5)->setCategory(ItemCategory::Tools)->setDescriptionId("fishCooked");
Item::dye_powder = (new DyePowderItem(95))->setIcon(14, 4)->setCategory(ItemCategory::Decorations)->setDescriptionId("dyePowder");
Item::bone = (new Item(96))->setIcon(12, 1)->setCategory(ItemCategory::Tools)->setDescriptionId("bone")->handEquipped();
Item::sugar = (new Item(97))->setIcon(13, 0)->setCategory(ItemCategory::FoodArmor)->setDescriptionId("sugar")->handEquipped();
//Item::cake = (new TilePlanterItem(98, Tile::cake))->setMaxStackSize(1)->setIcon(13, 1)->setCategory(ItemCategory::FoodArmor)->setDescriptionId("cake");
Item::bed = (new BedItem(99))->setMaxStackSize(1)->setIcon(13, 2)->setCategory(ItemCategory::Structures)->setDescriptionId("bed");
//Item::diode = (new TilePlanterItem(100, Tile::diode_off))->setIcon(6, 5)->setCategory(ItemCategory::Mechanisms)->setDescriptionId("diode");
Item::shears = (ShearsItem*)(new ShearsItem(103))->setIcon(13, 5)->setCategory(ItemCategory::Tools)->setDescriptionId("shears");
Item::melon = (new FoodItem(104, 2, false))->setIcon(13, 6)->setCategory(ItemCategory::FoodArmor)->setDescriptionId("melon");
Item::seeds_melon = (new SeedItem(106, Tile::melonStem->id, Tile::farmland->id))->setIcon(14, 3)->setCategory(ItemCategory::FoodArmor)->setDescriptionId("seedsMelon");
Item::beef_raw = (new FoodItem(107, 3, /*FoodConstants.FOOD_SATURATION_LOW,*/ true))->setIcon(9, 6)->setCategory(ItemCategory::FoodArmor)->setDescriptionId("beefRaw");
Item::beef_cooked = (new FoodItem(108, 8, /*FoodConstants.FOOD_SATURATION_GOOD,*/ true))->setIcon(10, 6)->setCategory(ItemCategory::FoodArmor)->setDescriptionId("beefCooked");
Item::chicken_raw = (new FoodItem(109, 2, /*FoodConstants.FOOD_SATURATION_LOW,*/ true))->setIcon(9, 7)->setCategory(ItemCategory::FoodArmor)->setDescriptionId("chickenRaw");
Item::chicken_cooked = (new FoodItem(110, 6, /*FoodConstants.FOOD_SATURATION_NORMAL,*/ true))->setIcon(10, 7)->setCategory(ItemCategory::FoodArmor)->setDescriptionId("chickenCooked");
Item::netherbrick = (new Item(149))->setIcon(5, 9)->setDescriptionId("netherbrickItem")->setCategory(ItemCategory::Structures);
Item::netherQuartz = (new Item(150))->setIcon(5, 10)->setDescriptionId("netherquartz")->setCategory(ItemCategory::Mechanisms);
//Item::record_01 = (new RecordingItem(2000, "13"))->setIcon(0, 15)->setCategory(ItemCategory::Decorations)->setDescriptionId("record");
//Item::record_02 = (new RecordingItem(2001, "cat"))->setIcon(1, 15)->setCategory(ItemCategory::Decorations)->setDescriptionId("record");
Item::camera = (new CameraItem(200))->setIcon(2, 15)->setCategory(ItemCategory::Decorations)->setDescriptionId("camera");
for (int i = 256; i < MAX_ITEMS; ++i) {
if (items[i] && items[i]->category == -1)
LOGE("Error: Missing category for item %d: %s\n", items[i]->id, items[i]->getDescriptionId().c_str());
}
}
/*static*/
void Item::teardownItems() {
for (int i = 0; i < MAX_ITEMS; ++i)
if (Item::items[i]) {
delete Item::items[i];
Item::items[i] = NULL;
}
}
ItemInstance Item::useTimeDepleted(ItemInstance* itemInstance, Level* level, Player* player )
{
return *itemInstance;
}

408
src/world/item/Item.h Executable file
View File

@@ -0,0 +1,408 @@
#ifndef NET_MINECRAFT_WORLD_ITEM__Item_H__
#define NET_MINECRAFT_WORLD_ITEM__Item_H__
//package net.minecraft.world.item;
#include "../../locale/I18n.h"
#include "../../util/Random.h"
#include "UseAnim.h"
class Level;
class Tile;
class Entity;
class Mob;
class Player;
class ItemInstance;
class ShearsItem;
class Item
{
static const int MAX_STACK_SIZE = 64;//Container::LARGE_MAX_STACK_SIZE;
public:
static const int MAX_ITEMS = 512;//32000;
static const int ICON_COLUMNS = 16;
static const std::string ICON_DESCRIPTION_PREFIX;
class Tier {
const int level;
const int uses;
const float speed;
const int damage;
public:
static const Tier WOOD;
static const Tier STONE;
static const Tier IRON;
static const Tier EMERALD;
static const Tier GOLD;
Tier(int level, int uses, float speed, int damage)
: level(level),
uses(uses),
speed(speed),
damage(damage)
{
}
int getUses() const {
return uses;
}
float getSpeed() const {
return speed;
}
int getAttackDamageBonus() const {
return damage;
}
int getLevel() const {
return level;
}
};
public:
static Item* items[MAX_ITEMS];
static Item* shovel_iron;
static Item* pickAxe_iron;
static Item* hatchet_iron;
static Item* flintAndSteel;
static Item* apple;
static Item* bow;
static Item* arrow;
static Item* coal;
static Item* emerald;
static Item* ironIngot;
static Item* goldIngot;
static Item* sword_iron;
static Item* sword_wood;
static Item* shovel_wood;
static Item* pickAxe_wood;
static Item* hatchet_wood;
static Item* sword_stone;
static Item* shovel_stone;
static Item* pickAxe_stone;
static Item* hatchet_stone;
static Item* sword_emerald;
static Item* shovel_emerald;
static Item* pickAxe_emerald;
static Item* hatchet_emerald;
static Item* stick;
static Item* bowl;
static Item* mushroomStew;
static Item* sword_gold;
static Item* shovel_gold;
static Item* pickAxe_gold;
static Item* hatchet_gold;
static Item* string;
static Item* feather;
static Item* sulphur;
static Item* hoe_wood;
static Item* hoe_stone;
static Item* hoe_iron;
static Item* hoe_emerald;
static Item* hoe_gold;
static Item* seeds_wheat;
static Item* wheat;
static Item* bread;
static Item* helmet_cloth;
static Item* chestplate_cloth;
static Item* leggings_cloth;
static Item* boots_cloth;
static Item* helmet_chain;
static Item* chestplate_chain;
static Item* leggings_chain;
static Item* boots_chain;
static Item* helmet_iron;
static Item* chestplate_iron;
static Item* leggings_iron;
static Item* boots_iron;
static Item* helmet_diamond;
static Item* chestplate_diamond;
static Item* leggings_diamond;
static Item* boots_diamond;
static Item* helmet_gold;
static Item* chestplate_gold;
static Item* leggings_gold;
static Item* boots_gold;
static Item* flint;
static Item* porkChop_raw;
static Item* porkChop_cooked;
static Item* painting;
static Item* apple_gold;
static Item* sign;
static Item* door_wood;
static Item* bucket_empty;
static Item* bucket_water;
static Item* bucket_lava;
static Item* minecart;
static Item* saddle;
static Item* door_iron;
static Item* redStone;
static Item* snowBall;
static Item* boat;
static Item* leather;
static Item* milk;
static Item* brick;
static Item* clay;
static Item* reeds;
static Item* paper;
static Item* book;
static Item* slimeBall;
static Item* minecart_chest;
static Item* minecart_furnace;
static Item* egg;
static Item* compass;
static Item* fishingRod;
static Item* clock;
static Item* yellowDust;
static Item* fish_raw;
static Item* fish_cooked;
static Item* melon;
static Item* seeds_melon;
static Item* dye_powder;
static Item* bone;
static Item* sugar;
static Item* cake;
static Item* bed;
static Item* diode;
static ShearsItem* shears;
static Item* beef_raw;
static Item* beef_cooked;
static Item* chicken_raw;
static Item* chicken_cooked;
static Item* netherbrick;
static Item* netherQuartz;
static Item* record_01;
static Item* record_02;
static Item* camera;
static void initItems();
static void teardownItems();
Item(int id)
: id(256 + id),
craftingRemainingItem(NULL),
maxStackSize(MAX_STACK_SIZE),
maxDamage(32),
category(-1),
_handEquipped(false),
_isStackedByData(false)
{
if (items[this->id] != NULL) {
printf("Item conflict id @ %d! Id already used\n", this->id);
}
items[this->id] = this;
}
virtual ~Item() {}
virtual Item* setIcon(int icon) {
this->icon = icon;
return this;
}
virtual Item* setMaxStackSize(int max) {
maxStackSize = max;
return this;
}
virtual bool canBeDepleted() {
return maxDamage > 0 && !_isStackedByData;
}
virtual int getIcon(int auxValue) {
return icon;
}
virtual Item* setIcon(int column, int row) {
icon = column + row * ICON_COLUMNS;
return this;
}
virtual bool useOn(ItemInstance* itemInstance, Level* level, int x, int y, int z, int face) {
return false;
}
virtual bool useOn(ItemInstance* itemInstance, Player* player, Level* level, int x, int y, int z, int face, float clickX, float clickY, float clickZ) {
return false;
}
virtual int getUseDuration(ItemInstance* itemInstance) {
return 0;
}
virtual ItemInstance useTimeDepleted(ItemInstance* itemInstance, Level* level, Player* player);
virtual float getDestroySpeed(ItemInstance* itemInstance, Tile* tile) {
return 1;
}
virtual ItemInstance* use(ItemInstance* itemInstance, Level* level, Player* player) {
return itemInstance;
}
virtual int getMaxStackSize() {
return maxStackSize;
}
virtual int getLevelDataForAuxValue(int auxValue) {
return 0;
}
virtual bool isStackedByData() {
return _isStackedByData;
}
Item* setCategory(int category) {
this->category = category;
return this;
}
virtual int getMaxDamage() {
return maxDamage;
}
virtual void hurtEnemy(ItemInstance* itemInstance, Mob* mob) {
}
virtual bool mineBlock(ItemInstance* itemInstance, int tile, int x, int y, int z) {
return false;
}
virtual int getAttackDamage(Entity* entity) {
return 1;
}
virtual bool canDestroySpecial(const Tile* tile) const {
return false;
}
virtual void interactEnemy(ItemInstance* itemInstance, Mob* mob) {
}
virtual Item* handEquipped() {
_handEquipped = true;
return this;
}
virtual bool isHandEquipped() const {
return _handEquipped;
}
virtual bool isMirroredArt() const {
return false;
}
virtual bool isFood() const {
return false;
}
virtual bool isArmor() const {
return false;
}
virtual Item* setDescriptionId(const std::string& id) {
descriptionId = ICON_DESCRIPTION_PREFIX + id;
return this;
}
virtual std::string getDescription() const {
return I18n::get(getDescriptionId());
}
virtual std::string getDescription(const ItemInstance* instance) const {
return I18n::get(getDescriptionId(instance));
}
virtual std::string getDescriptionId() const {
return descriptionId;
}
virtual std::string getDescriptionId(const ItemInstance* instance) const {
return descriptionId;
}
virtual Item* setCraftingRemainingItem(Item* craftingRemainingItem) {
if (maxStackSize > 1) {
printf("Max stack size must be 1 for items with crafting results\n");
}
this->craftingRemainingItem = craftingRemainingItem;
return this;
}
virtual Item* getCraftingRemainingItem() {
return craftingRemainingItem;
}
virtual bool hasCraftingRemainingItem() const {
return craftingRemainingItem != NULL;
}
virtual std::string getName() const {
return I18n::get(getDescriptionId() + ".name");
}
virtual void releaseUsing( ItemInstance* itemInstance, Level* level, Player* player, int durationLeft ) {}
virtual UseAnim::UseAnimation getUseAnimation() {return UseAnim::none;}
protected:
static Random random;
Item* setStackedByData(bool isStackedByData) {
_isStackedByData = isStackedByData;
return this;
}
Item* setMaxDamage(int maxDamage) {
this->maxDamage = maxDamage;
return this;
}
public:
const int id;
int maxDamage;
int icon;
int category;
protected:
int maxStackSize;
private:
bool _handEquipped;
bool _isStackedByData;
Item* craftingRemainingItem;
std::string descriptionId;
};
#endif /*NET_MINECRAFT_WORLD_ITEM__Item_H__*/

27
src/world/item/ItemCategory.h Executable file
View File

@@ -0,0 +1,27 @@
#ifndef NET_MINECRAFT_WORLD_ITEM__ItemCategory_H__
#define NET_MINECRAFT_WORLD_ITEM__ItemCategory_H__
class ItemCategory {
public:
static const int Structures = 1;
static const int Tools = 2;
static const int FoodArmor = 4;
static const int Decorations= 8;
static const int Mechanisms = 16;
static const int NUM_CATEGORIES = 5;
static const char* categoryToString(int id) {
switch (id) {
case Structures: return "Structures";
case Tools: return "Tools";
case FoodArmor: return "Food and\nArmor";
case Decorations: return "Decorations";
case Mechanisms: return "Mechanisms";
default: return "<Unknown category>";
}
}
};
#endif /*NET_MINECRAFT_WORLD_ITEM__ItemCategory_H__*/

36
src/world/item/ItemInclude.h Executable file
View File

@@ -0,0 +1,36 @@
#ifndef NET_MINECRAFT_WORLD_ITEM__ItemInclude_H__
#define NET_MINECRAFT_WORLD_ITEM__ItemInclude_H__
#include "Item.h"
#include "BedItem.h"
#include "CameraItem.h"
#include "CoalItem.h"
#include "DoorItem.h"
#include "EggItem.h"
#include "FlintAndSteelItem.h"
#include "SnowballItem.h"
#include "TilePlanterItem.h"
#include "AuxDataTileItem.h"
#include "BowlFoodItem.h"
#include "ClothTileItem.h"
#include "DyePowderItem.h"
#include "FoodItem.h"
#include "LeafTileItem.h"
#include "StoneSlabTileItem.h"
#include "ArmorItem.h"
#include "BowItem.h"
#include "DiggerItem.h"
#include "HatchetItem.h"
#include "HoeItem.h"
#include "PickaxeItem.h"
#include "ShovelItem.h"
#include "ShearsItem.h"
#include "WeaponItem.h"
#include "SeedItem.h"
#include "HangingEntityItem.h"
#include "SignItem.h"
#endif /*NET_MINECRAFT_WORLD_ITEM__ItemInclude_H__*/

292
src/world/item/ItemInstance.cpp Executable file
View File

@@ -0,0 +1,292 @@
#include "ItemInstance.h"
#include "Item.h"
#include "../level/tile/Tile.h"
#include "../../nbt/CompoundTag.h"
ItemInstance::ItemInstance() {
init(0, 0, 0);
}
ItemInstance::ItemInstance(const Tile* tile) {
init(tile->id, 1, 0);
}
ItemInstance::ItemInstance(const Tile* tile, int count) {
init(tile->id, count, 0);
}
ItemInstance::ItemInstance(const Tile* tile, int count, int auxValue) {
init(tile->id, count, auxValue);
}
ItemInstance::ItemInstance(const Item* item) {
init(item->id, 1, 0);
}
ItemInstance::ItemInstance(const Item* item, int count) {
init(item->id, count, 0);
}
ItemInstance::ItemInstance(const Item* item, int count, int auxValue) {
init(item->id, count, auxValue);
}
ItemInstance::ItemInstance(int id, int count, int damage) {
init(id, count, damage);
}
ItemInstance::ItemInstance(const ItemInstance& rhs) {
this->auxValue = rhs.auxValue;
this->count = rhs.count;
//this->popTime = rhs.popTime;
this->id = rhs.id;
}
void ItemInstance::init(int id, int count, int damage) {
this->id = id;
this->count = count;
this->auxValue = damage;
}
bool ItemInstance::isNull() const {
return (id|count|auxValue) == 0;
}
void ItemInstance::setNull() {
id = count = auxValue = 0;
}
//ItemInstance::ItemInstance(CompoundTag itemTag) {
// load(itemTag);
//}
ItemInstance ItemInstance::remove(int count) {
this->count -= count;
return /*new*/ ItemInstance(id, count, auxValue);
}
bool ItemInstance::useOn(Player* player, Level* level, int x, int y, int z, int face, float clickX, float clickY, float clickZ) {
if (getItem()->useOn(this, player, level, x, y, z, face, clickX, clickY, clickZ)) {
//player.awardStat(Stats.itemUsed[id], 1);
return true;
}
return false;
}
float ItemInstance::getDestroySpeed(Tile* tile) {
return getItem()->getDestroySpeed(this, tile);
}
ItemInstance* ItemInstance::use(Level* level, Player* player) {
return getItem()->use(this, level, player);
}
int ItemInstance::getMaxStackSize() const {
return getItem()->getMaxStackSize();
}
bool ItemInstance::isStackable() const {
return getMaxStackSize() > 1 && (!isDamageableItem() || !isDamaged());
}
bool ItemInstance::isStackable( const ItemInstance* a, const ItemInstance* b ) {
return a && b && a->id == b->id && b->isStackable()
&& (!b->isStackedByData() || a->getAuxValue() == b->getAuxValue());
}
bool ItemInstance::isDamageableItem() const {
return Item::items[id]->getMaxDamage() > 0;
}
/**
* Returns true if this item type only can be stacked with items that have
* the same auxValue data.
*
* @return
*/
bool ItemInstance::isStackedByData() const {
return Item::items[id]->isStackedByData();
}
bool ItemInstance::isDamaged() const {
return isDamageableItem() && auxValue > 0;
}
int ItemInstance::getDamageValue() const {
return auxValue;
}
int ItemInstance::getAuxValue() const {
return auxValue;
}
void ItemInstance::setAuxValue(int value) {
auxValue = value;
}
int ItemInstance::getMaxDamage() const {
return Item::items[id]->getMaxDamage();
}
void ItemInstance::hurt(int i) {
if (!isDamageableItem())
return;
auxValue += i;
if (auxValue > getMaxDamage()) {
count--;
if (count < 0) count = 0;
auxValue = 0;
}
}
void ItemInstance::hurtEnemy(Mob* mob) {
Item::items[id]->hurtEnemy(this, mob);
}
void ItemInstance::mineBlock(int tile, int x, int y, int z) {
Item::items[id]->mineBlock(this, tile, x, y, z);
}
int ItemInstance::getAttackDamage(Entity* entity) {
return Item::items[id]->getAttackDamage(entity);
}
bool ItemInstance::canDestroySpecial(Tile* tile) {
return Item::items[id]->canDestroySpecial(tile);
}
void ItemInstance::snap(Player* player) {
}
void ItemInstance::interactEnemy(Mob* mob) {
Item::items[id]->interactEnemy(this, mob);
}
ItemInstance* ItemInstance::copy() const {
return new ItemInstance(id, count, auxValue);
}
/*static*/
bool ItemInstance::matches(const ItemInstance* a, const ItemInstance* b) {
if (a == NULL && b == NULL) return true;
if (a == NULL || b == NULL) return false;
return a->matches(b);
}
/*static*/
bool ItemInstance::matchesNulls(const ItemInstance* a, const ItemInstance* b) {
bool aNull = !a || a->isNull();
bool bNull = !b || b->isNull();
if (aNull && bNull) return true;
if (aNull || bNull) return false;
return a->matches(b);
}
/**
* Checks if this item is the same item as the other one, disregarding the
* 'count' value.
*
* @param b
* @return
*/
bool ItemInstance::sameItem(ItemInstance* b) {
return id == b->id && auxValue == b->auxValue;
}
std::string ItemInstance::getDescriptionId() const {
return id? Item::items[id]->getDescriptionId(this) : "EmptyItemInstance";
}
ItemInstance* ItemInstance::setDescriptionId(const std::string& id) {
return this;
}
std::string ItemInstance::getName() const {
return I18n::get(getDescriptionId() + ".name");
}
std::string ItemInstance::toString() const {
std::stringstream ss;
ss << count << " x " << getDescriptionId() << "(" << id << ")" << "@" << auxValue;
return ss.str();
}
/*static*/
ItemInstance* ItemInstance::clone(const ItemInstance* item) {
return item == NULL ? NULL : item->copy();
}
/*static*/
ItemInstance ItemInstance::cloneSafe( const ItemInstance* item ) {
return item? *item : ItemInstance();
}
/*private*/
bool ItemInstance::matches(const ItemInstance* b) const {
return (id == b->id)
&& (count == b->count)
&& (auxValue == b->auxValue);
}
CompoundTag* ItemInstance::save(CompoundTag* compoundTag) {
compoundTag->putShort("id", (short) id);
compoundTag->putByte("Count", (unsigned char) count);
compoundTag->putShort("Damage", (short) auxValue);
return compoundTag;
}
void ItemInstance::load(CompoundTag* compoundTag) {
id = compoundTag->getShort("id");
count = (unsigned char) compoundTag->getByte("Count");
auxValue = compoundTag->getShort("Damage");
}
bool ItemInstance::operator==( const ItemInstance& rhs ) const {
return id == rhs.id
&& auxValue == rhs.auxValue
&& count == rhs.count;
}
ItemInstance* ItemInstance::fromTag( CompoundTag* tag ) {
ItemInstance* item = new ItemInstance();
item->load(tag);
if (item->getItem() == NULL) {
delete item;
item = NULL;
}
return item;
}
Item* ItemInstance::getItem() const {
return Item::items[id];
}
int ItemInstance::getIcon() const {
return Item::items[id]->getIcon(this->auxValue);
}
void ItemInstance::releaseUsing( Level* level, Player* player, int durationLeft ) {
getItem()->releaseUsing(this, level, player, durationLeft);
}
int ItemInstance::getUseDuration() {
return getItem()->getUseDuration(this);
}
UseAnim::UseAnimation ItemInstance::getUseAnimation() const {
return getItem()->getUseAnimation();
}
ItemInstance ItemInstance::useTimeDepleted( Level* level, Player* player ) {
return getItem()->useTimeDepleted(this, level, player);
}
bool ItemInstance::isArmorItem( const ItemInstance* instance ) {
if (!instance)
return false;
Item* item = instance->getItem();
if (!item)
return false;
return item->isArmor();
}

117
src/world/item/ItemInstance.h Executable file
View File

@@ -0,0 +1,117 @@
#ifndef NET_MINECRAFT_WORLD_ITEM__ItemInstance_H__
#define NET_MINECRAFT_WORLD_ITEM__ItemInstance_H__
//package net.minecraft.world.item;
#include <string>
#include "UseAnim.h"
class Level;
class Tile;
class Entity;
class Mob;
class Player;
class CompoundTag;
class Item;
/*final*/
class ItemInstance
{
public:
ItemInstance();
explicit ItemInstance(const Tile* tile); // for catching NULL inits
ItemInstance(const Tile* tile, int count);
ItemInstance(const Tile* tile, int count, int auxValue);
explicit ItemInstance(const Item* item); // for catching NULL inits
ItemInstance(const Item* item, int count);
ItemInstance(const Item* item, int count, int auxValue);
ItemInstance(int id, int count, int damage);
ItemInstance(const ItemInstance& rhs);
void init(int id, int count, int damage);
bool isNull() const;
void setNull();
bool operator==(const ItemInstance& rhs) const;
bool matches(const ItemInstance* b) const;
//ItemInstance(CompoundTag itemTag);
ItemInstance remove(int count);
Item* getItem() const;
int getIcon() const;
float getDestroySpeed(Tile* tile);
bool useOn(Player* player, Level* level, int x, int y, int z, int face, float clickX, float clickY, float clickZ);
ItemInstance* use(Level* level, Player* player);
/**
* Returns true if this item type only can be stacked with items that have
* the same auxValue data.
*/
bool isStackedByData() const;
bool isStackable() const;
int getMaxStackSize() const;
static bool isStackable(const ItemInstance* a, const ItemInstance* b);
bool isDamaged() const;
bool isDamageableItem() const;
int getDamageValue() const;
int getMaxDamage() const;
int getAuxValue() const;
void setAuxValue(int value);
void hurt(int i);
void hurtEnemy(Mob* mob);
void mineBlock(int tile, int x, int y, int z);
int getAttackDamage(Entity* entity);
bool canDestroySpecial(Tile* tile);
void snap(Player* player);
ItemInstance useTimeDepleted(Level* level, Player* player);
void interactEnemy(Mob* mob);
//@huge @attn @note: this returns a NEW'ed copy, change?
ItemInstance* copy() const;
static bool matches(const ItemInstance* a, const ItemInstance* b);
static bool matchesNulls(const ItemInstance* a, const ItemInstance* b);
static bool isArmorItem(const ItemInstance* instance);
/**
* Checks if this item is the same item as the other one, disregarding the
* 'count' value.
*/
bool sameItem(ItemInstance* b);
static ItemInstance* clone(const ItemInstance* item);
static ItemInstance cloneSafe(const ItemInstance* item);
std::string getDescriptionId() const;
std::string getName() const;
ItemInstance* setDescriptionId(const std::string& id);
std::string toString() const;
CompoundTag* save(CompoundTag* compoundTag);
void load(CompoundTag* compoundTag);
static ItemInstance* fromTag( CompoundTag* tag );
void releaseUsing( Level* level, Player* player, int durationLeft );
int getUseDuration();
UseAnim::UseAnimation getUseAnimation() const;
public:
int count;
//int popTime;
int id;
private:
/**
* This was previously the damage value, but is now used for different stuff
* depending on item / tile. Use the getter methods to make sure the value
* is interpreted correctly.
*/
int auxValue;
};
#endif /*NET_MINECRAFT_WORLD_ITEM__ItemInstance_H__*/

40
src/world/item/LeafTileItem.h Executable file
View File

@@ -0,0 +1,40 @@
#ifndef NET_MINECRAFT_WORLD_ITEM__LeafTileItem_H__
#define NET_MINECRAFT_WORLD_ITEM__LeafTileItem_H__
//package net.minecraft.world.item;
#include "TileItem.h"
#include "../level/tile/LeafTile.h"
#include "../level/FoliageColor.h"
class LeafTileItem: public TileItem
{
typedef TileItem super;
public:
LeafTileItem(int id)
: super(id)
{
setMaxDamage(0);
setStackedByData(true);
}
int getLevelDataForAuxValue(int auxValue) {
return auxValue | LeafTile::PERSISTENT_LEAF_BIT;
}
int getIcon(int itemAuxValue) {
return Tile::leaves->getTexture(0, itemAuxValue);
}
int getColor(int data) {
if ((data & LeafTile::EVERGREEN_LEAF) == LeafTile::EVERGREEN_LEAF) {
return FoliageColor::getEvergreenColor();
}
if ((data & LeafTile::BIRCH_LEAF) == LeafTile::BIRCH_LEAF) {
return FoliageColor::getBirchColor();
}
return FoliageColor::getDefaultColor();
}
};
#endif /*NET_MINECRAFT_WORLD_ITEM__LeafTileItem_H__*/

53
src/world/item/PickaxeItem.cpp Executable file
View File

@@ -0,0 +1,53 @@
#include "PickaxeItem.h"
#include "../level/material/Material.h"
#include "../level/tile/Tile.h"
PickaxeItem::PickaxeItem( int id, const Tier& tier ) : super(id, 2, tier)
{
TileList d;
d.push_back(Tile::stoneBrick);
d.push_back(Tile::stoneSlab);
d.push_back(Tile::stoneSlabHalf);
d.push_back(Tile::rock);
d.push_back(Tile::sandStone);
d.push_back(Tile::mossStone);
d.push_back(Tile::ironOre);
d.push_back(Tile::ironBlock);
d.push_back(Tile::coalOre);
d.push_back(Tile::goldBlock);
d.push_back(Tile::goldOre);
d.push_back(Tile::emeraldOre);
d.push_back(Tile::emeraldBlock);
d.push_back(Tile::ice);
//d.push_back(Tile::hellRock);
d.push_back(Tile::lapisOre);
d.push_back(Tile::lapisBlock);
d.push_back(Tile::redStoneOre);
d.push_back(Tile::redStoneOre_lit);
//d.push_back(Tile::rail);
//d.push_back(Tile::detectorRail);
//d.push_back(Tile::goldenRail);
setTiles(d);
}
bool PickaxeItem::canDestroySpecial( const Tile* tile ) const
{
if (tile == Tile::obsidian) return tier.getLevel() == 3;
if (tile == Tile::emeraldBlock || tile == Tile::emeraldOre) return tier.getLevel() >= 2;
if (tile == Tile::goldBlock || tile == Tile::goldOre) return tier.getLevel() >= 2;
if (tile == Tile::ironBlock || tile == Tile::ironOre) return tier.getLevel() >= 1;
if (tile == Tile::lapisBlock || tile == Tile::lapisOre) return tier.getLevel() >= 1;
if (tile == Tile::redStoneOre || tile == Tile::redStoneOre_lit) return tier.getLevel() >= 2;
if (tile->material == Material::stone) return true;
if (tile->material == Material::metal) return true;
return false;
}
float PickaxeItem::getDestroySpeed( ItemInstance* itemInstance, Tile* tile )
{
if (tile != NULL && (tile->material == Material::metal || tile->material == Material::stone)) {
return speed;
}
return super::getDestroySpeed(itemInstance, tile);
}

23
src/world/item/PickaxeItem.h Executable file
View File

@@ -0,0 +1,23 @@
#ifndef NET_MINECRAFT_WORLD_ITEM__PickaxeItem_H__
#define NET_MINECRAFT_WORLD_ITEM__PickaxeItem_H__
//package net.minecraft.world.item;
#include "DiggerItem.h"
class Tile;
class Tier;
class ItemInstance;
class PickaxeItem: public DiggerItem
{
typedef DiggerItem super;
public:
PickaxeItem(int id, const Tier& tier);
bool canDestroySpecial(const Tile* tile) const;
//@Override
float getDestroySpeed(ItemInstance* itemInstance, Tile* tile);
};
#endif /*NET_MINECRAFT_WORLD_ITEM__PickaxeItem_H__*/

View File

@@ -0,0 +1,29 @@
#ifndef NET_MINECRAFT_WORLD_ITEM__SaplingTileItem_H__
#define NET_MINECRAFT_WORLD_ITEM__SaplingTileItem_H__
//package net.minecraft.world.item;
#include "TileItem.h"
#include "../level/tile/Tile.h"
class SaplingTileItem: public TileItem
{
typedef TileItem super;
public:
SaplingTileItem(int id)
: super(id)
{
setMaxDamage(0);
setStackedByData(true);
}
int getLevelDataForAuxValue(int auxValue) {
return auxValue;
}
int getIcon(int itemAuxValue) {
return Tile::sapling->getTexture(0, itemAuxValue);
}
};
#endif /*NET_MINECRAFT_WORLD_ITEM__SaplingTileItem_H__*/

31
src/world/item/SeedItem.h Executable file
View File

@@ -0,0 +1,31 @@
#ifndef NET_MINECRAFT_WORLD_ITEM__SeedItem_H__
#define NET_MINECRAFT_WORLD_ITEM__SeedItem_H__
#include "Item.h"
class SeedItem : public Item {
typedef Item super;
public:
SeedItem(int id, int resultId, int targetLand)
: super(id),
resultId(resultId),
targetLand(targetLand)
{}
bool useOn(ItemInstance* itemInstance, Player* player, Level* level, int x, int y, int z, int face, float clickX, float clickY, float clickZ) {
if(face != 1) return false;
//if (!player.mayBuild(x, y, z) || !player.mayBuild(x, y + 1, z)) return false;
int targetType = level->getTile(x, y, z);
if(targetType == targetLand && level->isEmptyTile(x, y + 1, z)) {
level->setTile(x, y + 1, z, resultId);
itemInstance->count--;
return true;
}
return false;
}
private:
int resultId;
int targetLand;
};
#endif /* NET_MINECRAFT_WORLD_ITEM__SeedItem_H__ */

49
src/world/item/ShearsItem.h Executable file
View File

@@ -0,0 +1,49 @@
#ifndef NET_MINECRAFT_WORLD_ITEM__ShearsItem_H__
#define NET_MINECRAFT_WORLD_ITEM__ShearsItem_H__
//package net.minecraft.world.item;
#include "Item.h"
#include "../entity/Mob.h"
#include "../level/tile/Tile.h"
// @todo: web and perhaps mineBlock
class ShearsItem: public Item
{
typedef Item super;
public:
ShearsItem(int itemId)
: super(itemId)
{
setMaxStackSize(1);
setMaxDamage(238);
}
/*@Override*/
bool mineBlock(ItemInstance* itemInstance, int tile, int x, int y, int z/*, Mob* owner*/) {
if (tile == ((Tile*)Tile::leaves)->id || tile == Tile::web->id /*|| tile == Tile::tallgrass->id || tile == Tile::vine->id*/) {
itemInstance->hurt(1);//, owner);
return true;
}
return super::mineBlock(itemInstance, tile, x, y, z); // owner);
}
/*@Override*/
bool canDestroySpecial(const Tile* tile) const {
return tile->id == Tile::web->id;
}
/*@Override*/
float getDestroySpeed(ItemInstance* itemInstance, Tile* tile) {
if (tile->id == Tile::web->id || tile->id == ((Tile*)Tile::leaves)->id) {
return 15;
}
if (tile->id == Tile::cloth->id) {
return 5;
}
return super::getDestroySpeed(itemInstance, tile);
}
};
#endif /*NET_MINECRAFT_WORLD_ITEM__ShearsItem_H__*/

24
src/world/item/ShovelItem.cpp Executable file
View File

@@ -0,0 +1,24 @@
#include "ShovelItem.h"
#include "../level/tile/Tile.h"
ShovelItem::ShovelItem( int id, const Tier& tier )
: super(id, 1, tier)
{
TileList d;
d.push_back((Tile*)Tile::grass);
d.push_back(Tile::dirt);
d.push_back(Tile::sand);
d.push_back(Tile::gravel);
d.push_back(Tile::topSnow);
d.push_back(Tile::snow);
d.push_back(Tile::clay);
d.push_back(Tile::farmland);
setTiles(d);
}
bool ShovelItem::canDestroySpecial( const Tile* tile ) const {
if (tile == Tile::topSnow) return true;
if (tile == Tile::snow) return true;
return false;
}

21
src/world/item/ShovelItem.h Executable file
View File

@@ -0,0 +1,21 @@
#ifndef NET_MINECRAFT_WORLD_ITEM__ShovelItem_H__
#define NET_MINECRAFT_WORLD_ITEM__ShovelItem_H__
//package net.minecraft.world.item;
#include "DiggerItem.h"
#include <vector>
class Tile;
class Tier;
class ShovelItem: public DiggerItem
{
typedef DiggerItem super;
public:
ShovelItem(int id, const Tier& tier);
bool canDestroySpecial(const Tile* tile) const;
};
#endif /*NET_MINECRAFT_WORLD_ITEM__ShovelItem_H__*/

50
src/world/item/SignItem.h Executable file
View File

@@ -0,0 +1,50 @@
#ifndef NET_MINECRAFT_WORLD_ITEM__SignItem_H__
#define NET_MINECRAFT_WORLD_ITEM__SignItem_H__
//package net.minecraft.world.item;
#include "../entity/player/Player.h"
#include "../level/Level.h"
#include "../level/tile/Tile.h"
#include "../level/tile/entity/SignTileEntity.h"
class SignItem: public Item
{
typedef Item super;
public:
SignItem(int id)
: super(id)
{
maxStackSize = 16;
}
/*@Override*/
bool useOn(ItemInstance* instance, Player* player, Level* level, int x, int y, int z, int face, float clickX, float clickY, float clickZ) {
if (face == 0) return false;
if (!level->getMaterial(x, y, z)->isSolid()) return false;
if (face == 1) y++;
if (face == 2) z--;
if (face == 3) z++;
if (face == 4) x--;
if (face == 5) x++;
//if (!player->mayUseItemAt(x, y, z, face, instance)) return false;
if (!Tile::sign->mayPlace(level, x, y, z)) return false;
if (face == 1) {
int rot = Mth::floor(((player->yRot + 180) * 16) / 360 + 0.5f) & 15;
level->setTileAndData(x, y, z, Tile::sign->id, rot);
} else {
level->setTileAndData(x, y, z, Tile::wallSign->id, face);
}
instance->count--;
SignTileEntity* ste = (SignTileEntity*) level->getTileEntity(x, y, z);
if (ste != NULL) player->openTextEdit(ste);
return true;
}
};
#endif /*NET_MINECRAFT_WORLD_ITEM__SignItem_H__*/

30
src/world/item/SnowballItem.h Executable file
View File

@@ -0,0 +1,30 @@
#ifndef NET_MINECRAFT_WORLD_ITEM__SnowballItem_H__
#define NET_MINECRAFT_WORLD_ITEM__SnowballItem_H__
//package net.minecraft.world.item;
#include "Item.h"
#include "../entity/player/Player.h"
#include "../entity/projectile/Snowball.h"
#include "../level/Level.h"
class SnowballItem: public Item {
typedef Item super;
public:
SnowballItem(int id)
: super(id)
{
maxStackSize = 16;
}
ItemInstance* use(ItemInstance* instance, Level* level, Player* player) {
if (!player->abilities.instabuild)
instance->count--;
level->playSound(player, "random.bow", 0.5f, 0.4f / (random.nextFloat() * 0.4f + 0.8f));
if (!level->isClientSide) level->addEntity(new Snowball(level, player));
return instance;
}
};
#endif /*NET_MINECRAFT_WORLD_ITEM__SnowballItem_H__*/

View File

@@ -0,0 +1,65 @@
#ifndef NET_MINECRAFT_WORLD_ITEM__StoneSlabTileItem_H__
#define NET_MINECRAFT_WORLD_ITEM__StoneSlabTileItem_H__
//package net.minecraft.world.item;
#include "TileItem.h"
#include "../Facing.h"
#include "../level/Level.h"
#include "../entity/player/Player.h"
#include "../level/tile/StoneSlabTile.h"
#include "../level/tile/Tile.h"
class StoneSlabTileItem: public TileItem
{
typedef TileItem super;
public:
StoneSlabTileItem(int id)
: super(id)
{
setMaxDamage(0);
setStackedByData(true);
}
/*@Override*/
int getIcon(int itemAuxValue) {
return Tile::stoneSlabHalf->getTexture(2, itemAuxValue);
}
/*@Override*/
int getLevelDataForAuxValue(int auxValue) {
return auxValue;
}
/*@Override*/
std::string getDescriptionId(const ItemInstance* instance) const {
int auxValue = instance->getAuxValue();
if (auxValue < 0 || auxValue >= StoneSlabTile::SLAB_NAMES_COUNT)
auxValue = 0;
return super::getDescriptionId() + "." + StoneSlabTile::SLAB_NAMES[auxValue];
}
/*@Override*/
bool useOn(ItemInstance* instance, Player* player, Level* level, int x, int y, int z, int face, float clickX, float clickY, float clickZ) {
if (instance->count == 0) return false;
//if (!player->mayBuild(x, y, z)) return false;
int currentTile = level->getTile(x, y, z);
int currentData = level->getData(x, y, z);
int slabType = currentData & StoneSlabTile::TYPE_MASK;
bool isUpper = (currentData & StoneSlabTile::TOP_SLOT_BIT) != 0;
if (((face == Facing::UP && !isUpper) || (face == Facing::DOWN && isUpper)) && currentTile == Tile::stoneSlabHalf->id && slabType == instance->getAuxValue()) {
bool unobstructed = level->isUnobstructed(*Tile::stoneSlab->getAABB(level, x, y, z));
if (unobstructed && level->setTileAndData(x, y, z, Tile::stoneSlab->id, slabType)) {
level->playSound(x + 0.5f, y + 0.5f, z + 0.5f, Tile::stoneSlab->soundType->getStepSound(), (Tile::stoneSlab->soundType->getVolume() + 1) / 2, Tile::stoneSlab->soundType->getPitch() * 0.8f);
instance->count--;
}
return true;
} else {
return super::useOn(instance, player, level, x, y, z, face, clickX, clickY, clickZ);
}
}
};
#endif /*NET_MINECRAFT_WORLD_ITEM__StoneSlabTileItem_H__*/

86
src/world/item/TileItem.h Executable file
View File

@@ -0,0 +1,86 @@
#ifndef NET_MINECRAFT_WORLD_ITEM__TileItem_H__
#define NET_MINECRAFT_WORLD_ITEM__TileItem_H__
//package net.minecraft.world.item;
#include <string>
#include "Item.h"
#include "ItemInstance.h"
#include "../entity/player/Player.h"
#include "../level/Level.h"
#include "../level/tile/Tile.h"
#include "../../network/RakNetInstance.h"
#include "../../network/packet/PlaceBlockPacket.h"
class TileItem: public Item
{
typedef Item super;
int tileId;
public:
TileItem(int id_)
: super(id_)
{
this->tileId = id_ + 256;
this->setIcon(Tile::tiles[id_ + 256]->getTexture(2));
}
int getTileId() {
return tileId;
}
bool useOn(ItemInstance* instance, Player* player, Level* level, int x, int y, int z, int face, float clickX, float clickY, float clickZ) {
if (level->adventureSettings.immutableWorld) {
const Tile* tile = Tile::tiles[tileId];
if (tileId != ((Tile*)Tile::leaves)->id
&& tile->material != Material::plant) {
return false;
}
}
if (level->getTile(x, y, z) == Tile::topSnow->id) {
face = 0;
} else {
switch (face) {
case Facing::DOWN : y--; break;
case Facing::UP : y++; break;
case Facing::NORTH: z--; break;
case Facing::SOUTH: z++; break;
case Facing::WEST : x--; break;
case Facing::EAST : x++; break;
}
}
if (instance->count == 0) return false;
if (level->mayPlace(tileId, x, y, z, false, face)) {
Tile* tile = Tile::tiles[tileId];
int data = tile->getPlacedOnFaceDataValue(level, x, y, z, face, clickX, clickY, clickZ, getLevelDataForAuxValue(instance->getAuxValue()));
if (level->setTileAndData(x, y, z, tileId, data)) {
Tile::tiles[tileId]->setPlacedBy(level, x, y, z, player);
level->playSound(x + 0.5f, y + 0.5f, z + 0.5f, tile->soundType->getStepSound(), (tile->soundType->getVolume() + 1) / 2, tile->soundType->getPitch() * 0.8f);
/*
PlaceBlockPacket packet(player->entityId, x, y, z, face, tileId, instance->getAuxValue());
//LOGI("Place block at @ %d, %d, %d\n", x, y, z);
level->raknetInstance->send(packet);
*/
instance->count--;
}
return true;
}
return false;
}
std::string getDescriptionId(const ItemInstance* instance) const {
return Tile::tiles[tileId]->getDescriptionId();
}
std::string getDescriptionId() const {
return Tile::tiles[tileId]->getDescriptionId();
}
};
#endif /*NET_MINECRAFT_WORLD_ITEM__TileItem_H__*/

View File

@@ -0,0 +1,53 @@
#ifndef NET_MINECRAFT_WORLD_ITEM__TilePlanterItem_H__
#define NET_MINECRAFT_WORLD_ITEM__TilePlanterItem_H__
//package net.minecraft.world.item;
#include "../entity/player/Player.h"
#include "../level/Level.h"
#include "../level/tile/Tile.h"
#include "Item.h"
#include "ItemInstance.h"
class TilePlanterItem: public Item
{
typedef Item super;
int tileId;
public:
TilePlanterItem(int id, Tile* tile)
: super(id)
{
tileId = tile->id;
}
bool useOn(ItemInstance* instance, Player* player, Level* level, int x, int y, int z, int face, float clickX, float clickY, float clickZ) {
if (level->getTile(x, y, z) == Tile::topSnow->id) {
face = 0;
} else {
switch (face) {
case Facing::DOWN : y--; break;
case Facing::UP : y++; break;
case Facing::NORTH: z--; break;
case Facing::SOUTH: z++; break;
case Facing::WEST : x--; break;
case Facing::EAST : x++; break;
}
}
if (instance->count == 0) return false;
if (level->mayPlace(tileId, x, y, z, false, face)) {
//Tile* tile = Tile::tiles[tileId];
if (level->setTile(x, y, z, tileId)) {
//Tile::tiles[tileId]->setPlacedOnFace(level, x, y, z, face);
Tile::tiles[tileId]->setPlacedBy(level, x, y, z, player);
//level->playSound(x + 0.5f, y + 0.5f, z + 0.5f, tile->soundType.getStepSound(), (tile->soundType.getVolume() + 1) / 2, tile->soundType.getPitch() * 0.8f);
instance->count--;
}
}
return true;
}
};
#endif /*NET_MINECRAFT_WORLD_ITEM__TilePlanterItem_H__*/

30
src/world/item/TreeTileItem.h Executable file
View File

@@ -0,0 +1,30 @@
#ifndef NET_MINECRAFT_WORLD_ITEM__TreeTileItem_H__
#define NET_MINECRAFT_WORLD_ITEM__TreeTileItem_H__
//package net.minecraft.world.item;
#include "../level/tile/Tile.h"
#include "ItemInstance.h"
class TreeTileItem: public TileItem
{
typedef TileItem super;
public:
TreeTileItem(int id)
: super(id)
{
setMaxDamage(0);
setStackedByData(true);
}
int getIcon(const ItemInstance* itemInstance) {
return Tile::treeTrunk->getTexture(2, itemInstance->getAuxValue());
}
int getLevelDataForAuxValue(int auxValue) {
return auxValue;
}
};
#endif /*NET_MINECRAFT_WORLD_ITEM__TreeTileItem_H__*/

15
src/world/item/UseAnim.h Executable file
View File

@@ -0,0 +1,15 @@
#ifndef NET_MINECRAFT_WORLD_ITEM__UseAnim_H__
#define NET_MINECRAFT_WORLD_ITEM__UseAnim_H__
class UseAnim {
public:
enum UseAnimation {
none,
eat,
drink,
block,
bow
};
};
#endif /* NET_MINECRAFT_WORLD_ITEM__UseAnim_H__ */

82
src/world/item/WeaponItem.h Executable file
View File

@@ -0,0 +1,82 @@
#ifndef NET_MINECRAFT_WORLD_ITEM__WeaponItem_H__
#define NET_MINECRAFT_WORLD_ITEM__WeaponItem_H__
//package net.minecraft.world.item;
#include "Item.h"
#include "../entity/Entity.h"
#include "../entity/Mob.h"
#include "../entity/player/Player.h"
#include "../level/Level.h"
#include "../level/tile/Tile.h"
class WeaponItem: public Item
{
typedef Item super;
public:
WeaponItem(int id, const Item::Tier& tier)
: super(id),
tier(tier)
{
maxStackSize = 1;
setMaxDamage(tier.getUses());
damage = 4 + tier.getAttackDamageBonus();
}
/*@Override*/
float getDestroySpeed(ItemInstance* itemInstance, Tile* tile) {
//@todo
if (tile->id == Tile::web->id) {
// swords can quickly cut web
return 15;
}
return 1.5f;
}
void hurtEnemy(ItemInstance* itemInstance, Mob* mob/*, Mob* attacker*/) {
itemInstance->hurt(1);// attacker);
//return true;
}
bool mineBlock(ItemInstance* itemInstance, int tile, int x, int y, int z/*, Mob* owner*/) {
itemInstance->hurt(2);//, owner);
return true;
}
int getAttackDamage(Entity* entity) {
return damage;
}
bool isHandEquipped() const {
return true;
}
//UseAnim getUseAnimation(ItemInstance itemInstance) {
// return UseAnim.block;
//}
int getUseDuration(ItemInstance* itemInstance) {
return 20 * 60 * 60; // Block for a maximum of one hour!
}
ItemInstance* use(ItemInstance* instance, Level* level, Player* player) {
//player->startUsingItem(instance, getUseDuration(instance)); //@todo
return instance;
}
// /*@Override*/
bool canDestroySpecial(const Tile* tile) const {
return tile->id == Tile::web->id;
}
///*@Override*/
//int getEnchantmentValue() {
// return tier.getEnchantmentValue();
//}
private:
int damage;
const Tier& tier;
};
#endif /*NET_MINECRAFT_WORLD_ITEM__WeaponItem_H__*/

View File

@@ -0,0 +1,53 @@
#include "ArmorRecipes.h"
#include "Recipes.h"
#include "../../level/tile/Tile.h"
static RowList shapes[] = {
// Helmet
Recipes::Shape(
"XXX", //
"X X"),//
// Chest plate
Recipes::Shape(
"X X",//
"XXX",//
"XXX"),//
// Leggings
Recipes::Shape(
"XXX",//
"X X",//
"X X"),//
// Boots
Recipes::Shape(
"X X",//
"X X")//
};
void ArmorRecipes::addRecipes( Recipes* r )
{
int materialIds[] = {Item::leather->id, /*((Tile*)Tile::fire)->id,*/ Item::ironIngot->id, Item::emerald->id, Item::goldIngot->id};
const int NumMaterials = sizeof(materialIds) / sizeof(int);
const int NumRecipes = sizeof(shapes) / sizeof(RowList);
Item* map[NumRecipes][NumMaterials] = {
{Item::helmet_cloth, /*Item::helmet_chain,*/ Item::helmet_iron, Item::helmet_diamond, Item::helmet_gold},
{Item::chestplate_cloth, /*Item::chestplate_chain,*/ Item::chestplate_iron, Item::chestplate_diamond, Item::chestplate_gold},
{Item::leggings_cloth, /*Item::leggings_chain,*/ Item::leggings_iron, Item::leggings_diamond, Item::leggings_gold},
{Item::boots_cloth, /*Item::boots_chain,*/ Item::boots_iron, Item::boots_diamond, Item::boots_gold},
};
//const int OVERRIDDEN_MaterialCount = 2;
for (int m = 0; m < NumMaterials; m++) {
int materialId = materialIds[m];
for (int t = 0; t < NumRecipes; t++) {
Item* target = (Item*) map[t][m];
r->addShapedRecipe( ItemInstance(target), shapes[t],
definition('X', Item::items[materialId]) );
}
}
}

View File

@@ -0,0 +1,14 @@
#ifndef NET_MINECRAFT_WORLD_ITEM_CRAFTING__ArmorRecipes_H__
#define NET_MINECRAFT_WORLD_ITEM_CRAFTING__ArmorRecipes_H__
//package net.minecraft.world.item.crafting;
class Recipes;
class ArmorRecipes
{
public:
static void addRecipes(Recipes* r);
};
#endif /*NET_MINECRAFT_WORLD_ITEM_CRAFTING__ArmorRecipes_H__*/

View File

@@ -0,0 +1,73 @@
#ifndef NET_MINECRAFT_WORLD_ITEM_CRAFTING__ClothDyeRecipes_H__
#define NET_MINECRAFT_WORLD_ITEM_CRAFTING__ClothDyeRecipes_H__
//package net.minecraft.world.item.crafting;
#include "Recipes.h"
#include "../DyePowderItem.h"
#include "../Item.h"
#include "../ItemInstance.h"
#include "../../level/tile/ClothTile.h"
#include "../../level/tile/Tile.h"
class ClothDyeRecipes
{
public:
static void addRecipes(Recipes* r){
// recipes for converting cloth to colored cloth using dye
for (int i = 0; i < 16; i++) {
if (i == DyePowderItem::BLACK
|| i == DyePowderItem::BROWN
|| i == DyePowderItem::SILVER
|| i == DyePowderItem::GRAY
|| i == DyePowderItem::WHITE)
continue;
r->addShapelessRecipe(ItemInstance(Tile::cloth, 1, ClothTile::getTileDataForItemAuxValue(i)),
definition(0, ItemInstance(Item::dye_powder, 1, i), 0, ItemInstance(Item::items[Tile::cloth->id], 1, 0)));
}
// White cloth/wool-block from any cloth block (including white...)
/*
r->addShapelessRecipe(ItemInstance(Tile::cloth, 1, 15-DyePowderItem::WHITE),
definition(0, ItemInstance(Tile::cloth, 1, Recipe::ANY_AUX_VALUE)));
*/
// some dye recipes
r->addShapelessRecipe(ItemInstance(Item::dye_powder, 2, DyePowderItem::YELLOW),
definition(0, Tile::flower));
//r->addShapelessRecipe(ItemInstance(Item::dye_powder, 2, DyePowderItem::RED),
//definition(Tile*)Tile::rose));
r->addShapelessRecipe(ItemInstance(Item::dye_powder, 3, DyePowderItem::WHITE),
definition(0, Item::bone));
r->addShapelessRecipe(ItemInstance(Item::dye_powder, 2, DyePowderItem::PINK), //
definition(0, ItemInstance(Item::dye_powder, 1, DyePowderItem::RED), 0, ItemInstance(Item::dye_powder, 1, DyePowderItem::WHITE)));
r->addShapelessRecipe(ItemInstance(Item::dye_powder, 2, DyePowderItem::ORANGE), //
definition(0, ItemInstance(Item::dye_powder, 1, DyePowderItem::RED), 0, ItemInstance(Item::dye_powder, 1, DyePowderItem::YELLOW)));
r->addShapelessRecipe(ItemInstance(Item::dye_powder, 2, DyePowderItem::LIME), //
definition(0, ItemInstance(Item::dye_powder, 1, DyePowderItem::GREEN), 0, ItemInstance(Item::dye_powder, 1, DyePowderItem::WHITE)));
// r->addShapelessRecipe(ItemInstance(Item::dye_powder, 2, DyePowderItem::GRAY), //
// definition(0, ItemInstance(Item::dye_powder, 1, DyePowderItem::BLACK), 0, ItemInstance(Item::dye_powder, 1, DyePowderItem::WHITE)));
// r->addShapelessRecipe(ItemInstance(Item::dye_powder, 2, DyePowderItem::SILVER), //
// definition(0, ItemInstance(Item::dye_powder, 1, DyePowderItem::GRAY), 0, ItemInstance(Item::dye_powder, 1, DyePowderItem::WHITE)));
// r->addShapelessRecipe(ItemInstance(Item::dye_powder, 3, DyePowderItem::SILVER), //
// definition(0, ItemInstance(Item::dye_powder, 1, DyePowderItem::BLACK), 0, ItemInstance(Item::dye_powder, 1, DyePowderItem::WHITE), 0, ItemInstance(Item::dye_powder, 1, DyePowderItem::WHITE)));
// r->addShapelessRecipe(ItemInstance(Item::dye_powder, 2, DyePowderItem::BROWN), //
// definition(0, ItemInstance(Item::dye_powder, 1, DyePowderItem::BLACK), 0, ItemInstance(Item::dye_powder, 1, DyePowderItem::ORANGE)));
// r->addShapelessRecipe(ItemInstance(Item::dye_powder, 3, DyePowderItem::BROWN), //
// definition(0, ItemInstance(Item::dye_powder, 1, DyePowderItem::BLACK), 0, ItemInstance(Item::dye_powder, 1, DyePowderItem::RED), 0, ItemInstance(Item::dye_powder, 1, DyePowderItem::YELLOW)));
r->addShapelessRecipe(ItemInstance(Item::dye_powder, 2, DyePowderItem::LIGHT_BLUE), //
definition(0, ItemInstance(Item::dye_powder, 1, DyePowderItem::BLUE), 0, ItemInstance(Item::dye_powder, 1, DyePowderItem::WHITE)));
r->addShapelessRecipe(ItemInstance(Item::dye_powder, 2, DyePowderItem::CYAN), //
definition(0, ItemInstance(Item::dye_powder, 1, DyePowderItem::BLUE), 0, ItemInstance(Item::dye_powder, 1, DyePowderItem::GREEN)));
r->addShapelessRecipe(ItemInstance(Item::dye_powder, 2, DyePowderItem::PURPLE), //
definition(0, ItemInstance(Item::dye_powder, 1, DyePowderItem::BLUE), 0, ItemInstance(Item::dye_powder, 1, DyePowderItem::RED)));
//r->addShapelessRecipe(ItemInstance(Item::dye_powder, 2, DyePowderItem::MAGENTA), //
// definition(0, ItemInstance(Item::dye_powder, 1, DyePowderItem::PURPLE), 0, ItemInstance(Item::dye_powder, 1, DyePowderItem::PINK)));
//r->addShapelessRecipe(ItemInstance(Item::dye_powder, 3, DyePowderItem::MAGENTA), //
// definition(0, ItemInstance(Item::dye_powder, 1, DyePowderItem::BLUE), 0, ItemInstance(Item::dye_powder, 1, DyePowderItem::RED), 0, ItemInstance(Item::dye_powder, 1, DyePowderItem::PINK)));
r->addShapelessRecipe(ItemInstance(Item::dye_powder, 4, DyePowderItem::MAGENTA), //
definition(0, ItemInstance(Item::dye_powder, 1, DyePowderItem::BLUE), 0, ItemInstance(Item::dye_powder, 1, DyePowderItem::RED), 0, ItemInstance(Item::dye_powder, 1, DyePowderItem::RED), 0, ItemInstance(Item::dye_powder, 1, DyePowderItem::WHITE)));
}
};
#endif /*NET_MINECRAFT_WORLD_ITEM_CRAFTING__ClothDyeRecipes_H__*/

View File

@@ -0,0 +1,54 @@
#ifndef NET_MINECRAFT_WORLD_ITEM_CRAFTING__FoodRecipes_H__
#define NET_MINECRAFT_WORLD_ITEM_CRAFTING__FoodRecipes_H__
//package net.minecraft.world.item.crafting;
#include "Recipes.h"
#include "../Item.h"
#include "../ItemInstance.h"
#include "../DyePowderItem.h"
#include "../../level/tile/Tile.h"
class FoodRecipes {
public:
static void addRecipes(Recipes* r) {
r->addShapelessRecipe(ItemInstance(Item::mushroomStew), //
definition(0, Tile::mushroom1, 0, Tile::mushroom2, 0, Item::bowl));
//r->addShapedRecipe(/*new*/ ItemInstance(Item::cookie, 8), //
// "#X#", //
// definition('X', /*new*/ ItemInstance(Item::dye_powder, 1, DyePowderItem::BROWN), '#', Item::wheat));
r->addShapedRecipe(/*new*/ ItemInstance(Tile::melon), //
"MMM", //
"MMM", //
"MMM", //
definition('M', Item::melon));
r->addShapedRecipe(/*new*/ ItemInstance(Item::seeds_melon), //
"M", //
definition('M', Item::melon));
//r->addShapedRecipe(/*new*/ ItemInstance(Item::seeds_pumpkin, 4), //
// "M", //
// definition('M', Tile::pumpkin));
//r->addShapelessRecipe(/*new*/ ItemInstance(Item::fermentedSpiderEye), //
// definition(0,Item::spiderEye, 0,Tile::mushroom1, 0,Item::sugar));
//r->addShapelessRecipe(/*new*/ ItemInstance(Item::speckledMelon), //
// definition(0,Item::melon, 0,Item::goldNugget));
//r->addShapelessRecipe(/*new*/ ItemInstance(Item::blazePowder, 2), //
// definition(0,Item::blazeRod));
//r->addShapelessRecipe(/*new*/ ItemInstance(Item::magmaCream), //
// definition(0,Item::blazePowder, 0,Item::slimeBall));
}
};
#endif /*NET_MINECRAFT_WORLD_ITEM_CRAFTING__FoodRecipes_H__*/

View File

@@ -0,0 +1,66 @@
#include "FurnaceRecipes.h"
#include "../../level/tile/Tile.h"
#include "../DyePowderItem.h"
#include "../CoalItem.h"
/*static*/
FurnaceRecipes* FurnaceRecipes::instance = NULL;
const FurnaceRecipes* FurnaceRecipes::getInstance()
{
if (!instance) instance = new FurnaceRecipes();
return instance;
}
void FurnaceRecipes::addFurnaceRecipe( int itemId, const ItemInstance& result )
{
recipes.insert(std::make_pair(itemId, result));
}
bool FurnaceRecipes::isFurnaceItem( int itemId ) const
{
return recipes.find(itemId) != recipes.end();
}
ItemInstance FurnaceRecipes::getResult( int itemId ) const
{
Map::const_iterator cit = recipes.find(itemId);
return (cit != recipes.end())? cit->second : ItemInstance();
}
const FurnaceRecipes::Map& FurnaceRecipes::getRecipes() const
{
return recipes;
}
FurnaceRecipes::FurnaceRecipes()
{
addFurnaceRecipe(Tile::ironOre->id, ItemInstance(Item::ironIngot));
addFurnaceRecipe(Tile::goldOre->id, ItemInstance(Item::goldIngot));
addFurnaceRecipe(Tile::emeraldOre->id, ItemInstance(Item::emerald));
addFurnaceRecipe(Tile::sand->id, ItemInstance(Tile::glass));
addFurnaceRecipe(Item::porkChop_raw->id,ItemInstance(Item::porkChop_cooked));
addFurnaceRecipe(Item::beef_raw->id, ItemInstance(Item::beef_cooked));
addFurnaceRecipe(Item::chicken_raw->id, ItemInstance(Item::chicken_cooked));
//addFurnaceRecipe(Item::fish_raw->id, ItemInstance(Item::fish_cooked));
addFurnaceRecipe(Tile::stoneBrick->id, ItemInstance(Tile::rock));
addFurnaceRecipe(Item::clay->id, ItemInstance(Item::brick));
addFurnaceRecipe(Tile::cactus->id, ItemInstance(Item::dye_powder, 1, DyePowderItem::GREEN));
addFurnaceRecipe(Tile::mushroom2->id, ItemInstance(Item::dye_powder, 1, DyePowderItem::RED));
addFurnaceRecipe(Tile::treeTrunk->id, ItemInstance(Item::coal, 1, CoalItem::CHAR_COAL));
addFurnaceRecipe(Tile::netherrack->id, ItemInstance(Item::netherbrick));
/*
// special silk touch related recipes:
addFurnaceRecipe(Tile::coalOre->id, ItemInstance(Item::coal));
addFurnaceRecipe(Tile::redStoneOre->id, ItemInstance(Item::redStone));
addFurnaceRecipe(Tile::lapisOre->id, ItemInstance(Item::dye_powder, 1, DyePowderItem::BLUE));
*/
}
void FurnaceRecipes::teardownFurnaceRecipes()
{
if (instance) {
delete instance;
instance = NULL;
}
}

View File

@@ -0,0 +1,33 @@
#ifndef NET_MINECRAFT_WORLD_ITEM_CRAFTING__FurnaceRecipes_H__
#define NET_MINECRAFT_WORLD_ITEM_CRAFTING__FurnaceRecipes_H__
//package net.minecraft.world.item.crafting;
#include "../ItemInstance.h"
#include <map>
class FurnaceRecipes
{
public:
typedef std::map<int, ItemInstance> Map;
static void teardownFurnaceRecipes();
static const FurnaceRecipes* getInstance();
bool isFurnaceItem(int itemId) const;
ItemInstance getResult(int itemId) const;
const Map& getRecipes() const;
private:
FurnaceRecipes();
void addFurnaceRecipe(int itemId, const ItemInstance& result);
static FurnaceRecipes* instance;
Map recipes;
};
#endif /*NET_MINECRAFT_WORLD_ITEM_CRAFTING__FurnaceRecipes_H__*/

View File

@@ -0,0 +1,45 @@
#include "OreRecipes.h"
#include "Recipes.h"
#include "../../level/tile/Tile.h"
#include "../DyePowderItem.h"
#include <utility>
void OreRecipes::addRecipes(Recipes* r)
{
typedef std::pair<Tile*, ItemInstance> Pair;
Pair map[] = {
std::make_pair(Tile::goldBlock, ItemInstance(Item::goldIngot, 9)),
std::make_pair(Tile::ironBlock, ItemInstance(Item::ironIngot, 9)),
std::make_pair(Tile::emeraldBlock, ItemInstance(Item::emerald, 9)),
std::make_pair(Tile::lapisBlock, ItemInstance(Item::dye_powder, 9, DyePowderItem::BLUE))
};
const int NumItems = sizeof(map) / sizeof(Pair);
for (int i = 0; i < NumItems; i++) {
Tile* from = map[i].first;
ItemInstance to = map[i].second;
r->addShapedRecipe(ItemInstance(from), //
"###", //
"###", //
"###", //
definition('#', to));
r->addShapedRecipe(to, //
"#", //
definition('#', from));
}
//r->addShapedRecipe(ItemInstance(Item::goldIngot), //
// "###", //
// "###", //
// "###", //
// definition('#', Item::goldNugget));
//r->addShapedRecipe(ItemInstance(Item::goldNugget, 9), //
// "#", //
// definition('#', Item::goldIngot));
}

View File

@@ -0,0 +1,14 @@
#ifndef NET_MINECRAFT_WORLD_ITEM_CRAFTING__OreRecipies_H__
#define NET_MINECRAFT_WORLD_ITEM_CRAFTING__OreRecipies_H__
//package net.minecraft.world.item.crafting;
class Recipes;
class OreRecipes
{
public:
static void addRecipes(Recipes* r);
};
#endif /*NET_MINECRAFT_WORLD_ITEM_CRAFTING__OreRecipies_H__*/

View File

@@ -0,0 +1,109 @@
#include "Recipe.h"
#include "../../../util/Mth.h"
#include "../../level/tile/Tile.h"
void ItemPack::add( int id, int count /* = 1 */ )
{
Map::iterator it = items.find(id);
if (it == items.end()) {
items.insert(std::make_pair(id, count));
} else {
it->second += count;
}
}
void ItemPack::print() const
{
Map::const_iterator it = items.begin();
while (it != items.end()) {
ItemInstance item = getItemInstanceForId(it->first);
//LOGI("> %d - %d, %d\n", it->first, item.id, item.getAuxValue());
++it;
}
}
int ItemPack::getMaxMultipliesOf( ItemPack& v ) const
{
if (v.items.empty())
return 0;
int minCount = 99;
Map::iterator it = v.items.begin();
while (it != v.items.end()) {
if (it->first <= 0) {
++it;
continue;
}
Map::const_iterator jt = items.find(it->first);
if (jt == items.end()) {
//LOGI("shotto: %d (%s) wasn't found!\n", it->first, getItemInstanceForId(it->first).toString().c_str());
return 0;
}
if (it->second == 0) {
//LOGE("getMaxMultipliesOf: Can't have count 0 of item: %d\n", it->first);
return 0;
}
int count = jt->second / it->second;
if (count == 0) return 0;
minCount = Mth::Min(minCount, count);
++it;
}
return minCount;
}
std::vector<ItemInstance> ItemPack::getItemInstances() const
{
std::vector<ItemInstance> out;
Map::const_iterator it = items.begin();
while (it != items.end()) {
int id = it->first;
int count = it->second;
ItemInstance item = getItemInstanceForId(id);
item.count = count;
out.push_back(item);
++it;
}
return out;
}
int ItemPack::getIdForItemInstance( const ItemInstance* ii )
{
bool anyAuxValue = Recipe::isAnyAuxValue(ii);
return ii->id * 512 + (anyAuxValue? -1/*Recipes::ANY_AUX_VALUE*/ : ii->getAuxValue());
}
int ItemPack::getIdForItemInstanceAnyAux( const ItemInstance* ii )
{
return ii->id * 512 - 1;
}
ItemInstance ItemPack::getItemInstanceForId( int id )
{
id += 256;
return ItemInstance(id / 512, 1, (id & 511) - 256);
}
int ItemPack::getCount( int id ) const
{
Map::const_iterator it = items.find(id);
if (it == items.end()) return 0;
return it->second;
}
/*static*/
const int Recipe::SIZE_2X2 = 0;
const int Recipe::SIZE_3X3 = 1;
bool Recipe::isAnyAuxValue( int id )
{
bool isTile = id < 256;
if (!isTile) return false;
if (id == Tile::cloth->id
|| id == Tile::stoneSlabHalf->id
|| id == Tile::sandStone->id)
return false;
return true;
}

View File

@@ -0,0 +1,61 @@
#ifndef NET_MINECRAFT_WORLD_ITEM_CRAFTING__Recipe_H__
#define NET_MINECRAFT_WORLD_ITEM_CRAFTING__Recipe_H__
//package net.minecraft.world.item.crafting;
//#include "../../inventory/CraftingContainer.h"
#include "../ItemInstance.h"
#include <map>
#include <vector>
class CraftingContainer;
class ItemPack {
public:
typedef std::map<int, int> Map;
//typedef std::vector<std::pair<int, int> > TypeCountList;
void add(int id, int count = 1);
int getCount(int id) const;
void print() const;
int getMaxMultipliesOf(ItemPack& v) const;
std::vector<ItemInstance> getItemInstances() const;
static int getIdForItemInstance(const ItemInstance* ii);
static int getIdForItemInstanceAnyAux( const ItemInstance* ii );
static ItemInstance getItemInstanceForId(int id);
private:
Map items;
};
class Recipe
{
public:
static const int SIZE_2X2;// = 0;
static const int SIZE_3X3;// = 1;
static const int ANY_AUX_VALUE = -1;
virtual ~Recipe() {}
virtual bool matches(CraftingContainer* craftSlots) = 0;
virtual const ItemPack& getItemPack() { return myItems; }
virtual int getMaxCraftCount(ItemPack& fromItems) = 0;
virtual int size() = 0;
virtual ItemInstance assemble(CraftingContainer* craftSlots) = 0;
virtual ItemInstance getResultItem() const = 0;
static bool isAnyAuxValue(const ItemInstance* ii) {
return isAnyAuxValue(ii->id);
}
virtual int getCraftingSize() = 0;
private:
static bool isAnyAuxValue(int id);
protected:
ItemPack myItems;
};
#endif /*NET_MINECRAFT_WORLD_ITEM_CRAFTING__Recipe_H__*/

View File

@@ -0,0 +1,12 @@
#ifndef NET_MINECRAFT_WORLD_ITEM_CRAFTING__RecipeCategory_H__
#define NET_MINECRAFT_WORLD_ITEM_CRAFTING__RecipeCategory_H__
enum RecipeCategory {
RCAT_TOOL,
RCAT_WEAPON,
RCAT_ARMOR,
RCAT_FOOD,
RCAT_OTHER
};
#endif /*NET_MINECRAFT_WORLD_ITEM_CRAFTING__RecipeCategory_H__*/

View File

@@ -0,0 +1,642 @@
#include "Recipes.h"
#include "ShapedRecipe.h"
#include "ShapelessRecipe.h"
#include "ClothDyeRecipes.h"
#include "ToolRecipes.h"
#include "WeaponRecipes.h"
#include "StructureRecipes.h"
#include "FoodRecipes.h"
#include "FurnaceRecipes.h"
#include "ArmorRecipes.h"
#include "OreRecipes.h"
#include "../CoalItem.h"
#include "../../level/tile/StoneSlabTile.h"
/*static*/
Recipes* Recipes::instance = NULL;
Recipes::Recipes()
{
ToolRecipes::addRecipes(this);
WeaponRecipes::addRecipes(this);
OreRecipes::addRecipes(this);
FoodRecipes::addRecipes(this);
StructureRecipes::addRecipes(this);
ArmorRecipes::addRecipes(this);
ClothDyeRecipes::addRecipes(this);
addShapedRecipe(ItemInstance(Item::paper, 3), //
"###", //
definition('#', Item::reeds));
addShapedRecipe(ItemInstance(Item::book, 1), //
"#", //
"#", //
"#", //
definition('#', Item::paper));
addShapedRecipe(ItemInstance(Tile::fence, 2), //
"###", //
"###", //
definition('#', Item::stick));
//addShapedRecipe(ItemInstance(Tile::netherFence, 6), //
// "###", //
// "###", //
// '#', Tile::netherBrick);
addShapedRecipe(ItemInstance(Tile::fenceGate, 1), //
"#W#", //
"#W#", //
definition('#', Item::stick, 'W', Tile::wood));
//addShapedRecipe(ItemInstance(Tile::recordPlayer, 1), //
// "###", //
// "#X#", //
// "###", //
// definition('#', Tile::wood, 'X', Item::emerald));
//addShapedRecipe(ItemInstance(Tile::musicBlock, 1), //
// "###", //
// "#X#", //
// "###", //
// definition('#', Tile::wood, 'X', Item::redStone));
addShapedRecipe(ItemInstance(Tile::bookshelf, 1), //
"###", //
"XXX", //
"###", //
definition('#', Tile::wood, 'X', Item::book));
addShapedRecipe(ItemInstance(Tile::snow, 1), //
"##", //
"##", //
definition('#', Item::snowBall));
addShapedRecipe(ItemInstance(Tile::clay, 1), //
"##", //
"##", //
definition('#', Item::clay));
addShapedRecipe(ItemInstance(Tile::redBrick, 1), //
"##", //
"##", //
definition('#', Item::brick));
addShapedRecipe(ItemInstance(Tile::lightGem, 1), //
"##", //
"##", //
definition('#', Item::yellowDust));
addShapedRecipe(ItemInstance(Tile::cloth, 1), //
"##", //
"##", //
definition('#', Item::string));
addShapedRecipe(ItemInstance(Tile::tnt, 1), //
"X#X", //
"#X#", //
"X#X", //
definition( 'X', Item::sulphur,
'#', Tile::sand));
addShapedRecipe(ItemInstance(Tile::stoneSlabHalf, 6, StoneSlabTile::COBBLESTONE_SLAB), //
"###", //
definition('#', Tile::stoneBrick));
addShapedRecipe(ItemInstance(Tile::stoneSlabHalf, 6, StoneSlabTile::STONE_SLAB), //
"###", //
definition('#', Tile::rock));
addShapedRecipe(ItemInstance(Tile::stoneSlabHalf, 6, StoneSlabTile::SAND_SLAB), //
"###", //
definition('#', Tile::sandStone));
addShapedRecipe(ItemInstance(Tile::stoneSlabHalf, 6, StoneSlabTile::WOOD_SLAB), //
"###", //
definition('#', Tile::wood));
addShapedRecipe(ItemInstance(Tile::stoneSlabHalf, 6, StoneSlabTile::BRICK_SLAB), //
"###", //
definition('#', Tile::redBrick));
addShapedRecipe(ItemInstance(Tile::stoneSlabHalf, 6, StoneSlabTile::SMOOTHBRICK_SLAB), //
"###", //
definition('#', Tile::stoneBrickSmooth));
addShapedRecipe(ItemInstance(Tile::ladder, 2), //
"# #", //
"###", //
"# #", //
definition('#', Item::stick));
addShapedRecipe(ItemInstance(Item::door_wood, 1), //
"##", //
"##", //
"##", //
definition('#', Tile::wood));
addShapedRecipe(ItemInstance(Tile::trapdoor, 2), //
"###", //
"###", //
definition('#', Tile::wood));
//addShapedRecipe(ItemInstance(Item::door_iron, 1), //
// "##", //
// "##", //
// "##", //
// definition('#', Item::ironIngot));
addShapedRecipe(ItemInstance(Item::sign, 1), //
"###", //
"###", //
" X ", //
definition('#', Tile::wood, 'X', Item::stick));
//addShapedRecipe(ItemInstance(Item::cake, 1), //
// "AAA", //
// "BEB", //
// "CCC", //
// definition( 'A', Item::milk,//
// 'B', Item::sugar,//
// 'C', Item::wheat, 'E', Item::egg));
addShapedRecipe(ItemInstance(Item::sugar, 1), //
"#", //
definition('#', Item::reeds));
addShapedRecipe(ItemInstance(Tile::wood, 4), //
"#", //
definition('#', Tile::treeTrunk));
addShapedRecipe(ItemInstance(Item::stick, 4), //
"#", //
"#", //
definition('#', Tile::wood));
addShapedRecipe(ItemInstance(Tile::torch, 4), //
"X", //
"#", //
definition( 'X', Item::coal,//
'#', Item::stick));
// torch made of charcoal
addShapedRecipe(ItemInstance(Tile::torch, 4), //
"X", //
"#", //
definition( 'X', ItemInstance(Item::coal, 1, CoalItem::CHAR_COAL),//
'#', Item::stick));
addShapedRecipe(ItemInstance(Item::bowl, 4), //
"# #", //
" # ", //
definition('#', Tile::wood));
//addShapedRecipe(ItemInstance(Item::glassBottle, 3), //
// "# #", //
// " # ", //
// '#', Tile::glass);
//addShapedRecipe(ItemInstance(Tile::rail, 16), //
// "X X", //
// "X#X", //
// "X X", //
// definition( 'X', Item::ironIngot,//
// '#', Item::stick));
//addShapedRecipe(ItemInstance(Tile::goldenRail, 6), //
// "X X", //
// "X#X", //
// "XRX", //
// 'X', Item::goldIngot,//
// 'R', Item::redStone,//
// '#', Item::stick);
//addShapedRecipe(ItemInstance(Tile::detectorRail, 6), //
// "X X", //
// "X#X", //
// "XRX", //
// 'X', Item::ironIngot,//
// 'R', Item::redStone,//
// '#', Tile::pressurePlate_stone);
//addShapedRecipe(ItemInstance(Item::minecart, 1), //
// "# #", //
// "###", //
// definition('#', Item::ironIngot));
//addShapedRecipe(ItemInstance(Item::cauldron, 1), //
// "# #", //
// "# #", //
// "###", //
// '#', Item::ironIngot);
//addShapedRecipe(ItemInstance(Item::brewingStand, 1), //
// " B ", //
// "###", //
// '#', Tile::stoneBrick, 'B', Item::blazeRod);
//addShapedRecipe(ItemInstance(Tile::litPumpkin, 1), //
// "A", //
// "B", //
// definition('A', Tile::pumpkin, 'B', Tile::torch));
//addShapedRecipe(ItemInstance(Item::minecart_chest, 1), //
// "A", //
// "B", //
// definition('A', Tile::chest, 'B', Item::minecart));
//addShapedRecipe(ItemInstance(Item::minecart_furnace, 1), //
// "A", //
// "B", //
// definition('A', Tile::furnace, 'B', Item::minecart));
//addShapedRecipe(ItemInstance(Item::boat, 1), //
// "# #", //
// "###", //
// definition('#', Tile::wood));
//addShapedRecipe(ItemInstance(Item::bucket_empty, 1), //
// "# #", //
// " # ", //
// definition('#', Item::ironIngot));
addShapedRecipe(ItemInstance(Item::flintAndSteel, 1), //
"A ", //
" B", //
definition('A', Item::ironIngot, 'B', Item::flint));
addShapedRecipe(ItemInstance(Item::bread, 1), //
"###", //
definition('#', Item::wheat));
addShapedRecipe(ItemInstance(Tile::stairs_wood, 4), //
"# ", //
"## ", //
"###", //
definition('#', Tile::wood));
//addShapedRecipe(ItemInstance(Item::fishingRod, 1), //
// " #", //
// " #X", //
// "# X", //
// definition('#', Item::stick, 'X', Item::string));
addShapedRecipe(ItemInstance(Tile::stairs_stone, 4), //
"# ", //
"## ", //
"###", //
definition('#', Tile::stoneBrick));
addShapedRecipe(ItemInstance(Tile::stairs_brick, 4), //
"# ", //
"## ", //
"###", //
definition('#', Tile::redBrick));
addShapedRecipe(ItemInstance(Tile::stairs_stoneBrickSmooth, 4), //
"# ", //
"## ", //
"###", //
definition('#', Tile::stoneBrickSmooth));
addShapedRecipe(ItemInstance(Tile::stairs_netherBricks, 4), //
"# ", //
"## ", //
"###", //
definition('#', Tile::netherBrick));
addShapedRecipe(ItemInstance(Item::painting, 1), //
"###", //
"#X#", //
"###", //
definition('#', Item::stick, 'X', Tile::cloth));
//addShapedRecipe(ItemInstance(Item::apple_gold, 1), //
// "###", //
// "#X#", //
// "###", //
// definition('#', Tile::goldBlock, 'X', Item::apple));
//addShapedRecipe(ItemInstance(Tile::lever, 1), //
// "X", //
// "#", //
// definition('#', Tile::stoneBrick, 'X', Item::stick));
//addShapedRecipe(ItemInstance(Tile::notGate_on, 1), //
// "X", //
// "#", //
// definition('#', Item::stick, 'X', Item::redStone));
//addShapedRecipe(ItemInstance(Item::diode, 1), //
// "#X#", //
// "III", //
// definition('#', Tile::notGate_on, 'X', Item::redStone, 'I', Tile::rock));
//addShapedRecipe(ItemInstance(Item::clock, 1), //
// " # ", //
// "#X#", //
// " # ", //
// definition('#', Item::goldIngot, 'X', Item::redStone));
//addShapedRecipe(ItemInstance(Item::compass, 1), //
// " # ", //
// "#X#", //
// " # ", //
// definition('#', Item::ironIngot, 'X', Item::redStone));
//addShapedRecipe(ItemInstance(Item::map, 1), //
// "###", //
// "#X#", //
// "###", //
// '#', Item::paper, 'X', Item::compass);
//addShapedRecipe(ItemInstance(Tile::button, 1), //
// "#", //
// "#", //
// definition('#', Tile::rock));
//addShapedRecipe(ItemInstance(Tile::pressurePlate_stone, 1), //
// "##", //
// definition('#', Tile::rock));
//addShapedRecipe(ItemInstance(Tile::pressurePlate_wood, 1), //
// "##", //
// definition('#', Tile::wood));
//addShapedRecipe(ItemInstance(Tile::dispenser, 1), //
// "###", //
// "#X#", //
// "#R#", //
// definition('#', Tile::stoneBrick, 'X', Item::bow, 'R', Item::redStone));
//addShapedRecipe(ItemInstance(Tile::pistonBase, 1), //
// "TTT", //
// "#X#", //
// "#R#", //
// '#', Tile::stoneBrick, 'X', Item::ironIngot, 'R', Item::redStone, 'T', Tile::wood);
//addShapedRecipe(ItemInstance(Tile::pistonStickyBase, 1), //
// "S", //
// "P", //
// 'S', Item::slimeBall, 'P', Tile::pistonBase);
addShapedRecipe(ItemInstance(Item::bed, 1), //
"###", //
"XXX", //
definition('#', Tile::cloth, 'X', Tile::wood));
//addShapedRecipe(ItemInstance(Tile::enchantTable, 1), //
// " B ", //
// "D#D", //
// "###", //
// '#', Tile::obsidian, 'B', Item::book, 'D', Item::emerald);
//addShapelessRecipe(ItemInstance(Item::eyeOfEnder, 1), //
// Item::enderPearl, Item::blazePowder);
addShapedRecipe(ItemInstance(Tile::netherReactor, 1), //
"X#X", //
"X#X", //
"X#X", //
definition('#', Item::emerald, 'X', Item::ironIngot));
LOGI("%d recipes\n", (int)recipes.size());
}
void Recipes::addShapedRecipe( const ItemInstance& result, const RowList& rows, const TypeList& types )
{
if (rows.empty()) {
LOGE("Recipes::addShapedRecipe: adding an empty recipe!\n");
return;
}
std::string map = "";
int width = rows[0].length();
int height = rows.size();
for (unsigned int i = 0; i < rows.size(); ++i)
map += rows[i];
typedef std::map<char, ItemInstance> Map;
Map mappings;
for (unsigned int i = 0; i < types.size(); i++) {
const Type& type = types[i];
char from = type.c;
ItemInstance to;
if (type.item) {
to = ItemInstance(type.item);
} else if (type.tile) {
to = ItemInstance(type.tile, 1, Recipe::ANY_AUX_VALUE);
} else if (!type.itemInstance.isNull()) {
to = type.itemInstance;
}
mappings.insert(std::make_pair(from, to));
}
ItemInstance* ids = new ItemInstance[width * height];
for (int i = 0; i < width * height; i++) {
char ch = map[i];
Map::iterator it = mappings.find(ch);
if (it != mappings.end())
ids[i] = it->second;
}
// <ids> are deleted in ShapedRecipe
recipes.push_back(new ShapedRecipe(width, height, ids, result));
}
void Recipes::addShapedRecipe( const ItemInstance& result, const std::string& r0, const TypeList& types) {
addShapedRecipe(result, Shape(r0), types);
}
void Recipes::addShapedRecipe( const ItemInstance& result, const std::string& r0, const std::string& r1, const TypeList& types) {
addShapedRecipe(result, Shape(r0, r1), types);
}
void Recipes::addShapedRecipe( const ItemInstance& result, const std::string& r0, const std::string& r1, const std::string& r2, const TypeList& types) {
addShapedRecipe(result, Shape(r0, r1, r2), types);
}
void Recipes::addShapelessRecipe(const ItemInstance& result, const TypeList& types) {
std::vector<ItemInstance> ingredients;
for (unsigned int i = 0; i < types.size(); i++) {
const Type& type = types[i];
if (type.item) {
ingredients.push_back( ItemInstance(type.item) );
} else if (type.tile) {
ingredients.push_back( ItemInstance(type.tile) );
} else if (!type.itemInstance.isNull()) {
ingredients.push_back( type.itemInstance );
} else {
LOGE("addShapeLessRecipe: Incorrect shapeless recipe!\n");
}
}
recipes.push_back(new ShapelessRecipe(result, ingredients));
}
RowList Recipes::Shape( const std::string& r0 ) {
RowList rows;
rows.push_back(r0);
return rows;
}
RowList Recipes::Shape( const std::string& r0, const std::string& r1 ) {
RowList rows;
rows.push_back(r0);
rows.push_back(r1);
return rows;
}
RowList Recipes::Shape( const std::string& r0, const std::string& r1, const std::string& r2 ) {
RowList rows;
rows.push_back(r0);
rows.push_back(r1);
rows.push_back(r2);
return rows;
}
Recipe* Recipes::getRecipeFor( const ItemInstance& result )
{
for (unsigned int i = 0; i < recipes.size(); ++i) {
Recipe* recipe = recipes[i];
ItemInstance res = recipe->getResultItem();
if (result.id != res.id) continue;
if ( result.count == 0 && result.getAuxValue() == res.getAuxValue()
|| (result.count == res.count && result.getAuxValue() == res.getAuxValue()))
return recipe;
}
return NULL;
}
Recipes* Recipes::getInstance()
{
if (!instance)
instance = new Recipes();
return instance;
}
void Recipes::teardownRecipes()
{
if (instance) {
delete instance;
instance = NULL;
}
FurnaceRecipes::teardownFurnaceRecipes();
}
const RecipeList& Recipes::getRecipes()
{
return recipes;
}
ItemInstance Recipes::getItemFor( CraftingContainer* craftSlots )
{
int count = 0;
ItemInstance* first;
ItemInstance* second;
for (int i = 0; i < craftSlots->getContainerSize(); i++) {
ItemInstance* item = craftSlots->getItem(i);
if (item) {
if (count == 0) first = item;
if (count == 1) second = item;
count++;
}
}
if (count == 2 && first->id == second->id && first->count == 1 && second->count == 1 && Item::items[first->id]->canBeDepleted()) {
Item* item = Item::items[first->id];
int remaining1 = item->getMaxDamage() - first->getDamageValue();
int remaining2 = item->getMaxDamage() - second->getDamageValue();
int remaining = (remaining1 + remaining2) + item->getMaxDamage() * 10 / 100;
int resultDamage = item->getMaxDamage() - remaining;
if (resultDamage < 0) resultDamage = 0;
return ItemInstance(first->id, 1, resultDamage);
}
for (unsigned int i = 0; i < recipes.size(); i++) {
Recipe* r = recipes[i];
if (r->matches(craftSlots)) return r->assemble(craftSlots);
}
return ItemInstance();
}
Recipes::~Recipes()
{
for (unsigned int i = 0; i < recipes.size(); ++i)
delete recipes[i];
}

View File

@@ -0,0 +1,98 @@
#ifndef NET_MINECRAFT_WORLD_ITEM_CRAFTING__Recipes_H__
#define NET_MINECRAFT_WORLD_ITEM_CRAFTING__Recipes_H__
//package net.minecraft.world.item.crafting;
#include "../Item.h"
#include "../../inventory/CraftingContainer.h"
#include "../../level/tile/Tile.h"
#include "Recipe.h"
typedef std::vector<std::string> RowList;
typedef std::vector<Recipe*> RecipeList;
class Recipes
{
public:
static Recipes* getInstance();
const RecipeList& getRecipes();
static void teardownRecipes();
class Type {
public:
Type(char c, Item* item)
: c(c), item(item), tile(NULL) {}
Type(char c, Tile* tile)
: c(c), item(NULL), tile(tile) {}
Type(char c, const ItemInstance& itemInstance)
: c(c), item(NULL), tile(NULL), itemInstance(itemInstance) {}
bool isItem() { return item != NULL; }
Item* item;
Tile* tile;
ItemInstance itemInstance;
char c;
} ;//Type;
typedef std::vector<Type> TypeList;
static RowList Shape(const std::string& r0);
static RowList Shape(const std::string& r0, const std::string& r1);
static RowList Shape(const std::string& r0, const std::string& r1, const std::string& r2);
void addShapedRecipe(const ItemInstance& result, const std::string& r0, const TypeList& types);
void addShapedRecipe(const ItemInstance& result, const std::string& r0, const std::string&, const TypeList& types);
void addShapedRecipe(const ItemInstance& result, const std::string& r0, const std::string& r1, const std::string& r2, const TypeList& types);
void addShapedRecipe(const ItemInstance& result, const RowList& rows, const TypeList& types);
void addShapelessRecipe(const ItemInstance& result, const TypeList& types);
Recipe* getRecipeFor(const ItemInstance& result);
private:
Recipes();
~Recipes();
ItemInstance getItemFor(CraftingContainer* craftSlots);
private:
static Recipes* instance;
RecipeList recipes;
};
template <class T>
Recipes::TypeList definition(char c0, T t) {
Recipes::TypeList list;
list.push_back(Recipes::Type(c0, t));
return list;
}
template <class T, class U>
Recipes::TypeList definition(char c0, T t, char c1, U u) {
Recipes::TypeList list;
list.push_back(Recipes::Type(c0, t));
list.push_back(Recipes::Type(c1, u));
return list;
}
template <class T, class U, class V>
Recipes::TypeList definition(char c0, T t, char c1, U u, char c2, V v) {
Recipes::TypeList list;
list.push_back(Recipes::Type(c0, t));
list.push_back(Recipes::Type(c1, u));
list.push_back(Recipes::Type(c2, v));
return list;
}
template <class T, class U, class V, class W>
Recipes::TypeList definition(char c0, T t, char c1, U u, char c2, V v, char c3, W w) {
Recipes::TypeList list;
list.push_back(Recipes::Type(c0, t));
list.push_back(Recipes::Type(c1, u));
list.push_back(Recipes::Type(c2, v));
list.push_back(Recipes::Type(c3, w));
return list;
}
#endif /*NET_MINECRAFT_WORLD_ITEM_CRAFTING__Recipes_H__*/

View File

@@ -0,0 +1,105 @@
#ifndef NET_MINECRAFT_WORLD_ITEM_CRAFTING__ShapedRecipe_H__
#define NET_MINECRAFT_WORLD_ITEM_CRAFTING__ShapedRecipe_H__
//package net.minecraft.world.item.crafting;
#include "../../inventory/CraftingContainer.h"
#include "../ItemInstance.h"
#include "Recipe.h"
class ShapedRecipe: public Recipe
{
public:
ShapedRecipe(int width, int height, ItemInstance* recipeItems, const ItemInstance& result)
: width(width),
height(height),
recipeItems(recipeItems),
resultId(result.id),
result(result)
//@todo: move slots to upper left
{
for (int i = 0; i < width * height; ++i)
if (!recipeItems[i].isNull())
myItems.add( ItemPack::getIdForItemInstance(&recipeItems[i]));
}
~ShapedRecipe() {
delete[] recipeItems;
}
int getMaxCraftCount(ItemPack& fromItems) {
int count = fromItems.getMaxMultipliesOf(myItems);
return count;
//return (int)(Mth::random() * Mth::random() * 5);
}
ItemInstance getResultItem() const {
return result;
}
bool matches(CraftingContainer* craftSlots) {
for (int xOffs = 0; xOffs <= (3 - width); xOffs++) {
for (int yOffs = 0; yOffs <= (3 - height); yOffs++) {
if (matches(craftSlots, xOffs, yOffs, true)) return true;
if (matches(craftSlots, xOffs, yOffs, false)) return true;
}
}
return false;
}
ItemInstance assemble(CraftingContainer* craftSlots) {
return ItemInstance(result.id, result.count, result.getAuxValue());
}
int size() {
return width * height;
}
virtual std::vector<ItemInstance> getItems() {
std::vector<ItemInstance> out;
return out;
}
private:
bool matches(CraftingContainer* craftSlots, int xOffs, int yOffs, bool xFlip) {
for (int x = 0; x < 3; x++) {
for (int y = 0; y < 3; y++) {
int xs = x - xOffs;
int ys = y - yOffs;
ItemInstance expected;
if (xs >= 0 && ys >= 0 && xs < width && ys < height) {
if (xFlip) expected = recipeItems[(width - xs - 1) + ys * width];
else expected = recipeItems[xs + ys * width];
}
ItemInstance* item = craftSlots->getItem(x, y);
if (!item && expected.isNull())
continue;
if ((item == NULL) ^ expected.isNull())
return false;
if (expected.id != item->id)
return false;
if (expected.getAuxValue() != Recipe::ANY_AUX_VALUE && expected.getAuxValue() != item->getAuxValue())
return false;
}
}
return true;
}
int getCraftingSize() {
return (width <= 2 && height <= 2)? SIZE_2X2 : SIZE_3X3;
}
public:
const int resultId;
private:
int width, height;
ItemInstance* recipeItems;
ItemInstance result;
//ItemPack myItems;
};
#endif /*NET_MINECRAFT_WORLD_ITEM_CRAFTING__ShapedRecipe_H__*/

View File

@@ -0,0 +1,83 @@
#ifndef NET_MINECRAFT_WORLD_ITEM_CRAFTING__ShapelessRecipe_H__
#define NET_MINECRAFT_WORLD_ITEM_CRAFTING__ShapelessRecipe_H__
//package net.minecraft.world.item.crafting;
#include "Recipe.h"
#include "../ItemInstance.h"
#include "../../inventory/CraftingContainer.h"
class ShapelessRecipe: public Recipe
{
typedef std::vector<ItemInstance> Ingredients;
public:
ShapelessRecipe(ItemInstance result, const Ingredients& ingredients)
: result(result),
ingredients(ingredients)
{
for (unsigned int i = 0; i < ingredients.size(); ++i)
if (!ingredients[i].isNull())
myItems.add( ItemPack::getIdForItemInstance(&ingredients[i]) );
}
ItemInstance getResultItem() const {
return result;
}
int getMaxCraftCount(ItemPack& fromItems) {
int count = fromItems.getMaxMultipliesOf(myItems);
return count;
//return (int)(Mth::random() * Mth::random() * 5);
}
bool matches(CraftingContainer* craftSlots) {
Ingredients tempList = ingredients;
for (int y = 0; y < 3; y++) {
for (int x = 0; x < 3; x++) {
ItemInstance* item = craftSlots->getItem(x, y);
if (item) {
bool found = false;
for (unsigned int i = 0; i < ingredients.size(); ++i) {
const ItemInstance& ingredient = ingredients[i];
if (item->id == ingredient.id && (ingredient.getAuxValue() == Recipe::ANY_AUX_VALUE || item->getAuxValue() == ingredient.getAuxValue())) {
found = true;
Ingredients::iterator it = std::find(tempList.begin(), tempList.end(), ingredient);
if (it != tempList.end())
tempList.erase(it);
break;
}
}
if (!found) {
return false;
}
}
}
}
return tempList.empty();
}
ItemInstance assemble(CraftingContainer* craftSlots) {
return result;
}
int size() {
return (int)ingredients.size();
}
int getCraftingSize() {
return (ingredients.size() > 4)? SIZE_3X3 : SIZE_2X2;
}
private:
const ItemInstance result;
const Ingredients ingredients;
//ItemPack myItems;
};
#endif /*NET_MINECRAFT_WORLD_ITEM_CRAFTING__ShapelessRecipe_H__*/

View File

@@ -0,0 +1 @@
#include "StructureRecipes.h"

View File

@@ -0,0 +1,100 @@
#ifndef NET_MINECRAFT_WORLD_ITEM_CRAFTING__StructureRecipes_H__
#define NET_MINECRAFT_WORLD_ITEM_CRAFTING__StructureRecipes_H__
//package net.minecraft.world.item.crafting;
/* import net.minecraft.world.item.* */
#include "Recipes.h"
#include "../../level/tile/Tile.h"
#include "../../level/tile/SandStoneTile.h"
#include "../../level/tile/StoneSlabTile.h"
class StructureRecipes
{
public:
static void addRecipes(Recipes* r) {
r->addShapedRecipe(ItemInstance(Tile::chest), //
"###", //
"# #", //
"###", //
definition('#', Tile::wood));
r->addShapedRecipe(ItemInstance(Tile::furnace), //
"###", //
"# #", //
"###", //
definition('#', Tile::stoneBrick));
r->addShapedRecipe(ItemInstance(Tile::workBench), //
"##", //
"##", //
definition('#', Tile::wood));
r->addShapedRecipe(ItemInstance(Tile::stonecutterBench), //
"##", //
"##", //
definition('#', Tile::stoneBrick));
r->addShapedRecipe(ItemInstance(Tile::sandStone), //
"##", //
"##", //
definition('#', Tile::sand));
r->addShapedRecipe(ItemInstance(Tile::sandStone, 4, SandStoneTile::TYPE_SMOOTHSIDE), //
"##", //
"##", //
definition('#', Tile::sandStone));
r->addShapedRecipe(ItemInstance(Tile::sandStone, 1, SandStoneTile::TYPE_HEIROGLYPHS), //
"#", //
"#", //
definition('#', ItemInstance(Tile::stoneSlabHalf, 1, StoneSlabTile::SAND_SLAB)));
r->addShapedRecipe(ItemInstance(Tile::stoneBrickSmooth, 4), //
"##", //
"##", //
definition('#', Tile::rock));
//r->addShapedRecipe(ItemInstance(Tile::ironFence, 16), //
// "###", //
// "###", //
// definition('#', Item::ironIngot));
r->addShapedRecipe(ItemInstance(Tile::thinGlass, 16), //
"###", //
"###", //
definition('#', Tile::glass));
r->addShapedRecipe(ItemInstance(Tile::netherBrick, 1), //
"NN", //
"NN", //
definition('N', Item::netherbrick));
r->addShapedRecipe(ItemInstance(Tile::quartzBlock, 1), //
"NN", //
"NN", //
definition('N', Item::netherQuartz));
//r->addShapedRecipe(ItemInstance(Tile::redstoneLight, 1), //
// " R ", //
// "RGR", //
// " R ", //
// definition('R', Item::redStone, 'G', Tile::lightGem));
}
};
#endif /*NET_MINECRAFT_WORLD_ITEM_CRAFTING__StructureRecipes_H__*/

View File

@@ -0,0 +1,59 @@
#include "ToolRecipes.h"
#include "Recipes.h"
#include "../ShearsItem.h"
#include "../../level/tile/Tile.h"
static RowList shapes[] = {
Recipes::Shape( "XXX", //
" # ",//
" # "),//
Recipes::Shape( "X",//
"#",//
"#"),//
Recipes::Shape( "XX",//
"X#",//
" #"),//
Recipes::Shape( "XX",//
" #",//
" #")//
};
void ToolRecipes::addRecipes( Recipes* r )
{
int materialIds[] = {Tile::wood->id, Tile::stoneBrick->id, Item::ironIngot->id, Item::emerald->id, Item::goldIngot->id};
const int NumMaterials = sizeof(materialIds) / sizeof(int);
const int NumRecipes = sizeof(shapes) / sizeof(RowList);
Item* map[NumRecipes][NumMaterials] = {
{Item::pickAxe_wood, Item::pickAxe_stone, Item::pickAxe_iron, Item::pickAxe_emerald, Item::pickAxe_gold},
{Item::shovel_wood, Item::shovel_stone, Item::shovel_iron, Item::shovel_emerald, Item::shovel_gold},
{Item::hatchet_wood, Item::hatchet_stone, Item::hatchet_iron, Item::hatchet_emerald, Item::hatchet_gold},
{Item::hoe_wood, Item::hoe_stone, Item::hoe_iron, Item::hoe_emerald, Item::hoe_gold},
};
//const int OVERRIDDEN_MaterialCount = 2;
for (int m = 0; m < NumMaterials; m++) {
int mId = materialIds[m];
for (int t = 0; t < NumRecipes; t++) {
Item* target = (Item*) map[t][m];
if (mId < 256) { // Tile
r->addShapedRecipe( ItemInstance(target), shapes[t],
definition('#', Item::stick, 'X', Tile::tiles[mId]) );
} else { // Item
r->addShapedRecipe( ItemInstance(target), shapes[t],
definition('#', Item::stick, 'X', Item::items[mId]) );
}
}
}
r->addShapedRecipe( ItemInstance(Item::shears), //
" #", //
"# ", //
definition('#', Item::ironIngot));
}

View File

@@ -0,0 +1,14 @@
#ifndef NET_MINECRAFT_WORLD_ITEM_CRAFTING__ToolRecipes_H__
#define NET_MINECRAFT_WORLD_ITEM_CRAFTING__ToolRecipes_H__
//package net.minecraft.world.item.crafting;
class Recipes;
class ToolRecipes
{
public:
static void addRecipes(Recipes* r);
};
#endif /*NET_MINECRAFT_WORLD_ITEM_CRAFTING__ToolRecipes_H__*/

View File

@@ -0,0 +1,49 @@
#include "WeaponRecipes.h"
static RowList shapes[] = {
Recipes::Shape( "X", //
"X",//
"#"),//
};
void WeaponRecipes::addRecipes( Recipes* r )
{
int materialIds[] = {Tile::wood->id, Tile::stoneBrick->id, Item::ironIngot->id, Item::emerald->id, Item::goldIngot->id};
const int NumMaterials = sizeof(materialIds) / sizeof(int);
const int NumRecipes = sizeof(shapes) / sizeof(RowList);
Item* map[NumRecipes][NumMaterials] = {
{Item::sword_wood, Item::sword_stone, Item::sword_iron, Item::sword_emerald, Item::sword_gold},
};
//const int OVERRIDDEN_MaterialCount = 2;
for (int m = 0; m < NumMaterials; m++) {
int mId = materialIds[m];
for (int t = 0; t < NumRecipes; t++) {
Item* target = (Item*) map[t][m];
if (mId < 256) { // Tile
r->addShapedRecipe( ItemInstance(target), shapes[t],
definition('#', Item::stick, 'X', Tile::tiles[mId]) );
} else { // Item
r->addShapedRecipe( ItemInstance(target), shapes[t],
definition('#', Item::stick, 'X', Item::items[mId]) );
}
}
}
r->addShapedRecipe(ItemInstance(Item::bow, 1), //
" #X", //
"# X", //
" #X", //
definition( 'X', Item::string,//
'#', Item::stick));
r->addShapedRecipe(ItemInstance(Item::arrow, 4), //
"X", //
"#", //
"Y", //
definition( 'Y', Item::feather,//
'X', Item::flint,//
'#', Item::stick));
}

View File

@@ -0,0 +1,15 @@
#ifndef NET_MINECRAFT_WORLD_ITEM_CRAFTING__WeaponRecipes_H__
#define NET_MINECRAFT_WORLD_ITEM_CRAFTING__WeaponRecipes_H__
//package net.minecraft.world.item.crafting;
#include "Recipes.h"
#include "../../level/tile/Tile.h"
class WeaponRecipes
{
public:
static void addRecipes( Recipes* r );
};
#endif /*NET_MINECRAFT_WORLD_ITEM_CRAFTING__WeaponRecipes_H__*/