3

So, I have a class called HitDistanceRatios, it Implements CommandExecutor, It's called in MainClass which is the only class that calls JavaPlugin except for ConfigGets. I also have another class called HitEvent which is an EventHandler, every time a player is hit, the damager's UUID is added to a Multimap, hitMap, where the distances of the hits are stored as the values, a Double. There is also one more class that should be known is HitDistance, which CAN actually receive the hitMap. The difference between HitDistance and HitDistanceRatios is that HitDistanceRatios is called in MainClass to execute a command.

Basically the problem I'm having is that HitDistanceRatios isn't taking anything from any other class. I've tried multiple ways of getting the hitMap from HitEvent, and even going through HitDistance to try and get it, but I can't find a way that works.

Here is HitDistanceRatios:

package yt.Kaelinator.commands;

import java.text.DecimalFormat;

import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;

import yt.Kaelinator.ConfigGets;
import yt.Kaelinator.MainClass;
import yt.Kaelinator.calculations.HitDistance;

public class HitDistanceRatios implements CommandExecutor {

  public HitDistanceRatios(MainClass instance) {}

  @
  Override
  public boolean onCommand(CommandSender sender, Command command, String cmd, String[] args) {
    if (!(sender instanceof Player))
      return false;
    Player player = (Player) sender;

    if (args.length == 0) {

      DecimalFormat numberFormat = new DecimalFormat("#.00");
      HitDistance hd = new HitDistance(null);

      player.sendMessage(ConfigGets.prefix + ChatColor.BLUE + player.getName() + ": " + ChatColor.RED + numberFormat.format(hd.getFourMap(player.getUniqueId())) + ChatColor.BLUE + "% of hits are over 4 blocks, " + ChatColor.RED + numberFormat.format(hd.getThreeHalfMap(player.getUniqueId())) + ChatColor.BLUE + "% are over 3.5 blocks.");
      return true;
    } else {@
      SuppressWarnings("deprecation")
      Player target = Bukkit.getPlayer(args[0]);

      if (target == null) {
        player.sendMessage(ConfigGets.prefix + "Player " + args[0] + " couldn't be found.");
        return true;

      } else {

        DecimalFormat numberFormat = new DecimalFormat("#.00");
        HitDistance hd = new HitDistance(null);

        player.sendMessage(ConfigGets.prefix + ChatColor.BLUE + target.getName() + ": " + ChatColor.RED + numberFormat.format(hd.getFourMap(target.getUniqueId())) + ChatColor.BLUE + "% of hits are over 4 blocks, " + ChatColor.RED + numberFormat.format(hd.getThreeHalfMap(target.getUniqueId())) + ChatColor.BLUE + "% are over 3.5 blocks.");
      }
      return true;
    }
  }
}
Here, the class is taking in HitDistance and trying to get a couple HashMaps from there, but I get the same result if I use a getter in the HitEvent class.

Here is HitEvent:

package yt.Kaelinator.events;

import java.util.UUID;

import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDamageByEntityEvent;

import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;

import yt.Kaelinator.ConfigGets;
import yt.Kaelinator.MainClass;
import yt.Kaelinator.calculations.HitDistance;
import yt.Kaelinator.calculations.Lag;

public class HitEvent implements Listener {

  Multimap < UUID, Double > hitMap = ArrayListMultimap.create();

  public HitEvent(MainClass instance) {}

  @
  EventHandler
  public void onPlayerHit(EntityDamageByEntityEvent event) {

    // make sure they are all players
    if (!(event.getEntity() instanceof Player) | !(event.getDamager() instanceof Player))
      return;

    // get the event's players
    Player damaged = (Player) event.getEntity();
    Player damager = (Player) event.getDamager();

    // get the locations
    Location damagedLocation = damaged.getLocation();
    Location damagerLocation = damager.getLocation();

    // calculate the distance
    double distance = damagedLocation.distance(damagerLocation);

    // broadcast it to everyone
    ClickEvent ce = new ClickEvent();
    boolean displayHits = ConfigGets.DisplayDistances;
    if (displayHits) {
      for (Player p: Bukkit.getOnlinePlayers()) {
        p.sendMessage(ChatColor.translateAlternateColorCodes('&',
          ConfigGets.prefix +
          "&f" + damager.getDisplayName() + "&3 damaged &f" + damaged.getDisplayName() + "&3 Distance: &4" + distance + " &7&l" + ce.checkForLag(damager.getUniqueId()) + " " + ce.checkForLag(damaged.getUniqueId()) + " " + Math.ceil(Lag.getTPS())));
      }
    }

    if (!ce.checkForLag(damager.getUniqueId()) & !ce.checkForLag(damaged.getUniqueId()) & !(Math.ceil(Lag.getTPS()) < 20)) {
      hitMap.put(damager.getUniqueId(), distance);
    }

    UUID playerUUID = damager.getUniqueId();
    int hitAmount = hitMap.get(playerUUID).size();

    if ((hitAmount % 5 == 0) & hitAmount >= 20) {

      HitDistance hd = new HitDistance(null);
      hd.hasReach(hitMap.get(playerUUID), playerUUID);
    }
  }

