/**
   * When a creeper explodes, reinforcements are launched from him with random velocities by this
   * method.
   *
   * <p>Reinforcements are always launched at a 45 degree angle, a configurable range from the
   * exploding creeper.
   *
   * @param creeper the exploding creeper.
   */
  protected void launchReinforcements(Entity creeper) {
    final int numReinforcements = random(CONFIG.MIN_REINFORCEMENTS, CONFIG.MAX_REINFORCEMENTS);
    for (int i = 0; i < numReinforcements; ++i) {
      // Compute unit velocity vector components, given 45 degree pitch.
      double yaw = 2.0 * Math.PI * Math.random();
      double y = INV_ROOT_2;
      double x = INV_ROOT_2 * Math.cos(yaw);
      double z = INV_ROOT_2 * Math.sin(yaw);

      // Spawn one reinforcement.
      Location origin = creeper.getLocation();
      World world = origin.getWorld();
      Location loc =
          origin.clone().add(CONFIG.REINFORCEMENT_RANGE * x, 0.5, CONFIG.REINFORCEMENT_RANGE * z);
      Creeper reinforcement = (Creeper) world.spawnEntity(loc, EntityType.CREEPER);
      if (reinforcement != null) {
        reinforcement.setMetadata(SPECIAL_KEY, SPECIAL_META);

        double speed = random(CONFIG.MIN_REINFORCEMENT_SPEED, CONFIG.MAX_REINFORCEMENT_SPEED);
        Vector velocity = new Vector(speed * x, speed * y, speed * z);
        reinforcement.setVelocity(velocity);

        // Randomly charge a fraction of creepers.
        if (Math.random() < CONFIG.CHARGED_CHANCE) {
          reinforcement.setPowered(true);
        }
      }
    }
  } // launchReinforcements
  /** Replace naturally spawned monsters in the affected world with creepers. */
  @EventHandler(ignoreCancelled = true)
  public void onCreatureSpawn(CreatureSpawnEvent event) {
    if (!CONFIG.isAffectedWorld(event)
        || event.getSpawnReason() != SpawnReason.NATURAL
        || !isEligibleHostileMob(event.getEntityType())) {
      return;
    }

    Entity originalMob = event.getEntity();
    Creeper creeper;
    if (event.getEntityType() == EntityType.CREEPER) {
      creeper = (Creeper) originalMob;
    } else {
      Location loc = originalMob.getLocation();
      creeper = (Creeper) loc.getWorld().spawnEntity(loc, EntityType.CREEPER);
      originalMob.remove();
    }
    creeper.setMetadata(SPECIAL_KEY, SPECIAL_META);

    if (Math.random() < CONFIG.CHARGED_CHANCE) {
      creeper.setPowered(true);
    }
  } // onCreatureSpawn