Package org.spout.vanilla.component.block.material

Source Code of org.spout.vanilla.component.block.material.Furnace

/*
* This file is part of Vanilla.
*
* Copyright (c) 2011 Spout LLC <http://www.spout.org/>
* Vanilla is licensed under the Spout License Version 1.
*
* Vanilla is free software: you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option)
* any later version.
*
* In addition, 180 days after any changes are published, you can use the
* software, incorporating those changes, under the terms of the MIT license,
* as described in the Spout License Version 1.
*
* Vanilla is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
* more details.
*
* You should have received a copy of the GNU Lesser General Public License,
* the MIT license and the Spout License Version 1 along with this program.
* If not, see <http://www.gnu.org/licenses/> for the GNU Lesser General Public
* License and see <http://spout.in/licensev1> for the full license, including
* the MIT license.
*/
package org.spout.vanilla.component.block.material;

import org.spout.api.entity.Player;
import org.spout.api.event.cause.MaterialCause;
import org.spout.api.inventory.Container;
import org.spout.api.inventory.ItemStack;

import org.spout.vanilla.VanillaPlugin;
import org.spout.vanilla.component.block.ViewedBlockComponent;
import org.spout.vanilla.component.entity.inventory.WindowHolder;
import org.spout.vanilla.data.VanillaData;
import org.spout.vanilla.event.inventory.FurnaceCloseEvent;
import org.spout.vanilla.event.inventory.FurnaceOpenEvent;
import org.spout.vanilla.event.material.FurnaceBurnEvent;
import org.spout.vanilla.event.material.FurnaceSmeltEvent;
import org.spout.vanilla.inventory.block.FurnaceInventory;
import org.spout.vanilla.inventory.window.block.FurnaceWindow;
import org.spout.vanilla.inventory.window.prop.FurnaceProperty;
import org.spout.vanilla.material.Fuel;
import org.spout.vanilla.material.TimedCraftable;
import org.spout.vanilla.material.VanillaMaterials;

/**
* Represents a furnace in a world.
*/
public class Furnace extends ViewedBlockComponent implements Container {
  public static final float MAX_FUEL_INCREMENT = 12.5f;
  public static final float MAX_SMELT_TIME_INCREMENT = 9f;

  /**
   * Retrieve the maximum time to smelt something.
   *
   * @return The maximum time to smelt.
   */
  public float getMaxSmeltTime() {
    return getData().get(VanillaData.MAX_SMELT_TIME);
  }

  /**
   * Sets the maximum amount of time to smelt something.
   *
   * @param maxSmeltTime The maximum time to smelt.
   */
  public void setMaxSmeltTime(float maxSmeltTime) {
    getData().put(VanillaData.MAX_SMELT_TIME, maxSmeltTime);
  }

  /**
   * Retrieve the current smelting time.
   *
   * @return The current smelting time.
   */
  public float getSmeltTime() {
    return getData().get(VanillaData.SMELT_TIME);
  }

  /**
   * Sets the current smelting time.
   *
   * @param smeltTime The current smelting time.
   */
  public void setSmeltTime(float smeltTime) {
    getData().put(VanillaData.SMELT_TIME, smeltTime);
    for (Player player : viewers) {
      updateProgressArrow(player);
    }
  }

  private void updateProgressArrow(Player player) {
    WindowHolder window = player.get(WindowHolder.class);
    if (window != null) {
      float increment = 0.0f;
      if (canSmelt()) {
        float maxSmeltTime = getMaxSmeltTime();
        increment = (MAX_SMELT_TIME_INCREMENT * 20) - ((MAX_SMELT_TIME_INCREMENT / maxSmeltTime) * (getSmeltTime() * 20));
      }
      window.getActiveWindow().setProperty(FurnaceProperty.PROGRESS_ARROW, (int) increment);
    }
  }

  /**
   * Retrieve the maximum fuel amount currently set in the furnace.
   *
   * @return The max fuel amount.
   */
  //TODO: Better description anyone?
  public float getMaxFuel() {
    return getData().get(VanillaData.MAX_FURNACE_FUEL);
  }

  /**
   * Sets the maximum amount of fuel this furnace can hold.
   *
   * @param maxFuel The maximum amount of fuel.
   */
  public void setMaxFuel(float maxFuel) {
    getData().put(VanillaData.MAX_FURNACE_FUEL, maxFuel);
  }

  /**
   * Retrieve the current amount of fuel in this furnace.
   *
   * @return The current amount of fuel.
   */
  public float getFuel() {
    return getData().get(VanillaData.FURNACE_FUEL);
  }

  /**
   * Set the current amount of fuel in this furnace.
   *
   * @param fuel The current amount of fuel.
   */
  public void setFuel(float fuel) {
    getData().put(VanillaData.FURNACE_FUEL, fuel);
    for (Player player : viewers) {
      updateFireIcon(player);
    }
  }

