Configuration Résolu (Go direct à la page 4)Java : Check si un joueur est dans une zone

Alex Fatta

Commandant de la Flotte et de la Horde
13 Août 2014
1 391
1
191
187
Yo les gens ! :D

@DiscowZombie toi qui connait le contexte de mon code xD Tu es + convié, mais toutes personne qui a un avis est bien évidemment la bienvenue.

Je cherche donc à savoir si un joueur est dans une zone lorsqu'il pose un block. Ces zones en questions je les définies par une commande et les coordonnées des extrémités de cette zone (x1, x2, z1, z2) sont stockées dans un fichier .yml. Quand mon plugin s'allume, je charge ces données dans une HashMap :

Code:
Bases:
  rouge:
    world: world
    x1: 183
    x2: 213
    z1: 269
    z2: 299

Code:
    @Override
    public void onEnable() {
         saveDefaultConfig();
         for (String s : getConfig().getStringList("Bases")) {
             new LocationManager(s).add(getConfig().getString("Bases."+s+".world"), getConfig().getInt("Bases."+s+".x1"),
                     getConfig().getInt("Bases."+s+".x2"), getConfig().getInt("Bases."+s+".z1"), getConfig().getInt("Bases."+s+".z2"));
         }
       
    }

HashMap en question :
Code:
private static HashMap<String, LocSaver> bases = new HashMap<>();

Code:
package fr.alexfatta.fallenkingdoms.getDataBases;

public class LocSaver {
    
    private String worldname;
    private int x1, x2, z1, z2;
    
    public LocSaver(String worldname, int x1, int x2, int z1, int z2){
        this.worldname = worldname;
        this.x1 = x1;
        this.x2 = x2;
        this.z1 = z1;
        this.z2 = z2;
    }

Code:
package fr.alexfatta.fallenkingdoms.getDataBases;

import java.util.HashMap;

public class LocationManager {
    
    private static HashMap<String, LocSaver> bases = new HashMap<>();
    
    private String name;

    
    public LocationManager(String name) {
        this.name = name;
    }
    
    public void add(String worldname, int x1, int x2, int z1, int z2) {
        getBases().put(name, new LocSaver(worldname, x1, x2, z1, z2));
    }

    public static HashMap<String, LocSaver> getBases() {
        return bases;
    }

    public static void setBases(HashMap<String, LocSaver> bases) {
        LocationManager.bases = bases;
    }
}

Voilà vous avez donc les éléments nécéssaires à la compréhension de ma demande.

Donc, ce que je cherche à faire, c'est que quand un joueur pose un block, le plugin regarde si le joueur est dans l'une des zones contenues dans le fichier.yml donc dans la HashMap. J'ai donc essayé le code suivant, qui ne me sort pas d'erreur mais qui ne fonctionne pas. Je tient à dire que j'ai essayé plusieurs syntaxe dont la même que contient le onEnable mais j'avais une erreur. Donc si vous voyez des erreurs, si vous avez des suggestions de modif à faire ou même des questions,
Code:
package fr.alexfatta.fallenkingdoms.managers;


import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.inventory.EquipmentSlot;

import fr.alexfatta.fallenkingdoms.main;
import fr.alexfatta.fallenkingdoms.getDataBases.LocationManager;


public class BlockPlaceManager implements Listener {
   
    @EventHandler (ignoreCancelled = true, priority = EventPriority.LOWEST)
    public void onBlockPlace(BlockPlaceEvent event) {
       
        final Player player = event.getPlayer();
        Block block_to_replace = event.getBlockPlaced();
       
        if (playerInArea(player) == false) {
           
            if (event.getHand() == EquipmentSlot.HAND) {
                if (player.getInventory().getItemInMainHand().getType() == Material.TORCH ||
                        player.getInventory().getItemInMainHand().getType() == Material.TNT ||
                        player.getInventory().getItemInMainHand().getType() == Material.REDSTONE_TORCH_ON ||
                        player.getInventory().getItemInMainHand().getType() == Material.WATER_BUCKET ||
                        player.getInventory().getItemInMainHand().getType() == Material.ENDER_CHEST ||
                        player.getInventory().getItemInMainHand().getType() == Material.SIGN) {
                   
                } else {
                    block_to_replace.setType(Material.AIR);
                }
            }
        }  
    }
   
    public main main;
   
