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

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

/*
* 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 java.util.Random;

import org.spout.api.entity.Entity;
import org.spout.api.entity.Player;
import org.spout.api.geo.LoadOption;
import org.spout.api.geo.discrete.Point;

import org.spout.vanilla.component.block.VanillaBlockComponent;
import org.spout.vanilla.data.VanillaData;
import org.spout.vanilla.material.VanillaMaterials;
import org.spout.vanilla.protocol.entity.creature.CreatureType;

/**
* Component that represents a Monster Spawner in the world.
*/
public class MonsterSpawner extends VanillaBlockComponent {
  private final Random random = new Random();

  @Override
  public void onAttached() {
    resetSpawnDelay();
    sendData();
  }

  @Override
  public void onTick(float dt) {
    if (isActive()) {
      float spawnDelay = pulseSpawnDelay(dt);
      if (spawnDelay <= 0) {
        doSpawn();
      }
    } else {
      resetSpawnDelay();
    }
  }

  @Override
  public boolean canTick() {
    return true;
  }

  /**
   * Sets the minimum amount of seconds that the spawner can spawn within.
   *
   * @param delay in seconds
   */
  public void setMinSpawnDelay(int delay) {
    getData().put(VanillaData.MIN_SPAWN_DELAY, delay);
  }

  /**
   * Returns the minimum amount of seconds that the spawner can spawn within.
   *
   * @return delay in seconds
   */
  public int getMinSpawnDelay() {
    return getData().get(VanillaData.MIN_SPAWN_DELAY);
  }

  /**
   * Sets the maximum amount of seconds that a spawner can spawn within.
   *
   * @param delay in seconds
   */
  public void setMaxSpawnDelay(int delay) {
    getData().put(VanillaData.MAX_SPAWN_DELAY, delay);
  }

  /**
   * Returns the maximum amount of seconds that a spawner can spawn within.
   *
   * @return delay in seconds
   */
  public int getMaxSpawnDelay() {
    return getData().get(VanillaData.MAX_SPAWN_DELAY);
  }

  /**
   * Sets the amount of creatures that can be within the bounds specified by {@link #getCreatureSearchRange()}.
   *
   * @param maxCreatures maximum amount of creatures that can spawn
   */
  public void setMaxCreatures(int maxCreatures) {
    getData().put(VanillaData.MAX_CREATURES, maxCreatures);
  }

  /**
   * Returns the amount of creatures that can be within the bounds specified by {@link #getCreatureSearchRange()}.
   *
   * @return maximum amount of creatures that can spawn
   */
  public int getMaxCreatures() {
    return getData().get(VanillaData.MAX_CREATURES);
  }

  /**
   * Sets the range in which to search for creatures in.
   *
   * @param range to search for creatures in
   */
  public void setCreatureSearchRange(int range) {
    getData().put(VanillaData.CREATURE_SEARCH_RANGE, range);
  }

  /**
   * Returns the range in which to search for creatures in.
   *
   * @return range to search for creatures in
   */
  public int getCreatureSearchRange() {
    return getData().get(VanillaData.CREATURE_SEARCH_RANGE);
  }

  /**
   * Sets the range in which entities can spawn from the spawner.
   *
   * @param spawnRange of spawner
   */
  public void setSpawnRange(float spawnRange) {
    getData().put(VanillaData.SPAWN_RANGE, spawnRange);
  }

  /**
   * Returns the range in which entities can spawn from the spawner.
   *
   * @return range from the spawner
   */
  public float getSpawnRange() {
    return getData().get(VanillaData.SPAWN_RANGE);
  }

  /**
   * Sets the amount of entities the spawner should attempt to spawn on every {@link #doSpawn()}.
   *
   * @param spawnCount how many entities to try and spawn
   */
  public void setSpawnCount(int spawnCount) {
    getData().put(VanillaData.SPAWN_COUNT, spawnCount);
  }

