package joshie.harvest.cooking.tile; import joshie.harvest.api.HFApi; import joshie.harvest.api.cooking.Utensil; import joshie.harvest.cooking.CookingHelper.PlaceIngredientResult; import joshie.harvest.core.HFTrackers; import joshie.harvest.core.achievements.HFAchievements; import joshie.harvest.core.base.tile.TileFaceable; import joshie.harvest.core.entity.EntityBasket; import joshie.harvest.core.helpers.MCServerHelper; import joshie.harvest.core.helpers.NBTHelper; import joshie.harvest.core.helpers.SpawnItemHelper; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.item.ItemStack; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import net.minecraft.network.NetworkManager; import net.minecraft.network.play.server.SPacketUpdateTileEntity; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.ITickable; import javax.annotation.Nonnull; import java.util.ArrayList; import java.util.List; import static joshie.harvest.cooking.CookingHelper.PlaceIngredientResult.SUCCESS; public abstract class TileCooking extends TileFaceable { public static final String IN_UTENSIL = "InUtensil"; public abstract static class TileCookingTicking extends TileCooking implements ITickable { @Override public void update() { super.update(); } } private static final int COOK_TIMER = 100; private boolean cooking; private short cookTimer = 0; private ArrayList<ItemStack> ingredients = new ArrayList<>(); protected List<ItemStack> result = new ArrayList<>(); private int last; public final float[] rotations = new float[20]; public final float[] offset1 = new float[20]; public final float[] offset2 = new float[20]; public final float[] heightOffset = new float[20]; public TileCooking() {} public abstract Utensil getUtensil(); public boolean isCooking() { return cooking; } int getCookTimer() { return cookTimer; } public PlaceIngredientResult hasPrerequisites() { return SUCCESS; } public boolean isFinishedCooking() { return result.size() > 0; } public List<ItemStack> getResult() { return result; } public List<ItemStack> getIngredients() { return ingredients; } //reset everything ready for the next cooking batch public void giveToPlayer(EntityPlayer player) { List<ItemStack> theItems = getResult(); EntityBasket.findBasketAndShip(player, theItems); for (ItemStack theItem: theItems) { if (theItem.hasTagCompound()) { player.addStat(HFAchievements.cooking); } HFTrackers.getPlayerTrackerFromPlayer(player).getTracking().addAsObtained(theItem); SpawnItemHelper.addToPlayerInventory(player, theItem); } result.clear(); //Clear out the result } @SuppressWarnings("ConstantConditions") public void takeBackLastStack(EntityPlayer player) { if (ingredients.size() > 0) { ItemStack stack = ingredients.get(ingredients.size() - 1); if (stack.hasTagCompound()) stack.getTagCompound().removeTag(IN_UTENSIL); if (stack.hasTagCompound() && stack.getTagCompound().hasNoTags()) { stack.setTagCompound(null); } SpawnItemHelper.addToPlayerInventory(player, stack); ingredients.remove(ingredients.size() - 1); //Remove the last stack if (worldObj.isRemote) return; this.last = this.ingredients.size(); this.cooking = true; this.cookTimer = 0; this.markDirty(); } } public void animate() {} public short getCookingTime() { return COOK_TIMER; } public void update() { if (isCooking()) animate(); //If we are server side perform the actions if (!worldObj.isRemote) { if (cooking) { cookTimer++; if (ingredients.size() == 0) { cooking = false; markDirty(); } else if (cookTimer >= getCookingTime()) { result.addAll(HFApi.cooking.getCookingResult(getUtensil(), ingredients)); cooking = false; ingredients = new ArrayList<>(); cookTimer = 0; markDirty(); } if (hasPrerequisites() != SUCCESS) { cooking = false; this.markDirty(); } } } } //Returns true if this was a valid ingredient to add @SuppressWarnings("ConstantConditions") public boolean addIngredient(ItemStack stack) { if (ingredients.size() >= 20) return false; if (hasPrerequisites() != SUCCESS) return false; if (!HFApi.cooking.isIngredient(stack)) return false; else { if (worldObj.isRemote) return true; ItemStack clone = stack.copy(); clone.stackSize = 1; if (!clone.hasTagCompound()) { clone.setTagCompound(new NBTTagCompound()); } clone.getTagCompound().setBoolean(IN_UTENSIL, true); this.last = this.ingredients.size(); this.ingredients.add(clone); this.cooking = true; this.cookTimer = 0; this.markDirty(); return true; } } //Called Clientside to update the client @Override public void onDataPacket(NetworkManager net, SPacketUpdateTileEntity packet) { super.onDataPacket(net, packet); //Update the renderer doRenderUpdate(); } @Override public void handleUpdateTag(@Nonnull NBTTagCompound tag) { super.handleUpdateTag(tag); //Updated the renderer doRenderUpdate(); } protected void doRenderUpdate() { if (cooking) { rotations[last] = worldObj.rand.nextFloat() * 360F; offset1[last] = 0.5F - worldObj.rand.nextFloat(); offset2[last] = worldObj.rand.nextFloat() / 1.75F; heightOffset[last] = 0.5F + (ingredients.size() * 0.001F); } worldObj.markBlockRangeForRenderUpdate(getPos(), getPos()); } @Override public void markDirty() { if (!worldObj.isRemote) { MCServerHelper.markForUpdate(worldObj, getPos()); MCServerHelper.markForUpdate(worldObj, getPos().down()); } super.markDirty(); } @Override public void readFromNBT(NBTTagCompound nbt) { super.readFromNBT(nbt); cooking = nbt.getBoolean("IsCooking"); cookTimer = nbt.getShort("CookingTimer"); last = nbt.getByte("Last"); ingredients = new ArrayList<>(); if (nbt.hasKey("IngredientsInside")) { NBTTagList is = nbt.getTagList("IngredientsInside", 10); for (int i = 0; i < is.tagCount(); i++) { ingredients.add(NBTHelper.readItemStack(is.getCompoundTagAt(i))); } } //Resulting item result = new ArrayList<>(); if (nbt.hasKey("Result")) { NBTTagList is = nbt.getTagList("Result", 10); for (int i = 0; i < is.tagCount(); i++) { result.add(NBTHelper.readItemStack(is.getCompoundTagAt(i))); } } } @Override @Nonnull public NBTTagCompound writeToNBT(@Nonnull NBTTagCompound nbt) { nbt.setBoolean("IsCooking", cooking); nbt.setShort("CookingTimer", cookTimer); nbt.setByte("Last", (byte) last); //Write out the saved Ingredients if (ingredients.size() > 0) { NBTTagList is = new NBTTagList(); for (ItemStack ingredient : ingredients) { is.appendTag(NBTHelper.writeItemStack(ingredient, new NBTTagCompound())); } nbt.setTag("IngredientsInside", is); } //Write out the result items if (result.size() > 0) { NBTTagList is = new NBTTagList(); for (ItemStack ingredient : result) { is.appendTag(NBTHelper.writeItemStack(ingredient, new NBTTagCompound())); } nbt.setTag("Result", is); } return super.writeToNBT(nbt); } boolean isAbove(Utensil utensil) { TileEntity tile = worldObj.getTileEntity(pos.down()); return tile instanceof TileCooking && ((TileCooking)tile).getUtensil() == utensil; } }