    public boolean playerInArea(Player player) {
        int x1, x2, z1, z2;
        String world;
       
        //Object myKey = statusName.keySet().toArray()[0];
        for (int k = 0; k < LocationManager.getBases().size(); k++) {
            x1 = main.getConfig().getInt("Bases."+LocationManager.getBases().get(k)+".x1");
            x2 = main.getConfig().getInt("Bases."+LocationManager.getBases().get(k)+".x2");
            z1 = main.getConfig().getInt("Bases."+LocationManager.getBases().get(k)+".z1");
            z2 = main.getConfig().getInt("Bases."+LocationManager.getBases().get(k)+".z2");
            world = main.getConfig().getString("Bases."+LocationManager.getBases().get(k)+".world");
           
            if (!(player.getLocation().getX() > x1) && !(player.getLocation().getX() < x2) &&
                    !(player.getLocation().getZ() > z1) && !(player.getLocation().getZ() < z2) && !(player.getWorld().getName() == world)) {
                player.sendMessage(fr.alexfatta.fallenkingdoms.main.getGamePrefix() +
                        ChatColor.RED + "Erreur : tu ne peux pas poser ce block !");
                return false;
            }
        }
        return true;
    }
   
}
N'hésitez pas !!! :D

AlexFatta
 

Alex Fatta

Commandant de la Flotte et de la Horde
13 Août 2014
1 391
1
191
187
Re !

Donc je viens de visionner la vidéo. Donc ok il gère les zones je modifierai mon code. Par contre, il gère les zones manuellement, c'est à dire qu'il définit dans sa class principale le nom de ses zones or ce que je voudrait ce serait que ces zones soient chargées depuis la HashMap (parce que depuis le fichier de config ca marche pas dans une autre class aec ta boucle for @DiscowZombie je ne sais pourquoi). Donc sois faire ça dans le main ce que je ne voudrai pas, sois lire les données de la première colonne de la HashMap.

AlexFatta
 

DiscowZombie

Développeur
Staff
Modérateur
Support
2 Mars 2017
2 659
1
931
298
Alsace
www.discowzombie.fr
(parce que depuis le fichier de config ca marche pas dans une autre class aec ta boucle for @DiscowZombie je ne sais pourquoi)
Je n'ait pas bien compris mais si tu me donne plus de détails, je peut peut-être t'aider :D

sois lire les données de la première colonne de la HashMap.
Oui tu peut, il te suffit de bien adapté ça pour que ça fonctionne avec ton code ;) Son code est assez court et tu devrait pouvoir l'adapter au tien sans trop de difficultés :p
 
Dernière édition:

Alex Fatta

Commandant de la Flotte et de la Horde
13 Août 2014
1 391
1
191
187
Re !

Oui tu peut, il te suffit de bien adapté ça pour que ça fonctionne avec ton code ;) Son code est assez court et tu devrait pouvoir l'adapter au tien sans trop de difficultés :p
Mais justement c'est ça que je ne sais pas faire xDD D'où mon premier message qui vous montre le code que j'ai fait et qui ne fonctionne pas et je cherche à savoir pourquoi ;) C'est ça ma demande à la base x)

Je n'ait pas bien compris mais si tu me donne plus de détails, je peut peut-être t'aider
En fait la boucle for qui se site dans le onEnable elle fonctionne (enfin je pense j'ai jamais regardé si elle faisait son taff mais y'a pas d'erreur donc je pense que oui). Eh bien cette boucle for je l'ai mise dans mon BlockPlaceManager sous la forme :
Code:
for (String s : main.getConfig().getStringList("Bases"))

Sauf que ca fonctionnait pas, j'avais une erreur dans la console longue comme.... le bras qui me mettait un NullPointerException sur la ligne de la boucle for.

AlexFatta
 

DiscowZombie

Développeur
Staff
Modérateur
Support
2 Mars 2017
2 659
1
931
298
Alsace
www.discowzombie.fr
Mais justement c'est ça que je ne sais pas faire xDD D'où mon premier message qui vous montre le code que j'ai fait et qui ne fonctionne pas et je cherche à savoir pourquoi ;) C'est ça ma demande à la base x)
Ha oui, houla, on s'est bien éloigné xD Je vais te donner quelques pistes, mais vu que je suis sur téléphone cava pas être fameux ;)

En réalité, tu peut utiliser sa class toute faite (https://pastebin.com/4xZFaVAj). Du coup, le plus simple serait de créér un 'getter' pour récupérer ton HashMap:
Code:
//Dans ta class LocationManager
public HashMap... getRegions(){
return this.bases;
}

Il faut aussi que tu créé ceci :
Code:
//Toujours dans LocationManager
public LocationManager(){}

Ensuite, tu peut
Code:
//Tu peut faire ça de n'importe quel class, pratique ;)
new LocationManager().getRegions();

Maintenant que tu as ceci, petit boucle for pour testé s'il est dans une région :
Code:
//Tu peut faire ça dans ton block break ou le mettre dans une  méthode
for(LocSaver l : LocationManager().getRegions().values()){
//Je crois que c'est .values(), je te laisse vérifier
//Tu créer tes locations à partir de tes coordonnées de région
boolean isInRegion = new Cuboide(new Location(l.getWorld(), l.getX1(), 0, l.getZ1()), new Location(l.getWorld(), l.getX2(), 0, l.getZ2())).isInCuboid(Ton Player);
if(isInRegion){
//Si il est dans une region, tu peut cancel le placement ou faire ce que tu veut...
}
}

Désolé pour le code fait complètement à l'arrache, pas facile sur Mobile ;)


Sauf que ca fonctionnait pas, j'avais une erreur dans la console longue comme.... le bras qui me mettait un NullPointerException sur la ligne de la boucle for.
Ha ! Ne prends pas peurs des NPE, c'est des erreurs toutes bêtes qui se corrige super facilement ;) (bien qu'un peu chiante à la longue). C'est sûrement que ton main devait être null :)
 
