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

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

/*
* 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.geo.cuboid.Block;
import org.spout.api.geo.discrete.Point;
import org.spout.api.material.BlockMaterial;

import org.spout.vanilla.component.block.ViewedBlockComponent;
import org.spout.vanilla.component.entity.inventory.WindowHolder;
import org.spout.vanilla.component.entity.misc.Effects;
import org.spout.vanilla.data.VanillaData;
import org.spout.vanilla.data.effect.EntityEffect;
import org.spout.vanilla.data.effect.EntityEffectType;
import org.spout.vanilla.event.inventory.BeaconCloseEvent;
import org.spout.vanilla.event.inventory.BeaconOpenEvent;
import org.spout.vanilla.inventory.block.BeaconInventory;
import org.spout.vanilla.inventory.window.block.BeaconWindow;
import org.spout.vanilla.material.VanillaMaterials;

/**
* Component that represents a Anvil in the world.
*/
public class Beacon extends ViewedBlockComponent {
  /**
   * Returns the amount of levels on the pyramid below this Beacon, this will only account for up to a 4-level pyramid.
   *
   * @return levels on pyramid
   */
  public int getLevels() {
    Block block = getBlock();
    for (int lvl = 1; lvl <= 4; lvl++) {
      for (int dx = -lvl; dx <= lvl; dx++) {
        for (int dz = -lvl; dz <= lvl; dz++) {
          if (!isPyramidMaterial(block.translate(dx, -lvl, dz).getMaterial())) {
            return lvl - 1;
          }
        }
      }
    }
    return 4;
  }

  /**
   * Returns the range in which players are effected by this Beacon determined by an arbitrary algorithm.
   *
   * @return range of effects
   */
  public float getEffectRange() {
    return getLevels() * 10 + 10;
  }

  /**
   * Returns the amount of time (in seconds) until the Beacon will update the players in the vicinity specified by {@link #getEffectRange()}.
   *
   * @return time (in seconds) until beacon sends an update
   */
  public float getUpdateDelay() {
    return getData().get(VanillaData.UPDATE_DELAY);
  }

  /**
   * Sets the amount of time (in seconds) until the Beacon will update the players in the vicinity specified by {@link #getEffectRange()}.
   *
   * @param delay (in seconds) until beacon should send an update
   */
  public void setUpdateDelay(float delay) {
    getData().put(VanillaData.UPDATE_DELAY, delay);
  }

  /**
   * Returns the time that the update delay should be set to upon reaching zero.
   *
   * @return delay to update to when delay reaches zero
   */
  public float getMaxUpdateDelay() {
    return getData().get(VanillaData.MAX_UPDATE_DELAY);
  }

  /**
   * Sets the time that the delay will be reset to upon reaching zero.
   *
   * @param delay to reset to
   */
  public void setMaxUpdateDelay(float delay) {
    getData().put(VanillaData.MAX_UPDATE_DELAY, delay);
  }

  /**
   * Returns the primary effect of this Beacon.
   *
   * @return primary effect of beacon
   */
  public EntityEffectType getPrimaryEffect() {
    return getData().get(VanillaData.PRIMARY_EFFECT);
  }

  /**
   * Sets the primary effect of this Beacon.
   *
   * @param type of effect to use
   */
  public void setPrimaryEffect(EntityEffectType type) {
    getData().put(VanillaData.PRIMARY_EFFECT, type);
  }

  /**
   * Returns the secondary effect of this Beacon.
   *
   * @return type of effect to use
   */
  public EntityEffectType getSecondaryEffect() {
    return getData().get(VanillaData.SECONDARY_EFFECT);
  }

  /**
   * Sets the secondary effect of this Beacon.
   *
   * @param type of effect to use
   */
  public void setSecondaryEffect(EntityEffectType type) {
    getData().put(VanillaData.SECONDARY_EFFECT, type);
  }

  /**
   * Returns the duration of the effects applied by this Beacon.
   *
   * @return duration of effects that are applied
   */
  public float getEffectDuration() {
    return getData().get(VanillaData.EFFECT_DURATION);
  }

  /**
   * Sets the duration of the effects applied by this Beacon.
   *
   * @param duration of effects
   */
  public void setEffectDuration(float duration) {
    getData().put(VanillaData.EFFECT_DURATION, duration);
  }

  /**
   * Returns the amplifier on the primary effect. This returns one if this Beacon has four levels, and it's primary effect is the same as it's secondary effect.
   *
   * @return amplifier of primary effect
   */
  public int getPrimaryAmplifier() {
    return getLevels() == 4 && getPrimaryEffect() == getSecondaryEffect() ? 1 : 0;
  }

  /**
   * Performs an update on the Players in the vicinity specified by {@link #getEffectRange()}. This method applies the primary effect to each player with the duration specified by {@link
   * #getEffectDuration()} and the amplifier specified by {@link #getPrimaryAmplifier()}. The Beacon will apply the secondary effect if it is set, the Beacon's pyramid contains four levels, and the
   * primary effect is not the same as the secondary effect. Note that in order for the secondary effect to be applied it must differ from the primary effect otherwise a buff will just be applied to
   * the primary effect.
   */
  public void doUpdate() {
    resetUpdateDelay();
    Point pos = getPoint();
    EntityEffectType primary = getPrimaryEffect();
    EntityEffectType secondary = getSecondaryEffect();
    if (getLevels() < 1 || primary == null || primary == EntityEffectType.NONE) {
      return;
    }

    for (Player player : pos.getWorld().getNearbyPlayers(pos, (int) getEffectRange())) {
      Effects effects = player.add(Effects.class);
      effects.add(new EntityEffect(primary, getPrimaryAmplifier(), getEffectDuration()));
      if (secondary != null && secondary != EntityEffectType.NONE && getLevels() == 4 && primary != secondary) {
        effects.add(new EntityEffect(secondary, getEffectDuration()));
      }
    }
  }

  /**
   * Resets the update delay specified by {@link #getMaxUpdateDelay()}.
   */
  public void resetUpdateDelay() {
    setUpdateDelay(getMaxUpdateDelay());
  }

  /**
   * Returns true if the specified {@link BlockMaterial} is a valid material to use in the construction of a Beacon's power pyramid.
   *
   * @param mat to check
   * @return true if material is valid
   */
  public static boolean isPyramidMaterial(BlockMaterial mat) {
    return mat.isMaterial(VanillaMaterials.IRON_BLOCK, VanillaMaterials.GOLD_BLOCK, VanillaMaterials.DIAMOND_BLOCK, VanillaMaterials.EMERALD_BLOCK);
  }

  private float pulseUpdateDelay(float dt) {
    float delay = getUpdateDelay() - dt;
    setUpdateDelay(delay);
    return delay;
  }

  @Override
  public void onTick(float dt) {
    if (pulseUpdateDelay(dt) <= 0) {
      doUpdate();
    }
  }

  @Override
  public boolean open(Player player) {
    BeaconOpenEvent event = player.getEngine().getEventManager().callEvent(new BeaconOpenEvent(this, player));
    if (!event.isCancelled()) {
      player.get(WindowHolder.class).openWindow(new BeaconWindow(player, this, new BeaconInventory()));
      return true;
    }
    return false;
  }

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

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

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.