Duel Plugin, sending requests and opening inventories with HashMaps - java

I asked a similar question to this today, but I need help with further development.
The HashMaps:
Map<UUID, UUID> duels = new HashMap<UUID, UUID>();
Map<UUID, UUID> selecting = new HashMap<UUID, UUID>();
The command:
if (cmd.getName().equalsIgnoreCase("duel")) {
if (!(args.length == 1)) {
sender.sendMessage(ChatColor.DARK_RED + "[" + ChatColor.DARK_GREEN + "HuntsCraft" + ChatColor.DARK_RED + "]" + ChatColor.RED + " Usage: /duel <Player>");
return true;
} else if (args.length == 1) {
Player p = Bukkit.getServer().getPlayer(args[0]);
if (p != null) {
if (p.equals(sender)) {
sender.sendMessage(ChatColor.DARK_RED + "[" + ChatColor.DARK_GREEN + "HuntsCraft" + ChatColor.DARK_RED + "]" + ChatColor.RED + " You cannot duel yourself!");
return true;
} else {
if (duels.containsKey(p) || duels.containsKey(sender)) {
sender.sendMessage(ChatColor.DARK_RED + "[" + ChatColor.DARK_GREEN + "HuntsCraft" + ChatColor.DARK_RED + "] " + ChatColor.RED + "Either you or " + ChatColor.BLUE + p.getName() + ChatColor.RED + " are already in a duel!");
return true;
} else
openKitSelector((Player) sender);
selecting.put(p.getUniqueId(), ((Player) sender).getUniqueId());
The KitSelector inventory:
public void openKitSelector(Player p) {
Inventory selector = Bukkit.createInventory(p, 9, ChatColor.DARK_RED + "[" + ChatColor.DARK_GREEN + "KitSelector" + ChatColor.DARK_RED + "]");
ItemStack diamond = new ItemStack(Material.DIAMOND_SWORD);
ItemMeta diamondMeta = diamond.getItemMeta();
diamondMeta.setDisplayName(ChatColor.DARK_AQUA + "Diamond Kit");
diamond.setItemMeta(diamondMeta);
ItemStack iron = new ItemStack(Material.IRON_SWORD);
ItemMeta ironMeta = iron.getItemMeta();
ironMeta.setDisplayName(ChatColor.DARK_GREEN + "Iron Kit");
iron.setItemMeta(ironMeta);
selector.setItem(0, diamond);
selector.setItem(1, iron);
p.openInventory(selector);
}
The Accept/Deny inventory:
private void openGUI(Player player) {
Inventory inv = Bukkit.createInventory(null, 9, ChatColor.DARK_RED + "[" + ChatColor.DARK_GREEN + "DuelRequest" + ChatColor.DARK_RED + "]");
ItemStack accept = new ItemStack(Material.EMERALD_BLOCK);
ItemMeta acceptMeta = accept.getItemMeta();
ItemStack decline = new ItemStack(Material.REDSTONE_BLOCK);
ItemMeta declineMeta = decline.getItemMeta();
acceptMeta.setDisplayName(ChatColor.GREEN + "Accept!");
accept.setItemMeta(acceptMeta);
declineMeta.setDisplayName(ChatColor.RED + "Decline!");
decline.setItemMeta(declineMeta);
inv.setItem(3, accept);
inv.setItem(5, decline);
player.openInventory(inv);
}
So what I need to happen is, when someone types /duel <player> , they will get an inventory up with a selection of items that will give them kits, which I have done correctly and tested. Then when they select a kit, the target of the /duel command will get an inventory with an accept item and decline item.
I got everything working up to the part were the target gets the inventory for accept or deny as I am not really experienced with HashMaps, and I am a little confused.

If you wanted to get the target of a duel request from the selecting HashMap, you could use:
UUID id = selecting.get(player.getUniqueId());
Player target = Bukkit.getPlayer(id);
So, if you wanted to open the kit selector for the target, you could use:
//get the UUID of the Player that is being targeted by the Player player
UUID id = selecting.get(player.getUniqueId());
//get the target Player from the UUID above
Player target = Bukkit.getPlayer(id);
//open the kit selector for the target Player above
openKitSelector(target);
To open the target's inventory after the duel requester has selected their kit, you would have to listen for InventoryCloseEvent:
#EventHandler
public void inventoryClose(InventoryCloseEvent e){
//called when a player closes their inventory
}
So, your code could look like this:
#EventHandler
public void inventoryClose(InventoryCloseEvent e){
//check if the inventory is the duel inventory
if(e.getInventory().getName().equals(ChatColor.DARK_RED + "[" + ChatColor.DARK_GREEN + "DuelRequest" + ChatColor.DARK_RED + "]"){
//get the player who opened the inventory
Player p = (Player) e.getWhoClicked();
//now, check if the selecting HashMap contains the Player above
if(selecting.containsKey(p.getUniqueId())){
//get the target of the duel
Player target = Bukkit.getPlayer(selecting.get(p.getUniqueId()));
//open the kit selector for the target Player above
openKitSelector(target);
//now, remove the target's, and the sender's UUID from the selecting
//HashMap, to make sure that we don't accidentally open the kit
//selector for a player who is currently in a duel.
selecting.remove(p.getUniqueId());
//make sure the selecting HashMap contains the target's UUID before
//attempting to remove it
if(selecting.containsKey(target.getUniqueId())){
selecting.remove(target.getUniqueId());
}
}
}
}
If you wanted to make sure that the player clicks something in the inventory, you could use InventoryClickEvent:
#EventHandler
public void inventoryClick(InventoryClickEvent e){
//called when a player clicks something in a inventory
}
Also, you will have to switch around the order in which items are in the HashMap. Instead of using the target as the key, use the sender as the key:
selecting.put(((Player) sender).getUniqueId(), p.getUniqueId());
So, your onCommand could look like this:
if(cmd.getName().equalsIgnoreCase("duel")){
if(!(args.length == 1)){
sender.sendMessage(ChatColor.DARK_RED + "[" + ChatColor.DARK_GREEN + "HuntsCraft" + ChatColor.DARK_RED + "]" + ChatColor.RED + " Usage: /duel <Player>");
return true;
}
else if (args.length == 1){
Player p = Bukkit.getServer().getPlayer(args[0]);
if(p != null){
if(p.equals(sender)){
sender.sendMessage(ChatColor.DARK_RED + "[" + ChatColor.DARK_GREEN + "HuntsCraft" + ChatColor.DARK_RED + "]" + ChatColor.RED + " You cannot duel yourself!");
return true;
}
else{
if(duels.containsKey(p) || duels.containsKey(sender)){
sender.sendMessage(ChatColor.DARK_RED + "[" + ChatColor.DARK_GREEN + "HuntsCraft" + ChatColor.DARK_RED + "] " + ChatColor.RED + "Either you or " + ChatColor.BLUE + p.getName() + ChatColor.RED + " are already in a duel!");
return true;
}
else{
openKitSelector((Player) sender);
//this line was changed from
//selecting.put(p.getUniqueId(), ((Player) sender).getUniqueId())
//to the new value, with the sender as the key,
//and the target as the value.
selecting.put(((Player) sender).getUniqueId(), p.getUniqueId());
}
}
}
}
}

Related

Problem with vanish | When a player quit and rejoin, he can see me (while i'm vanished) | Minecraft Plugin Java

I'm having issues with my command /vanish: while i'm vanished, and a player join the game after my vanishing, he can see me. Here the code of the command and of the PlayerJoinEvent + updateVanish():
if(commandLabel.equalsIgnoreCase("vanish")) {
if (player.hasPermission("vanish.permission")) {
if(!vanish.contains(target)) {
vanish.add(target);
if (player == target) {
player.sendMessage(ChatColor.BLUE + "Ora sei in " + ChatColor.LIGHT_PURPLE + "Vanish" + ChatColor.BLUE+ ". Nessuno ti potrĂ  vedere");
} else {
player.sendMessage(ChatColor.BLUE + "Hai Impostato " + ChatColor.DARK_BLUE + target.getName() + ChatColor.YELLOW + " in " + ChatColor.LIGHT_PURPLE + "Vanish");
target.sendMessage(ChatColor.BLUE + "Ora sei in Vanish. Nessuno ti potrĂ  vedere");
}
for (Player persone : Bukkit.getOnlinePlayers()) {
if (!persone.hasPermission("visible.vanish")) {
persone.hidePlayer(this, target);
}
}
} else {
vanish.remove(target);
for (Player persone : Bukkit.getOnlinePlayers()) {
persone.showPlayer(this, target);
}
if (player == target) {
player.sendMessage(ChatColor.RED + "Ora non sei in " + ChatColor.LIGHT_PURPLE + "Vanish" + ChatColor.RED+ ". Tutti ti potranno vedere");
} else {
player.sendMessage(ChatColor.RED + "Hai disattivato " + ChatColor.DARK_BLUE + target.getName() + ChatColor.YELLOW + " dal " + ChatColor.LIGHT_PURPLE + "Vanish");
target.sendMessage(ChatColor.RED + "Ora non sei in Vanish. Tutti ti potranno vedere");
}
}
} else {
player.sendMessage(ChatColor.RED + "Non hai il permesso di usare questo comando");
}
return true;
}
Here the PlayerJoinEvent + updateVanish():
#EventHandler
public void OnPlayerJoin(PlayerJoinEvent e) {
updateVanish();
}
public void updateVanish() {
for (Player persone : Bukkit.getOnlinePlayers()) {
if (vanish.contains(persone)) {
for (Player persone2 : Bukkit.getOnlinePlayers() ) {
persone2.hidePlayer(this, persone);
}
}
}
}
Thanks <3!
This can be solved by creating an List containing all currently vanished players and then once a new player joins, use the PlayerJoinEvent to iterate trough all currently vanished players and vanish them for the newbie using:
Player.hidePlayer(t)
I currently do not own the tools to build proper code but if you are still indoubted after reading the above, I can detail better.

Removing all occurrences of a key only removes one

I have the following:
ArrayList<GregorianCalendar> toRemove = new ArrayList<GregorianCalendar>();
SortedSet<GregorianCalendar> copyKeys = new TreeSet<GregorianCalendar>(MyCalendarTester.myCal.getMyCalHash().keySet());
for(GregorianCalendar remove: toRemove){
copyKeys.removeAll(Collections.singleton(remove));
}
And I am trying to remove every occurrence of the key "remove" in my TreeSet copyKeys. But it only seems to remove one of them. Could someone please tell me what I'm doing wrong? Please let me know if you need more information.
EDIT:
For the sake of it, here is my entire mess of a method (I know it has a few more issues that just the question that I am asking), but here is goes:
public void eventList(){
int year = -1;
GregorianCalendar tempKey = null;
ArrayList<Event> tempArr = new ArrayList<Event>();
ArrayList<GregorianCalendar> toRemove = new ArrayList<GregorianCalendar>();
int countEnd = 0;
if(MyCalendarTester.myCal.getMyCalHash().equals(null)){
System.out.println("Your calendar is empty!");
}
else{
System.out.println("Here are your events: ");
SortedSet<GregorianCalendar> keys = new TreeSet<GregorianCalendar>(MyCalendarTester.myCal.getMyCalHash().keySet());
SortedSet<GregorianCalendar> copyKeys = new TreeSet<GregorianCalendar>(MyCalendarTester.myCal.getMyCalHash().keySet());
tempKey = keys.first();
int countTotal = keys.size();
for(GregorianCalendar key : copyKeys){
GregorianCalendar copyKey = key;
Event value = MyCalendarTester.myCal.getMyCalHash().get(key);
// System.out.println(" key.get(Calendar.MONTH) = " + key.get(Calendar.MONTH));
// System.out.println("(tempKey.get(Calendar.MONTH)) = " + (tempKey.get(Calendar.MONTH)));
// System.out.println(" key.get(Calendar.DATE) = " + key.get(Calendar.DATE));
// System.out.println(" tempKey.get(Calendar.DATE) = " + (tempKey.get(Calendar.DATE)));
tempArr.add(value);
countEnd++;
if(key.get(Calendar.MONTH) == (tempKey.get(Calendar.MONTH))
&& key.get(Calendar.DATE) == (tempKey.get(Calendar.DATE))
&& key.get(Calendar.YEAR) == tempKey.get(Calendar.YEAR)){
// tempArr.add(value);
if(key.get(Calendar.YEAR) != year){
System.out.println(key.get(Calendar.YEAR));
year = key.get(Calendar.YEAR);
System.out.println(MyCalendarTester.arrayOfDays[key.get(Calendar.DAY_OF_WEEK) - 1] + ", " + MyCalendarTester.arrayOfMonths[key.get(Calendar.MONTH) - 1] + " "
+ key.get(Calendar.DATE) + " ");
}
toRemove.add(copyKey);
// toRemove.add(copyKey);
//keys.remove(copyKey);
}else{
//if(count <= 1){
//if(tempArr.size() == 1){
if(countEnd == countTotal){
tempArr.remove(tempArr.size() - 1);
}else{
if(tempArr.size() > 1){
tempArr.remove(tempArr.size() - 2);
}else{
tempArr.remove(tempArr.size() - 1);
}
if(toRemove.size() > 0){
toRemove.remove(toRemove.size() - 1);
}
}
// }
// else{
// tempArr.remove(tempArr.size() - 2);
// toRemove.remove(toRemove.size() - 1);
// }
//
// count = 0; //reset matches
//}
}
tempKey = key;
}
Collections.sort(tempArr);
for(Event e: tempArr){
if(e.endTime != null){
System.out.println(" " + e.eventName + " " + e.startTime.get(Calendar.HOUR_OF_DAY) + ":" +
e.startTime.get(Calendar.MINUTE) + " " + e.endTime.get(Calendar.HOUR_OF_DAY)
+ ":" + e.endTime.get(Calendar.MINUTE));
//tempKey = key;
// year = key.get(Calendar.YEAR);
//keys.remove(key);
}
else{
System.out.println(" " + e.eventName + " " + e.startTime.get(Calendar.HOUR_OF_DAY) + ":" +
e.startTime.get(Calendar.MINUTE));
// tempKey = key;
// year = key.get(Calendar.YEAR);
//keys.remove(key);
}
}
tempArr.clear();
//break;
for(GregorianCalendar remove: toRemove){
copyKeys.removeAll(Collections.singleton(remove));
}
for(GregorianCalendar key : copyKeys){
Event value = MyCalendarTester.myCal.getMyCalHash().get(key);
if(tempArr.size() == 0){
if(value.endTime != null){
if(key.get(Calendar.YEAR) == year){
System.out.println(MyCalendarTester.arrayOfDays[key.get(Calendar.DAY_OF_WEEK) - 1] + ", " + MyCalendarTester.arrayOfMonths[key.get(Calendar.MONTH) - 1] + " "
+ key.get(Calendar.DATE) + " " + value.startTime.get(Calendar.HOUR_OF_DAY) + ":" + value.startTime.get(Calendar.MINUTE) + " - " + value.endTime.get(Calendar.HOUR_OF_DAY)
+ ":" + value.endTime.get(Calendar.MINUTE) + " " + value.eventName);
// tempKey = key;
}else{
System.out.println(key.get(Calendar.YEAR));
System.out.println(MyCalendarTester.arrayOfDays[key.get(Calendar.DAY_OF_WEEK) - 1] + ", " + MyCalendarTester.arrayOfMonths[key.get(Calendar.MONTH) - 1] + " "
+ key.get(Calendar.DATE) + " " + value.startTime.get(Calendar.HOUR_OF_DAY) + ":" + value.startTime.get(Calendar.MINUTE) + " - " + value.endTime.get(Calendar.HOUR_OF_DAY)
+ ":" + value.endTime.get(Calendar.MINUTE) + " " + value.eventName );
year = key.get(Calendar.YEAR);
tempKey = key;
}
}else{
if(key.get(Calendar.YEAR) == year){
System.out.println(MyCalendarTester.arrayOfDays[key.get(Calendar.DAY_OF_WEEK) - 1] + ", " + MyCalendarTester.arrayOfMonths[key.get(Calendar.MONTH) - 1] + " "
+ key.get(Calendar.DATE) + " " + value.startTime.get(Calendar.HOUR_OF_DAY) + ":" + value.startTime.get(Calendar.MINUTE) + " " + value.eventName);
tempKey = key;
}else{
System.out.println(key.get(Calendar.YEAR));
System.out.println(MyCalendarTester.arrayOfDays[key.get(Calendar.DAY_OF_WEEK) - 1] + ", " + MyCalendarTester.arrayOfMonths[key.get(Calendar.MONTH) - 1] + " "
+ key.get(Calendar.DATE) + " " + value.startTime.get(Calendar.HOUR_OF_DAY) + ":" + value.startTime.get(Calendar.MINUTE) + " " + value.eventName);
System.out.println();
year = key.get(Calendar.YEAR);
tempKey = key;
}
}
}
}
}
}
I originally have it sorted by the keys (dates) in ascending order. From there, I am looking for any identical dates and sorting them by the time (values). Then, since I've already sorted and printed those days by the time, I don't want to reprint them later. I've been tweaking this for hours to try to get it to cooperate, so perhaps I'm over thinking it at this point. Anyway, if anyone is nice enough to look at this and make a few suggestions, I'd greatly appreciate it. Otherwise, just skip over because this is a long and convoluted one.
There will only be one occurrence of any given object in a Set and that is why only one is being removed.
Sets do not allow duplicates. If you want to allow duplicates, use another data structure such as an ArrayList.

How do I call a InventoryClickEvent in a boolean?

I first created the inventory that will be opened:
private void openGUI(Player player) {
Inventory inv = Bukkit.createInventory(null, 9, ChatColor.DARK_RED + "[" + ChatColor.DARK_GREEN + "DuelRequest" + ChatColor.DARK_RED + "]");
ItemStack accept = new ItemStack(Material.EMERALD_BLOCK);
ItemMeta acceptMeta = accept.getItemMeta();
ItemStack decline = new ItemStack(Material.REDSTONE_BLOCK);
ItemMeta declineMeta = decline.getItemMeta();
acceptMeta.setDisplayName(ChatColor.GREEN + "Accept!");
accept.setItemMeta(acceptMeta);
declineMeta.setDisplayName(ChatColor.RED + "Decline!");
decline.setItemMeta(declineMeta);
inv.setItem(3, accept);
inv.setItem(5, decline);
player.openInventory(inv);
}
Then I created the command that will be run:
if (cmd.getName().equalsIgnoreCase("duel")) {
if (!(args.length == 1)) {
sender.sendMessage(ChatColor.DARK_RED + "[" + ChatColor.DARK_GREEN + "HuntsCraft" + ChatColor.DARK_RED + "]" + ChatColor.RED + " Usage: /duel <Player>");
return true;
} else if (args.length == 1) {
Player p = Bukkit.getServer().getPlayer(args[0]);
if (p != null) {
if (p.equals(sender)) {
sender.sendMessage(ChatColor.DARK_RED + "[" + ChatColor.DARK_GREEN + "HuntsCraft" + ChatColor.DARK_RED + "]" + ChatColor.RED + " You cannot duel yourself!");
return true;
} else {
sender.sendMessage(ChatColor.DARK_RED + "[" + ChatColor.DARK_GREEN + "HuntsCraft" + ChatColor.DARK_RED + "]" + ChatColor.GREEN + " You sent a duel request to " + ChatColor.BLUE + p.getName());
p.sendMessage(ChatColor.DARK_RED + "[" + ChatColor.DARK_GREEN + "HuntsCraft" + ChatColor.DARK_RED + "]" + ChatColor.GREEN + " You recieved a duel request from " + ChatColor.BLUE + sender.getName());
openGUI(p);
}
}
} else {
sender.sendMessage(ChatColor.DARK_RED + "[" + ChatColor.DARK_GREEN + "HuntsCraft" + ChatColor.DARK_RED + "]" + ChatColor.RED + " Player not found!");
}
}
return true;
I Then created an event that is called when a players clicks their inventory.
#SuppressWarnings("deprecation")
#EventHandler
private void onClick(InventoryClickEvent e) {
if (!ChatColor.stripColor(e.getInventory().getName()).equalsIgnoreCase("[DuelRequest]"))
return;
Player player = (Player) e.getWhoClicked();
e.setCancelled(true);
switch (e.getCurrentItem().getType()) {
case EMERALD_BLOCK:
player.closeInventory();
player.sendMessage(ChatColor.DARK_RED + "[" + ChatColor.DARK_GREEN + "HuntsCraft" + ChatColor.DARK_RED + "]" + ChatColor.GREEN + " You accepted the request");
player.getInventory().setItem(0, new ItemStack(Material.DIAMOND_SWORD));
player.getInventory().setItem(1, new ItemStack(Material.BOW));
player.getInventory().setItem(2, new ItemStack(Material.GOLDEN_APPLE, 2));
player.getInventory().setItem(3, new ItemStack(Material.ARROW, 32));
player.getInventory().setHelmet(new ItemStack(Material.DIAMOND_HELMET));
player.getInventory().setChestplate(new ItemStack(Material.DIAMOND_CHESTPLATE));
player.getInventory().setLeggings(new ItemStack(Material.DIAMOND_LEGGINGS));
player.getInventory().setBoots(new ItemStack(Material.DIAMOND_BOOTS));
break;
case REDSTONE_BLOCK:
player.closeInventory();
player.sendMessage(ChatColor.DARK_RED + "[" + ChatColor.DARK_GREEN + "HuntsCraft" + ChatColor.DARK_RED + "]" + ChatColor.RED + " You denied the request!");
break;
default:
player.closeInventory();
break;
}
}
So, what i want to happen is..
When a player types /duel , the (target) will have an inventory opened in front of them with an option to accept or decline the duel request. I have tested this and it works as expected. If they decline they will receive a message telling them they rejected it, if they accept they will be given a Kit to duel with. This also works as expected. However, i need to be able to give the sender of the /duel command the same kit, but i don't know how to. So... When the (target) accepts the duel, both players will receive a kit so they can both fight.
Is there a way of calling for the onClick event inside the onCommand?
Or is there a way to contact the sender of the command from inside the onClick event?
I am average with Bukkit coding but obviously still have a lot to learn so any help/constructive criticism is always helpful!
You could use a HashMap, to store the player that sent the duel request to a player:
Map<UUID, UUID> duels = new HashMap<UUID, UUID>();
HashMaps are used to store a value for another value, it's effectively a large collection of variables.
When the sender runs the command, you could use:
duels.put(target.getUniqueId(), sender.getUniqueId());
So, when the target accepts the duel, you could get the sender of the request with:
duels.get(target.getUniqueId());
Here's what your onCommand() could look like:
if (cmd.getName().equalsIgnoreCase("duel")) {
if (!(args.length == 1)) {
sender.sendMessage(ChatColor.DARK_RED + "[" + ChatColor.DARK_GREEN + "HuntsCraft" + ChatColor.DARK_RED + "]" + ChatColor.RED + " Usage: /duel <Player>");
return true;
} else if (args.length == 1) {
Player p = Bukkit.getServer().getPlayer(args[0]);
if (p != null) {
if (p.equals(sender)) {
sender.sendMessage(ChatColor.DARK_RED + "[" + ChatColor.DARK_GREEN + "HuntsCraft" + ChatColor.DARK_RED + "]" + ChatColor.RED + " You cannot duel yourself!");
return true;
} else {
sender.sendMessage(ChatColor.DARK_RED + "[" + ChatColor.DARK_GREEN + "HuntsCraft" + ChatColor.DARK_RED + "]" + ChatColor.GREEN + " You sent a duel request to " + ChatColor.BLUE + p.getName());
p.sendMessage(ChatColor.DARK_RED + "[" + ChatColor.DARK_GREEN + "HuntsCraft" + ChatColor.DARK_RED + "]" + ChatColor.GREEN + " You recieved a duel request from " + ChatColor.BLUE + sender.getName());
openGUI(p);
//Put the player in the HashMap here
duels.put(p.getUniqueId(), ((Player) sender).getUniqueId());
}
}
} else {
sender.sendMessage(ChatColor.DARK_RED + "[" + ChatColor.DARK_GREEN + "HuntsCraft" + ChatColor.DARK_RED + "]" + ChatColor.RED + " Player not found!");
}
}
return true;
And your onClick() could look like this:
#SuppressWarnings("deprecation")
#EventHandler
//It's better if you make your events public
//and not private
public void onClick(InventoryClickEvent e) {
if (!ChatColor.stripColor(e.getInventory().getName()).equalsIgnoreCase("[DuelRequest]"))
return;
Player player = (Player) e.getWhoClicked();
e.setCancelled(true);
//get the UUID stored in the duels HashMap for the player's UUID as a key
UUID uuid = duels.get(player.getUniqueId());
//Get the challenger from the UUID above
Player challenger = Bukkit.getPlayer(uuid);
switch (e.getCurrentItem().getType()) {
case EMERALD_BLOCK:
player.closeInventory();
player.sendMessage(ChatColor.DARK_RED + "[" + ChatColor.DARK_GREEN + "HuntsCraft" + ChatColor.DARK_RED + "]" + ChatColor.GREEN + " You accepted the request");
player.getInventory().setItem(0, new ItemStack(Material.DIAMOND_SWORD));
player.getInventory().setItem(1, new ItemStack(Material.BOW));
player.getInventory().setItem(2, new ItemStack(Material.GOLDEN_APPLE, 2));
player.getInventory().setItem(3, new ItemStack(Material.ARROW, 32));
player.getInventory().setHelmet(new ItemStack(Material.DIAMOND_HELMET));
player.getInventory().setChestplate(new ItemStack(Material.DIAMOND_CHESTPLATE));
player.getInventory().setLeggings(new ItemStack(Material.DIAMOND_LEGGINGS));
player.getInventory().setBoots(new ItemStack(Material.DIAMOND_BOOTS));
//give the kit to the challenger here
//Maybe make a method, giveKit(Player p), to clean up your code
//Then you could run giveKit(challenger) and giveKit(player)
break;
case REDSTONE_BLOCK:
player.closeInventory();
player.sendMessage(ChatColor.DARK_RED + "[" + ChatColor.DARK_GREEN + "HuntsCraft" + ChatColor.DARK_RED + "]" + ChatColor.RED + " You denied the request!");
//tell the challenger that player denied their duel request
challenger.sendMessage(ChatColor.DARK_RED + "[" + ChatColor.DARK_GREEN + "HuntsCraft" + ChatColor.DARK_RED + "]" + ChatColor.RED + player.getName + " denied your duel request");
break;
default:
player.closeInventory();
break;
}
}
If you wanted to check if a UUID exists in the HashMap, you could use duels.containsKey(uuid)
Make sure to never store Player objects inside of HashMaps, because it can cause memory leaks if the player leaves the server, for instance. The best way to store player information is by storing their UUID, or by storing their username.

If statement always returns false

I have a series of if statements that all seem to work except for when I reach two arguments after a command (Minecraft Bukkit server/API). With two arguments it returns false no matter what. I am using the command /jukebox play 13 to test it.
Current code:
#SuppressWarnings("deprecation")
public boolean onCommand(CommandSender sender, Command cmd, String commandlabel, String[] args) {
Player p = (Player) sender;
if (cmd.getName().equalsIgnoreCase("jukebox")) {
if (args.length == 0) {
sender.sendMessage(ChatColor.GOLD + "** " + ChatColor.AQUA + "Jukebox version " + pdFile.getVersion() + ChatColor.GOLD + " **\n" + ChatColor.RED + "Usage: " + ChatColor.LIGHT_PURPLE + "/jukebox play (track)");
return true;
}
if (args.length == 1) {
if (args[0].equalsIgnoreCase("play")) {
String recordNames = "Stop, 13, Cat, Blocks, Chirp, Far, Mall, Mellohi, Stal, Strad, Ward, 11, Wait";
String regex = "\\[|\\]";
recordNames = recordNames.replaceAll(regex, "");
sender.sendMessage(ChatColor.AQUA + "Track selection: " + ChatColor.GREEN + recordNames + "\n" + ChatColor.AQUA + "Type " + ChatColor.LIGHT_PURPLE + "/jukebox play (track)" + ChatColor.AQUA + " to play a track.");
return true;
}
if (args.length == 2 && (args[0].equalsIgnoreCase("play"))) {
if (args[1].equalsIgnoreCase("13")) {
p.playEffect(p.getLocation(), Effect.RECORD_PLAY, 2256);
sender.sendMessage(ChatColor.AQUA + "Now playing " + ChatColor.GREEN + "13" + ChatColor.AQUA + ".");
return true;
}
else {
sender.sendMessage(ChatColor.AQUA + "Please enter a valid track name.");
}
}
}
}
return false;
}
}
Does anyone see why it is returning false? Just as a side note, if you see anything in here that could be coded more efficiently, feel free to suggest that too.
Your indention is throwing you off. Your closing braces are in the wrong place. Your args.length == 2 check is nested within the args.length ==1 check. At the minimum you will have to :
1. add a closing brace before the if statement for args.length == 2 check
2. delete a closing brace before the return false statement.
It looks like a bracket is in the wrong place:
if (args.length == 1) {
if (args[0].equalsIgnoreCase("play")) {
String recordNames = "Stop, 13, Cat, Blocks, Chirp, Far, Mall, Mellohi, Stal, Strad, Ward, 11, Wait";
String regex = "\\[|\\]";
recordNames = recordNames.replaceAll(regex, "");
sender.sendMessage(ChatColor.AQUA + "Track selection: " + ChatColor.GREEN + recordNames + "\n" + ChatColor.AQUA + "Type " + ChatColor.LIGHT_PURPLE + "/jukebox play (track)" + ChatColor.AQUA + " to play a track.");
return true;
}
should be:
if (args.length == 1) {
if (args[0].equalsIgnoreCase("play")) {
String recordNames = "Stop, 13, Cat, Blocks, Chirp, Far, Mall, Mellohi, Stal, Strad, Ward, 11, Wait";
String regex = "\\[|\\]";
recordNames = recordNames.replaceAll(regex, "");
sender.sendMessage(ChatColor.AQUA + "Track selection: " + ChatColor.GREEN + recordNames + "\n" + ChatColor.AQUA + "Type " + ChatColor.LIGHT_PURPLE + "/jukebox play (track)" + ChatColor.AQUA + " to play a track.");
return true;
}
}
notice the } at the end. Right now, you're code is doing this:
if(args.length == 1){
if(args.length > 1 && args[0].equalsIgnoreCase("play")){
}
}
which will always return false, as args cannot have a length of one, and also have a length greater than one
As other's have said, you've gotten the bracket nesting wrong, and your incorrect code indentation is misleading you.
Advice ... if you want to avoid this kind of problem in the future:
Pay more attention to your code style in general, and particularly indentation. It makes your code easier for >>you<< to read.
Use an IDE ... or a smart editor that is capable of correctly indenting Java. And make sure that you make use of its auto-indenting functionality.
If possible, configure your IDE / editor to use space characters not TAB characters for code indentation. If your code has TAB characters in it, then it will look different (i.e. incorrectly indented) on different systems.
As shoover pointed out the } for the if (args.length == 1) statement was in the wrong place.
The new code is:
#SuppressWarnings("deprecation")
public boolean onCommand(CommandSender sender, Command cmd, String commandlabel, String[] args) {
Player p = (Player) sender;
if (cmd.getName().equalsIgnoreCase("jukebox")) {
if (args.length == 0) {
sender.sendMessage(ChatColor.GOLD + "** " + ChatColor.AQUA + "Jukebox version " + pdFile.getVersion() + ChatColor.GOLD + " **\n" + ChatColor.RED + "Usage: " + ChatColor.LIGHT_PURPLE + "/jukebox play (track)");
return true;
}
if (args.length == 1) {
if (args[0].equalsIgnoreCase("play")) {
String recordNames = "Stop, 13, Cat, Blocks, Chirp, Far, Mall, Mellohi, Stal, Strad, Ward, 11, Wait";
String regex = "\\[|\\]";
recordNames = recordNames.replaceAll(regex, "");
sender.sendMessage(ChatColor.AQUA + "Track selection: " + ChatColor.GREEN + recordNames + "\n" + ChatColor.AQUA + "Type " + ChatColor.LIGHT_PURPLE + "/jukebox play (track)" + ChatColor.AQUA + " to play a track.");
return true;
}
}
if (args.length > 1 && (args[0].equalsIgnoreCase("play"))) {
if (args[1].equalsIgnoreCase("13")) {
p.playEffect(p.getLocation(), Effect.RECORD_PLAY, 2256);
sender.sendMessage(ChatColor.AQUA + "Now playing " + ChatColor.GREEN + "13" + ChatColor.AQUA + ".");
return true;
}
else {
sender.sendMessage(ChatColor.AQUA + "Please enter a valid track name.");
return true;
}
}
}
return false;

Storing part of method as another method?

Basically, I have code that uses the same few lines in different scenarios, and it makes the code a bit messy (especially since I probably overcomplicated what I made, but that's another issue). What I wanted to do is store that piece of code as another function and calling it in the longer one. WHich should work as far as I know, except, the longer function has variables that aren't set in the shorter one, and if they were, I'm pretty sure it would change the final result of the function.
Here is the longer code:
public static void combat(Character a,Character b){
int battleturn = 1;
int maxTurns=20;
int draw1 = 0;
//stop after 20 turns, or stop when one player has 0 HP.
while (a.health > 0 && b.health > 0 && maxTurns > 0){
/* run a round of combat*/
if (b.health < 0.25 * b.maxHealth){
if (b.getFlee(a)){
System.out.println(">>>>>>>>>>The enemy has fled successfully<<<<<<<<<<");
break;
}else{
System.out.println("Battle turn " + battleturn + ", <attack> or <flee>?");
Scanner input = new
Scanner(System.in);
String move = input.next();
while(!move.equals("attack") && !move.equals("flee")){
System.out.println("Error: Please input <attack> or <flee>.");
input = new Scanner(System.in);
move = input.next();
}
if (move.equals("attack")){
System.out.println(a.name + " dealt " + a.combatRound(b) + " damage to " + b.name + "." + " Enemy has "
+ b.getHealth() + "/" + b.getMaxHealth() + " health.");
System.out.println(b.name + " dealt " + b.combatRound(a) + " damage to " + a.name + "." + " You have " +
a.getHealth() + "/" + a.getMaxHealth() + " health");
maxTurns--;
battleturn++;
}else if(move.equals("flee")){
if (a.getFlee(b)){
draw1++;
System.out.println(">>>>>>>>>>You have fled!<<<<<<<<<<");
break;
}else{
System.out.println(a.name + " dealt " + a.combatRound(b) + " damage to " + b.name + "." + " Enemy has " +
b.getHealth() + "/" + b.getMaxHealth() + " health.");
System.out.println(b.name + " dealt " + b.combatRound(a) + " damage to " + a.name + "." + " You have " +
a.getHealth() + "/" + a.getMaxHealth() + " health");
maxTurns--;
battleturn++;
}
}
}
}else{
System.out.println("Battle turn " + battleturn + ", <attack> or <flee>?");
Scanner input = new
Scanner(System.in);
String move = input.next();
while(!move.equals("attack") && !move.equals("flee")){
System.out.println("Error: Please input <attack> or <flee>.");
input = new Scanner(System.in);
move = input.next();
}
if (move.equals("attack")){
System.out.println(a.name + " dealt " + a.combatRound(b) + " damage to " + b.name+ "." + " Enemy has " +
b.getHealth() + "/" + b.getMaxHealth() + "health.");
System.out.println(b.name + " dealt " + b.combatRound(a) + " damage to " + a.name + "." + " You have " +
a.getHealth() + "/" + a.getMaxHealth() + " health");
maxTurns--;
battleturn++;
}else if(move.equals("flee")){
if (a.getFlee(b)){
draw1++;
System.out.println(">>>>>>>>>>You have fled!<<<<<<<<<<");
break;
}else{
System.out.println(a.name + " dealt " + a.combatRound(b) + " damage to " + b.name+ "." + " Enemy has " +
b.getHealth() + "/" + b.getMaxHealth() + " health.");
System.out.println(b.name + " dealt " + b.combatRound(a) + " damage to " + a.name + "." + " You have " +
a.getHealth() + "/" + a.getMaxHealth() + " health");
maxTurns--;
battleturn++;
}
}
}
}
}
As you can see there is a part of code that is repeated, and that is.
System.out.println("Battle turn " + battleturn + ", <attack> or <flee>?");
Scanner input = new
Scanner(System.in);
String move = input.next();
while(!move.equals("attack") && !move.equals("flee")){
System.out.println("Error: Please input <attack> or <flee>.");
input = new Scanner(System.in);
move = input.next();
}
if (move.equals("attack")){
System.out.println(a.name + " dealt " + a.combatRound(b) + " damage to " + b.name + "." + " Enemy has "
+ b.getHealth() + "/" + b.getMaxHealth() + " health.");
System.out.println(b.name + " dealt " + b.combatRound(a) + " damage to " + a.name + "." + " You have " +
a.getHealth() + "/" + a.getMaxHealth() + " health");
maxTurns--;
battleturn++;
}else if(move.equals("flee")){
if (a.getFlee(b)){
draw1++;
System.out.println(">>>>>>>>>>You have fled!<<<<<<<<<<");
break;
}else{
System.out.println(a.name + " dealt " + a.combatRound(b) + " damage to " + b.name + "." + " Enemy has " +
b.getHealth() + "/" + b.getMaxHealth() + " health.");
System.out.println(b.name + " dealt " + b.combatRound(a) + " damage to " + a.name + "." + " You have " +
a.getHealth() + "/" + a.getMaxHealth() + " health");
maxTurns--;
battleturn++;
}
}
}
It won't compile if I set that chunk of code as a method, because it doesn't have the variables battleturn, maxturns, draw1, but if I put them in there, the amount of battle turns messes up.
Any ideas?
Java applications should be modular: each class fulfilling its own function, each method generally performing a single operation.
In a method you can use either class variables or its own local variables.
If you need several methods work with the same data, it should either be part of a class (instance and/or static variables) or passed to each method as parameters.
Make sure that you do not define class variables in a method. This will create local variables that will shadow class variables.
This might help you accomplish what you're trying to do.
private static void reportDamage(Character a,
Character b) {
System.out.println(a.name + " dealt "
+ a.combatRound(b) + " damage to " + b.name
+ "." + " Enemy has " + b.getHealth() + "/"
+ b.getMaxHealth() + " health.");
}
I suggest changing your combat method like this.
int battleturn = 0;
int maxTurns = 20;
// stop after 20 turns, or stop when one player has 0
// HP.
Scanner input = new Scanner(System.in);
try {
while (a.health > 0 && b.health > 0
&& battleturn < maxturn) {
battleturn++;
/* run a round of combat */
if (b.getFlee(a)) {
System.out.println(">>>>>>>>>>"
+ "The enemy has fled successfully"
+ "<<<<<<<<<<");
break;
} else {
System.out.println("Battle turn "
+ battleturn + ", <attack> or <flee>?");
boolean isFlee = false;
boolean isAttack = false;
String move = input.next();
for (;;) {
isAttack = "attack".equalsIgnoreCase(move);
isFlee = "flee".equalsIgnoreCase(move);
if (isFlee || isAttack) {
break;
}
System.out.println("Error: "
+ "Please input <attack> or <flee>.");
move = input.next();
}
if (isAttack) {
reportDamage(a, b);
reportDamage(b, a);
} else { // isFlee
if (a.getFlee(b)) {
System.out.println(">>>>>>>>>>"
+ "You have fled successfully"
+ "<<<<<<<<<<");
break;
} else {
// b is fleeing.
// reportDamage(a, b);
reportDamage(b, a);
}
}
}
}
} finally {
input.close();
}

Categories

Resources