tcr/java/src/game/item/Item.java

671 lines
17 KiB
Java
Raw Normal View History

2025-03-11 00:23:54 +01:00
package game.item;
import java.util.List;
import java.util.Map;
import java.util.Set;
import game.collect.Maps;
import game.collect.Sets;
2025-03-16 17:40:47 +01:00
2025-03-11 00:23:54 +01:00
import game.block.Block;
import game.color.TextColor;
import game.entity.attributes.Attribute;
import game.entity.attributes.AttributeModifier;
import game.entity.npc.EntityNPC;
import game.entity.types.EntityLiving;
import game.nbt.NBTTagCompound;
import game.renderer.ItemMeshDefinition;
import game.renderer.blockmodel.ModelBlock;
import game.renderer.blockmodel.Transforms;
import game.rng.Random;
import game.util.ExtMath;
2025-03-11 00:23:54 +01:00
import game.world.BlockPos;
import game.world.Facing;
import game.world.HitPosition;
import game.world.Vec3;
import game.world.World;
public class Item
{
protected static final Random itemRand = new Random();
protected int maxStackSize = 64;
private int maxDamage;
protected boolean hasSubtypes;
private Item containerItem;
private String potionEffect;
private String display;
private CheatTab tabToDisplayOn;
private TextColor color = null;
public Item setMaxStackSize(int maxStackSize)
{
this.maxStackSize = maxStackSize;
return this;
}
public Item setHasSubtypes(boolean hasSubtypes)
{
this.hasSubtypes = hasSubtypes;
return this;
}
/**
* set max damage of an Item
*/
public Item setMaxDamage(int maxDamageIn)
{
this.maxDamage = maxDamageIn;
return this;
}
public Item setDisplay(String name)
{
this.display = name;
return this;
}
public Item setContainerItem(Item containerItem)
{
this.containerItem = containerItem;
return this;
}
/**
* Sets the string representing this item's effect on a potion when used as an ingredient.
*/
public Item setPotionEffect(String potionEffect)
{
this.potionEffect = potionEffect;
return this;
}
/**
* returns this;
*/
public Item setTab(CheatTab tab)
{
this.tabToDisplayOn = tab;
return this;
}
public Item setColor(TextColor color)
{
this.color = color;
return this;
}
public Block getBlock()
{
return null;
}
/**
* Called when an ItemStack with NBT data is read to potentially that ItemStack's NBT data
*/
public boolean updateItemStackNBT(NBTTagCompound nbt)
{
return false;
}
/**
* Called when a Block is right-clicked with this Item
*/
public boolean onItemUse(ItemStack stack, EntityNPC playerIn, World worldIn, BlockPos pos, Facing side, float hitX, float hitY, float hitZ)
{
return false;
}
public boolean onAction(ItemStack stack, EntityNPC player, World world, ItemControl control, BlockPos block) {
return false;
}
public float getStrVsBlock(ItemStack stack, Block state)
{
return 1.0F;
}
/**
* Called whenever this item is equipped and the right mouse button is pressed. Args: itemStack, world, entityPlayer
*/
public ItemStack onItemRightClick(ItemStack itemStackIn, World worldIn, EntityNPC playerIn)
{
return itemStackIn;
}
/**
* Called when the player finishes using this Item (E.g. finishes eating.). Not called when the player stops using
* the Item before the action is complete.
*/
public ItemStack onItemUseFinish(ItemStack stack, World worldIn, EntityNPC playerIn)
{
return stack;
}
/**
* Returns the maximum size of the stack for a specific item. *Isn't this more a Set than a Get?*
*/
public int getItemStackLimit()
{
return this.maxStackSize;
}
/**
* Converts the given ItemStack damage value into a metadata value to be placed in the world when this Item is
* placed as a Block (mostly used with ItemBlocks).
*/
public int getMetadata(int damage)
{
return 0;
}
public boolean getHasSubtypes()
{
return this.hasSubtypes;
}
/**
* Returns the maximum damage an item can take.
*/
public int getMaxDamage()
{
return this.maxDamage;
}
public boolean isDamageable()
{
return this.maxDamage > 0 && !this.hasSubtypes;
}
/**
* Current implementations of this method in child classes do not use the entry argument beside ev. They just raise
* the damage on the stack.
*/
public boolean hitEntity(ItemStack stack, EntityLiving target, EntityLiving attacker)
{
return false;
}
/**
* Called when a Block is destroyed using this Item. Return true to trigger the "Use Item" statistic.
*/
public boolean onBlockDestroyed(ItemStack stack, World worldIn, Block blockIn, BlockPos pos, EntityLiving playerIn)
{
return false;
}
/**
* Check whether this Item can harvest the given Block
*/
public boolean canHarvestBlock(Block blockIn)
{
return false;
}
/**
* Returns true if the item can be used on the given entity, e.g. shears on sheep.
*/
public boolean itemInteractionForEntity(ItemStack stack, EntityNPC playerIn, EntityLiving target)
{
return false;
}
// public String getUnlocalizedNameInefficiently(ItemStack stack)
// {
// String s = this.getUnlocalizedName(stack);
// return s == null ? "" : s; // I18n.translate(s);
// }
// /**
// * Returns the unlocalized name of this item.
// */
// public String getUnlocalizedName()
// {
// return "item." + this.unlocalizedName;
// }
public String getDisplay(ItemStack stack)
{
return this.display;
}
/**
* If this function returns true (or the item is damageable), the ItemStack's NBT tag will be sent to the client.
*/
public boolean getShareTag()
{
return true;
}
public Item getContainerItem()
{
return this.containerItem;
}
/**
* True if this Item has a container item (a.k.a. crafting result)
*/
public boolean hasContainerItem()
{
return this.containerItem != null;
}
public int getColorFromItemStack(ItemStack stack, int renderPass)
{
return 16777215;
}
// /**
// * Called each tick as long the item is on a player inventory. Uses by maps to check if is on a player hand and
// * update it's contents.
// */
// public void onUpdate(ItemStack stack, World worldIn, Entity entityIn, int itemSlot, boolean isSelected)
// {
// }
//
// /**
// * Called when item is crafted/smelted. Used only by maps so far.
// */
// public void onCreated(ItemStack stack, World worldIn, EntityNPC playerIn)
// {
// }
/**
* returns the action that specifies what animation to play when the items is being used
*/
public ItemAction getItemUseAction(ItemStack stack)
{
return ItemAction.NONE;
}
public ItemAction getItemPosition(ItemStack stack)
{
return ItemAction.NONE;
}
/**
* How long it takes to use or consume an item
*/
public int getMaxItemUseDuration(ItemStack stack)
{
return 0;
}
/**
* Called when the player stops using an Item (stops holding the right mouse button).
*/
public void onPlayerStoppedUsing(ItemStack stack, World worldIn, EntityNPC playerIn, int timeLeft)
{
}
public String getPotionEffect(ItemStack stack)
{
return this.potionEffect;
}
public boolean isPotionIngredient(ItemStack stack)
{
return this.getPotionEffect(stack) != null;
}
/**
* allows items to add custom lines of information to the mouseover description
*/
public void addInformation(ItemStack stack, EntityNPC playerIn, List<String> tooltip)
{
}
// public String getItemStackDisplayName(ItemStack stack)
// {
// return this.getUnlocalizedName(stack);
// }
public boolean hasEffect(ItemStack stack)
{
return stack.isItemEnchanted();
}
public TextColor getColor(ItemStack stack)
{
return this.color != null ? this.color : (stack.isItemEnchanted() ? TextColor.NEON : TextColor.WHITE);
}
/**
* Checks isDamagable and if it cannot be stacked
*/
public boolean isItemTool(ItemStack stack)
{
return this.getItemStackLimit() == 1 && this.isDamageable();
}
protected HitPosition getMovingObjectPositionFromPlayer(World worldIn, EntityNPC playerIn, boolean useLiquids)
{
float f = playerIn.rotPitch;
float f1 = playerIn.rotYaw;
double d0 = playerIn.posX;
double d1 = playerIn.posY + (double)playerIn.getEyeHeight();
double d2 = playerIn.posZ;
Vec3 vec3 = new Vec3(d0, d1, d2);
float f2 = ExtMath.cos(-f1 * 0.017453292F - (float)Math.PI);
float f3 = ExtMath.sin(-f1 * 0.017453292F - (float)Math.PI);
float f4 = -ExtMath.cos(-f * 0.017453292F);
float f5 = ExtMath.sin(-f * 0.017453292F);
float f6 = f3 * f4;
float f7 = f2 * f4;
double d3 = 5.0D;
Vec3 vec31 = vec3.addVector((double)f6 * d3, (double)f5 * d3, (double)f7 * d3);
return worldIn.rayTraceBlocks(vec3, vec31, useLiquids, !useLiquids, false);
}
/**
* Return the enchantability factor of the item, most of the time is based on material.
*/
public int getItemEnchantability()
{
return 0;
}
/**
* returns a list of items with the same ID, but different meta (eg: dye returns 16 items)
*/
public void getSubItems(Item itemIn, CheatTab tab, List<ItemStack> subItems)
{
subItems.add(new ItemStack(itemIn, 1, 0));
}
/**
* gets the tab this item is displayed on
*/
public CheatTab getTab()
{
return this.tabToDisplayOn;
}
// public boolean canItemEditBlocks()
// {
// return false;
// }
/**
* Return whether this item is repairable in an anvil.
*/
public boolean getIsRepairable(ItemStack toRepair, ItemStack repair)
{
return false;
}
public Map<Attribute, Set<AttributeModifier>> getItemAttributeModifiers()
{
return Maps.newHashMap();
}
public Map<Attribute, Set<AttributeModifier>> getItemInventoryModifiers()
{
return Maps.newHashMap();
}
// public boolean canBeDyed() {
// return false;
// }
public boolean isFragile() {
return false;
}
// public boolean isValidMeta(int meta) {
// return true; // meta == 0;
// }
//
// public int getDefaultMeta() {
// return 0;
// }
public final Set<String> getValidTags() {
return Sets.newHashSet();
}
// private static final Set<String> VALID_TAGS = Sets.newHashSet("Name", "ench", "RepairCost");
protected final boolean validateNbt(NBTTagCompound tag) {
return true;
}
// private final boolean isValidNbt(ItemStack stack) {
// if(!stack.hasTagCompound()) {
// return true;
// }
// NBTTagCompound tag = stack.getTagCompound();
// if(tag.hasNoTags()) {
// return false;
// }
// Set<String> keys = tag.getKeySet();
// int z = keys.size();
// boolean validate = false;
// if(z > 0) {
// for(String v : VALID_TAGS) {
// if(keys.contains(v)) {
// z--;
// if(z == 0) {
// break;
// }
// }
// }
// }
//// if(adv && z > 0) {
////// for(String v : ADV_TAGS) {
//// if(keys.contains("Unbreakable")) {
//// z--;
////// if(z == 0) {
////// break;
////// }
//// }
////// }
//// }
// if(z > 0) {
// for(String v : this.getValidTags()) {
// if(keys.contains(v)) {
// validate = true;
// z--;
// if(z == 0) {
// break;
// }
// }
// }
// }
// if(z > 0) {
// return false;
// }
//// if(tag.hasKey("display")) {
//// if(!tag.hasKey("display", 10)) {
//// return false;
//// }
//// NBTTagCompound display = tag.getCompoundTag("display");
//// keys = display.getKeySet();
//// z = keys.size();
// if(tag.hasKey("Name")) {
// if(!tag.hasKey("Name", 8)) {
// return false;
// }
// if(tag.getString("Name").length() > 64) {
// return false;
// }
//// z--;
// }
//// if(display.hasKey("Lore")) {
//// if(!adv) {
//// display.removeTag("Lore");
//// if(display.hasNoTags()) {
//// tag.removeTag("display");
//// if(tag.hasNoTags()) {
//// stack.setTagCompound(null);
//// return true;
//// }
//// }
//// }
//// else {
//// if(!display.hasKey("Lore", 9)) {
//// return false;
//// }
//// NBTTagList lore = display.getTagList("Lore", 8);
//// if(lore.hasNoTags()) {
//// return false;
//// }
//// }
//// z--;
//// }
//// if(display.hasKey("color")) {
//// if(!display.hasKey("color", 3)) {
//// return false;
//// }
//// if(!this.canBeDyed()) {
//// return false;
//// }
//// z--;
//// }
//// if(z > 0) {
//// return false;
//// }
//// }
// if(tag.hasKey("RepairCost")) {
// if(!tag.hasKey("RepairCost", 3)) {
// return false;
// }
// if(tag.getInteger("RepairCost") < 1) {
// return false;
// }
// }
// if(tag.hasKey("ench")) {
// if(!tag.hasKey("ench", 9)) {
// return false;
// }
// NBTTagList ench = tag.getTagList("ench", 10);
// if(ench.hasNoTags()) {
// return false;
// }
// if(ench.tagCount() > Enchantment.getNames().size()) {
// return false;
// }
// Enchantment[] ecn = new Enchantment[ench.tagCount()];
// for(int e = 0; e < ench.tagCount(); e++) {
// NBTTagCompound ec = ench.getCompoundTagAt(e);
// if(ec.getKeySet().size() != 2 || !ec.hasKey("id", 2) || !ec.hasKey("lvl", 2)) {
// return false;
// }
// int id = ec.getShort("id");
// int lvl = ec.getShort("lvl");
// Enchantment en = Enchantment.getEnchantmentById(id);
// if(en == null) {
// return false;
// }
//// if(!adv && (lvl < en.getMinLevel() || lvl > en.getMaxLevel())) {
//// return false;
//// }
//// if(!adv && !en.canApply(stack)) {
//// return false;
//// }
// ecn[e] = en;
// }
// for(int e = 0; e < ecn.length; e++) {
// for(int f = 0; f < ecn.length; f++) {
// if(f != e && ecn[e] == ecn[f]) {
// return false;
// }
// }
// }
// }
//// if(adv) {
//// if(tag.hasKey("Unbreakable")) {
//// if(!tag.hasKey("Unbreakable", 1)) {
//// return false;
//// }
//// }
//// if(tag.hasKey("HideFlags")) {
//// if(!tag.hasKey("HideFlags", 3)) {
//// return false;
//// }
//// }
//// }
// if(validate) {
// if(this.validateNbt(stack.getTagCompound())) {
// if(tag.hasNoTags()) {
// stack.setTagCompound(null);
// }
// }
// else {
// return false;
// }
// }
// return true;
// }
// boolean validate(ItemStack stack) {
//// if(!bypass && this.isSpecialItem()) {
//// return false;
//// }
// boolean flag = true;
// if(this.isDamageable() && (stack.getItemDamage() < 0 || (stack.getItemDamage() > this.getMaxDamage()))) {
// stack.setItemDamage(0);
// flag = false;
// }
// if(stack.stackSize > stack.getMaxStackSize()) {
// stack.stackSize = stack.getMaxStackSize();
// flag = false;
// }
// else if(stack.stackSize < 1) {
// stack.stackSize = 1;
// flag = false;
// }
// if(!this.isValidNbt(stack)) {
// stack.setTagCompound(null);
// flag = false;
// }
// return flag;
// }
// public boolean canBreakBlocks() {
// return true;
// }
//
// public boolean canUseInAir() {
// return false;
// }
//
// public boolean ignoresBlocks() {
// return false;
// }
public float getRadiation(ItemStack stack) {
return 0.0f;
}
public boolean isMagnetic() {
return false;
}
public boolean isFirstPerson() {
return true;
}
public String getHotbarText(EntityNPC player, ItemStack stack) {
return stack.getColoredName();
}
public Transforms getTransform() {
return Transforms.ITEM;
}
public ModelBlock getModel(String name, int meta) {
return new ModelBlock(this.getTransform(), name);
}
public ItemMeshDefinition getMesher() {
return null;
}
public void getRenderItems(Item itemIn, List<ItemStack> subItems) {
this.getSubItems(itemIn, null, subItems);
}
}