  /**
   * Returns the amount of entities the spawner should attempt to spawn on every {@link #doSpawn()}.
   *
   * @return how many entities to spawn
   */
  public int getSpawnCount() {
    return getData().get(VanillaData.SPAWN_COUNT);
  }

  /**
   * Attempts to spawn the amount of entities specified by {@link #getSpawnCount()} within the range specified by {@link #getSpawnRange()} and resets the spawn delay.
   */
  public void doSpawn() {
    Point pos = getPoint();
    resetSpawnDelay();
    for (int i = 0; i < getSpawnCount(); i++) {
      float range = getSpawnRange();
      float x = pos.getX() + (random.nextFloat() - random.nextFloat()) * range;
      float y = pos.getY() + random.nextInt(3) - 1;
      float z = pos.getZ() + (random.nextFloat() - random.nextFloat()) * range;
      Point p = new Point(pos.getWorld(), x, y, z);
      if (p.getBlock().getMaterial().isMaterial(VanillaMaterials.AIR) && canSpawn()) {
        p.getWorld().createAndSpawnEntity(p, LoadOption.LOAD_ONLY, getCreatureType().getComponentType());
      }
    }
  }

  /**
   * Whether the spawner should spawn more creatures.
   *
   * @return true if the spawner is able to spawn more
   */
  public boolean canSpawn() {
    int count = 0;
    int range = getCreatureSearchRange();
    for (Entity e : getOwner().getWorld().getNearbyEntities(getPoint(), range)) {
      if (e instanceof Player) {
        continue;
      }
      count++;
    }
    return count < getMaxCreatures();
  }

  /**
   * Sets the {@link CreatureType} spawned.
   *
   * @param type to spawn
   */
  public void setCreatureType(CreatureType type) {
    getData().put(VanillaData.CREATURE_TYPE, type.getId());
    sendData();
  }

  /**
   * Returns the {@link CreatureType} to spawn.
   *
   * @return creature to spawn
   */
  public CreatureType getCreatureType() {
    return CreatureType.get(getData().get(VanillaData.CREATURE_TYPE));
  }

  /**
   * Sets the radius in which the spawner requires at least one {@link Player} to be within.
   *
   * @param radius to search for players in
   */
  public void setRadius(int radius) {
    getData().put(VanillaData.RADIUS, radius);
  }

  /**
   * Returns the radius in which the spawner requires at least one {@link Player} to be within.
   *
   * @return radius to search for players in
   */
  public int getRadius() {
    return getData().get(VanillaData.RADIUS);
  }

  /**
   * Returns true if a {@link Player} is within the radius specified by {@link #getRadius()}.
   *
   * @return true if there is a player within the radius
   */
  public boolean isActive() {
    return !getOwner().getWorld().getNearbyPlayers(getPoint(), getRadius()).isEmpty();
  }

  /**
   * Returns the amount of time, in seconds, there is until the next {@link #doSpawn()} call.
   *
   * @return time, in seconds, until next spawn
   */
  public float getSpawnDelay() {
    return getData().get(VanillaData.SPAWN_DELAY);
  }

  /**
   * Sets the amount of time, in seconds, there is until the next {@link #doSpawn()} call.
   *
   * @param spawnDelay in seconds
   */
  public void setSpawnDelay(float spawnDelay) {
    getData().put(VanillaData.SPAWN_DELAY, spawnDelay);
  }

  /**
   * Resets the spawn delay to an amount between 10 and 40 seconds.
   */
  public void resetSpawnDelay() {
    int max = getMaxSpawnDelay(), min = getMinSpawnDelay();
    setSpawnDelay(random.nextInt(max - min) + min);
  }

  private float pulseSpawnDelay(float dt) {
    float delay = getSpawnDelay() - dt;
    setSpawnDelay(delay);
    return delay;
  }

  private void sendData() {
    // TODO: Update the client
  }
}
TOP

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

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.