  public Multimap < UUID, Double > getHitMap() {
    return hitMap;
  }
}

As you can see, I have a getter that I would use, this getter used to be a Collection and would return the collection of hit distances given a UUID. Anything gotten from another class into HitDistanceRatio returns null, causing errors.

Here's HitDistance:

package yt.Kaelinator.calculations;

import java.util.Collection;
import java.util.HashMap;
import java.util.UUID;

import org.bukkit.Bukkit;

import yt.Kaelinator.ConfigGets;
import yt.Kaelinator.MainClass;
import yt.Kaelinator.events.HitEvent;

public class HitDistance {

  public HitDistance(MainClass instance) {}

  public HashMap < UUID, Double > mapFourOverTotal = new HashMap < UUID, Double > ();
  public HashMap < UUID, Double > mapThreeHalfOverTotal = new HashMap < UUID, Double > ();

  HitEvent he = new HitEvent(null);

  public void hasReach(Collection < Double > collection, UUID uuid) {

    int length = collection.size();

    Double[] distances = collection.toArray(new Double[length]);

    int overThreeHalf = 0;
    int overFour = 0;
    int rep = 0;
    for (int i = 0; i < distances.length; i++) {
      if (distances[i] > 4.0) {
        overFour++;
        if (i >= 5) {
          if (distances[i - 1] > 4.0)
            rep++;
          if (distances[i - 2] > 4.05)
            rep += 2;
          if (distances[i - 3] > 4.1)
            rep += 3;
        }
      } else if (distances[i] > 3.5) {
        overThreeHalf++;
        if (i >= 5) {
          if (distances[i - 1] > 3.6)
            rep++;
          if (distances[i - 2] > 3.7)
            rep += 2;
          if (distances[i - 3] > 3.8)
            rep += 3;
        }
      }
    }

    double fourOverTotal = overFour / distances.length;
    double threeHalfOverTotal = overThreeHalf / distances.length;

    mapFourOverTotal.put(uuid, fourOverTotal);
    mapThreeHalfOverTotal.put(uuid, threeHalfOverTotal);

    if (fourOverTotal >= 1 / 3) {
      rep += 10;
    }

    if (threeHalfOverTotal / distances.length >= 2 / 5) {
      rep += 10;
    }



    if (rep >= 30) {
      Bukkit.getPlayer(uuid).kickPlayer(ConfigGets.prefix +
        ConfigGets.kickForReach);
    }
  }

  public double getFourMap(UUID uuid) {
    return mapFourOverTotal.get(uuid);
  }

  public double getThreeHalfMap(UUID uuid) {
    return mapThreeHalfOverTotal.get(uuid);
  }
}

Again, as you can see I have a couple getters that get the values from a hashmap given a UUID. But to no surprize, everything returns null. This is very confusing to me because HitDistance can access hitMap, but HitDistanceRatios can't access anything. I feel like this has something to do with how they interact inside of MainClass:

package yt.Kaelinator;

import org.bukkit.Bukkit;
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin;

import yt.Kaelinator.calculations.Lag;
import yt.Kaelinator.commands.HitDistanceRatios;
import yt.Kaelinator.events.ClickEvent;
import yt.Kaelinator.events.HitEvent;

public class MainClass extends JavaPlugin {

  public static MainClass instance = null;

  public void onEnable() {
    registerEvents();
    registerConfig();
    registerCommands();
    Bukkit.getServer().getScheduler().scheduleSyncRepeatingTask(this, new Lag(), 100L, 1L);
  }

  public void registerEvents() {
    PluginManager pm = getServer().getPluginManager();
    pm.registerEvents(new HitEvent(null), this);
    pm.registerEvents(new ClickEvent(), this);
  }

  private void registerConfig() {
    getConfig().options().copyDefaults(true);
    saveConfig();
  }

  private void registerCommands() {
    getCommand("hitdistanceratio").setExecutor(new HitDistanceRatios(this));
  }

}
Any suggestions?
Kaelinator
  • 360
  • 3
  • 17
  • minecraft type questions are typically off-topic for StackOverflow. Not sure why the tags are still here. They are next to impossible for us to reproduce. – user1231232141214124 Jun 29 '16 at 04:49
  • @redFIVE I know :/ I've already tried going there. I was just hoping that this a problem that people had with java all around. – Kaelinator Jun 29 '16 at 04:59
  • What is the code trying to do? Or, rather, what were you wanting the code to do? – G. May Jun 29 '16 at 12:54
  • Could you tell me what exactly you're trying to accomplish? I might be able to give a little help – LeoColman Jul 12 '16 at 06:24

1 Answers1

0

This is a complicated one. From a little bit of reading, I saw that if you do not specify an access modifier, it is by default, a "private package". I do not completely know what this means, but I think if you change the line in HitEvent to this:

public Multimap < UUID, Double > hitMap = ArrayListMultimap.create();

It should work if it is like that. The reason being, the access modifier, "private package", only lets the classes in that specific package access it. If the class that is trying to access it, is not in it's package, it has no access.

Fishy
  • 1,275
  • 1
  • 12
  • 26