  private void updateFireIcon(Player player) {
    WindowHolder window = player.get(WindowHolder.class);
    if (window != null) {
      // (12.5 / maximum time from fuel source) * (fuel seconds left * 20) = increment to send to client
      float maxFuel = getMaxFuel();
      float increment = MAX_FUEL_INCREMENT / maxFuel * (getFuel() * 20);
      window.getActiveWindow().setProperty(FurnaceProperty.FIRE_ICON, (int) increment);
    }
  }

  public void pulseFuel(float dt) {
    setFuel(getFuel() - dt);
  }

  public void pulseSmeltTime(float dt) {
    setSmeltTime(getSmeltTime() - dt);
  }

  /**
   * Check if all the criteria for smelting is met.
   *
   * @return True if smelting can happen else false.
   */
  public boolean canSmelt() {
    FurnaceInventory inventory = getInventory();
    ItemStack output = inventory.getOutput();
    return inventory.hasIngredient() && (output == null || output.getMaterial() == ((TimedCraftable) inventory.getIngredient().getMaterial()).getResult().getMaterial());
  }

  /**
   * Activate the smelting process.
   */
  public void smelt() {
    FurnaceInventory inventory = getInventory();
    if (!inventory.hasIngredient()) {
      return;
    }
    ItemStack ingredient = inventory.getIngredient();
    ItemStack result = ((TimedCraftable) ingredient.getMaterial()).getResult();
    FurnaceSmeltEvent event = VanillaPlugin.getInstance().getEngine().getEventManager().callEvent(new FurnaceSmeltEvent(this, new MaterialCause(ingredient.getMaterial(), this.getBlock()), ingredient, result));
    if (!event.isCancelled()) {
      if (inventory.getOutput() == null) {
        inventory.setOutput(event.getResult());
      } else {
        result = event.getResult();
        if (inventory.getOutput().getMaterial().getId() != result.getMaterial().getId()) {
          throw new UnsupportedOperationException("Smelt result must be the same material as the output slot.");
        }
        inventory.addAmount(FurnaceInventory.OUTPUT_SLOT, result.getAmount());
      }
      inventory.addAmount(FurnaceInventory.INGREDIENT_SLOT, -1);
    }

    setMaxSmeltTime(-1);
    setSmeltTime(-1);
  }

  @Override
  public void onTick(float dt) {
    final float fuel = getFuel();
    final FurnaceInventory inventory = getInventory();

    // Not burning
    if (fuel <= 0) {
      // Reset any progress
      if (getSmeltTime() > 0) {
        setSmeltTime(-1);
        setMaxSmeltTime(-1);
      }

      // Try to light the furnace
      if (inventory.hasFuel() && inventory.hasIngredient()) {
        float newFuel = ((Fuel) inventory.getFuel().getMaterial()).getFuelTime();
        FurnaceBurnEvent event = VanillaPlugin.getInstance().getEngine().getEventManager().callEvent(new FurnaceBurnEvent(this, inventory.getFuel(), newFuel));

        if (event.isCancelled()) {
          return;
        }
        newFuel = event.getBurnTime();
        setMaxFuel(newFuel);
        setFuel(newFuel);
        inventory.addAmount(FurnaceInventory.FUEL_SLOT, -1);
        setBurning(true);
        return;
      }

      setBurning(false);
    }
    // Burning
    else if (fuel > 0) {
      setBurning(true);
      pulseFuel(dt);
      final float smeltTime = getSmeltTime();
      if (smeltTime == -1) {
        // Try to start smelting
        if (inventory.hasIngredient()) {
          if (!canSmelt()) {
            return;
          }
          float newSmeltTime = ((TimedCraftable) inventory.getIngredient().getMaterial()).getCraftTime();
          setMaxSmeltTime(newSmeltTime);
          setSmeltTime(newSmeltTime);
          return;
        }
      }

      if (smeltTime <= 0) {
        // Try to smelt the current ingredient
        if (inventory.hasIngredient()) {
          smelt();
          return;
        }
      }

      if (smeltTime > 0) {
        // Reset progress if ingredient is gone
        if (!inventory.hasIngredient()) {
          setSmeltTime(-1);

          return;
        }
        pulseSmeltTime(dt);
      }
    }
  }

  private void setBurning(boolean burning) {
    VanillaMaterials.FURNACE.setBurning(getBlock(), burning);
  }

  @Override
  public FurnaceInventory getInventory() {
    return getData().get(VanillaData.FURNACE_INVENTORY);
  }

  @Override
  public boolean open(Player player) {
    FurnaceOpenEvent event = player.getEngine().getEventManager().callEvent(new FurnaceOpenEvent(this, player));
    if (!event.isCancelled()) {
      WindowHolder window = player.get(WindowHolder.class);
      if (window != null) {
        window.openWindow(new FurnaceWindow(player, this, getInventory()));
        updateProgressArrow(player);
        updateFireIcon(player);
      }
      return true;
    }
    return false;
  }

  @Override
  public boolean close(Player player) {
    FurnaceCloseEvent event = player.getEngine().getEventManager().callEvent(new FurnaceCloseEvent(this, player));
    if (!event.isCancelled()) {
      return super.close(player);
    }
    return false;
  }
}
TOP

Related Classes of org.spout.vanilla.component.block.material.Furnace

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.