Dernière édition:
  • J'aime
Reactions: Alex Fatta

Alex Fatta

Commandant de la Flotte et de la Horde
13 Août 2014
1 391
1
191
187
Re !

Alors en premier merci d'avoir pris le temps de faire ça :p Mais là encore le problème n'est pas résolu @DiscowZombie xDDDD Tu me dit :
//Tu créer tes locations à partir de tes coordonnées de région
Je veux bien MAIS ces données sont la HashMap, deuxième colonne. Et ma question depuis le début c'est comment je fais pour prendre ces données (que ce soit première ou deuxième colonne ?) xDDDDD

Je ne sais pas si tu as donné la réponse à ce que je cherchais dans ce que tu as donné (c'est que je suis vraiment pas dégourdi dans ce cas xDDD).

Voilà est-ce que tu as compris mon problème xDD En fait ce que je voudrais ce serais faire l'équivalence d'un tabl[1]m pour prendre la deuxième colonne du tableau mais avec la HashMap. Do you dunderstanditiit ? xD

AlexFatta
 

DiscowZombie

Développeur
Staff
Modérateur
Support
2 Mars 2017
2 659
1
931
298
Alsace
www.discowzombie.fr
Re !

Je commence à me demander si on parle la même langue xDD

Si tu as fait ça, tu peut récupérer ta Map facilement :
Code:
//Dans ta class LocationManager
public HashMap... getRegions(){
return this.bases;
}
Il faut aussi que tu créé ceci :
Code:
//Toujours dans LocationManager
public LocationManager(){}
Pour récupérer la Map :
Code:
new LocationManager().getRegions();


Tu peut récupérer toutes les valeurs de la Map (colonne 1 et deux (aussi appelé 'entry')) en faisant :
Code:
new LocationManager().getRegions().entrySet();
Tu peut aussi récupérer uniquement la colonne 1 (appeler 'key') :
Code:
new LocationManager().getRegions().keySet();
Tu peut aussi récupérer uniquement la colonne 2 (appelé 'values') :
Code:
new LocationManager().getRegions().values();

Voilà j'espère que c'est ce que tu cherchais :D
 

Alex Fatta

Commandant de la Flotte et de la Horde
13 Août 2014
1 391
1
191
187
Re re ! (Ca peut durer des heures xD)

Je commence à me demander si on parle la même langue xDD
C'est en effet une bonne questions ! x)

Re !

Je commence à me demander si on parle la même langue xDD

Si tu as fait ça, tu peut récupérer ta Map facilement :
Code:
//Dans ta class LocationManager
public HashMap... getRegions(){
return this.bases;
}
Il faut aussi que tu créé ceci :
Code:
//Toujours dans LocationManager
public LocationManager(){}
Pour récupérer la Map :
Code:
new LocationManager().getRegions();


Tu peut récupérer toutes les valeurs de la Map (colonne 1 et deux (aussi appelé 'entry')) en faisant :
Code:
new LocationManager().getRegions().entrySet();
Tu peut aussi récupérer uniquement la colonne 1 (appeler 'key') :
Code:
new LocationManager().getRegions().keySet();
Tu peut aussi récupérer uniquement la colonne 2 (appelé 'values') :
Code:
new LocationManager().getRegions().values();

Voilà j'espère que c'est ce que tu cherchais :D
  • Dac ! Donc je reprends ce que je disais, je cite : "Je suis pas très dégourdi" xDDDD
Je suis un vrai boulet xDD Faut dire que les HashMap j'ai pas trouvé de cour complet de A a Z. J'ai trouvé sur open classroom et cherche notamment sur stack overflow et je me doutais que y avais un truc avec "key" sauf que comme ca marchais pas dans mes premiers essais bah j'ai changé l'idée x) Ok donc j'ai ce que je cherchais ! (Je me rend compte que c'était sous mon nez depuis le début en fait xD je me déprime tout seul x) )

Bon eh bien écoute je testerai et incorporerai tout ça demain !! :D Du coup j'ai plein d'idée de chose à faire ça !! :D

Je te remercie et on verra demain si sujet résolu ou pas :p !! :D Thanks brother !! :D

AlexFatta
 

DiscowZombie

Développeur
Staff
Modérateur
Support
2 Mars 2017
2 659
1
931
298
Alsace
www.discowzombie.fr
Bon eh bien écoute je testerai et incorporerai tout ça demain !! :D Du coup j'ai plein d'idée de chose à faire ça !! :D

Je te remercie et on verra demain si sujet résolu ou pas :p !! :D Thanks brother !! :D
Pas de soucis, je me perds de te souhaiter une bonne nuit, il me semble que ton cerveau en a besoin :D

À demain xD À toute à l'heure (il est plus que minuit, on est déjà 'demain' xD)
 
  • J'aime
Reactions: Alex Fatta