Krekkie
Krekkie

Reputation: 1

How do I share variables between classes created from a method?

Context

I'm creating a spigot plugin for Minecraft which lets a player hunt another player with a certain command.

Problem

As of right now, all the variables are declared at the top of the class so that they are accessible from within the onCommand method. However, if I do it like this, the plugin will only work for 1 player because the variables will be the same for everyone and overwritten by everyone using the command (e.g. all players will have a cooldown timer on the command because of the first player using it). I want all the variables to be declared inside of the onCommand method so that the values of the variables are unique to every player using the command. However, if I move them to the top of the onCommand method, I'm not able to use them anymore and get the following errors (see images):

I also want some variables to be public, so that they can be used in another class, but it seems variables aren't allowed to be public inside of a method (see image):

Is anyone able to help me out with those three problems?

Full code below:

package com.krekkie.hunt.commands;

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

import java.text.MessageFormat;
import java.util.Timer;
import java.util.TimerTask;

public class HuntCommands implements CommandExecutor {

    @Override
    public boolean onCommand(CommandSender sender, Command command, String label, String[] arguments) {
        if (!(sender instanceof Player)) {
            sender.sendMessage("Only players can use that command!");
            return true;
        }
        Player player = (Player) sender;
        String playerName = player.getName();
        public Player targetPlayer;
        String targetPlayerName;
        World world = player.getWorld();
        long currentTime = world.getFullTime();

        Timer timer;
        public boolean isHunting = false;
        long fixedCooldownTime = 5*1000;
        long cooldownTime = 0;
        float cooldownTimeLeft;
        long huntStartTime = 0;

        // /hunt <player>
        if (command.getName().equalsIgnoreCase("hunt")) {
            if (!isHunting) {
                if (currentTime >= huntStartTime + cooldownTime) {
                    if (arguments.length == 1) {
                        targetPlayer = Bukkit.getPlayer(arguments[0]);
                        targetPlayerName = targetPlayer.getName();
                        try {
                            huntStartTime = world.getFullTime();
                            targetPlayer.sendMessage(MessageFormat.format("You are being hunted by {0}!", playerName));

                            timer = new Timer();
                            TimerTask timerTask = new TimerTask() {
                                int count = 0;

                                @Override
                                public void run() {
                                    Location targetPlayerLocation = targetPlayer.getLocation();
                                    float axisX = targetPlayerLocation.getBlockX();
                                    float axisY = targetPlayerLocation.getBlockY();
                                    float axisZ = targetPlayerLocation.getBlockZ();
                                    player.sendMessage(MessageFormat.format("You smell {0} at {1} {2} {3}", targetPlayerName, axisX, axisY, axisZ));

                                    count++;
                                    if (count >= 3) {
                                        timer.cancel();
                                        cooldownTime = fixedCooldownTime;
                                        player.sendMessage(MessageFormat.format("You cannot smell {0} anymore!", targetPlayerName));
                                        targetPlayer.sendMessage(MessageFormat.format("{0} lost your trace!", playerName));
                                        isHunting = false;
                                    }
                                }
                            };
                            timer.schedule(timerTask, 0, 10*1000);
                            isHunting = true;
                        } catch (IllegalArgumentException e) {
                            player.sendMessage("§c§l(!) §cInvalid argument!");
                        }
                    } else {
                        player.sendMessage("§c§l(!) §c/hunt <player>");
                    }
                } else {
                    cooldownTimeLeft = (float) Math.ceil(((huntStartTime + cooldownTime) - currentTime) / 1000);
                    player.sendMessage(MessageFormat.format("§c§l(!) §cYou need to wait {0} more minutes!", cooldownTimeLeft));
                }
            } else {
                player.sendMessage("§c§l(!) §cYou are already hunting someone!");
            }
        }

        // /huntstop
        if (command.getName().equalsIgnoreCase("huntstop")) {
            if (isHunting) {
                timer.cancel();
                cooldownTime = fixedCooldownTime;
                player.sendMessage(MessageFormat.format("You cannot smell {0} anymore!", targetPlayerName));
                targetPlayer.sendMessage(MessageFormat.format("{0} lost your trace!", playerName));
                isHunting = false;
            } else {
                player.sendMessage(("You are not hunting anyone!"));
            }
        }

        return true;
    }
}

Upvotes: 0

Views: 479

Answers (1)

GJohannes
GJohannes

Reputation: 1763

You can create a Helper class which contains a static field. This can be simply shared by both classes at the same time. Be careful with "hacks" like this. it is really easy to create spaghetti code like this. Also Multithreading will become difficult since every Thread can change such a global public variable at any time.

public classA {
    ....
    Helper.setInt(42);
    ....
} 

public classB {
    ....
    Helper.getInt(); // will return 42 if the call in classA was done before 
    ....
} 


public class Helper {
    public static int someInt = 0;

    public static int getInt() {
        return someInt;
    };

    public static void setInt(int value) {
        someInt = value;
    };
}

Upvotes: 1

Related Questions