Plugin Résolu Java : plugin de freeze

Salut,

Au lieu de faire un
Code:
event.setCancel(true)
Je pense que tu as plus intérêt à teleporter le joueur :)
En gros au moment où tu fais la commande tu enregistres la Location du joueur et chaque fois qu'il bouge tu le teleporte à cet endroit la (sans cancel sinon tu pourra pas le tp).


Cordialement,
Detobel36
 
Salut,

Au lieu de faire un
Code:
event.setCancel(true)
Je pense que tu as plus intérêt à teleporter le joueur :)
En gros au moment où tu fais la commande tu enregistres la Location du joueur et chaque fois qu'il bouge tu le teleporte à cet endroit la (sans cancel sinon tu pourra pas le tp).


Cordialement,
Detobel36
Bonjour @Detobel36 :D

J'ai mis à jour le code, il a pas mal changé mais cette fois-ci le joueur peut sauter (j'ai essayé les 2 codes mais aucune ne marche complètement)
PHP:
package com.freeze.fr;


import java.util.ArrayList;

import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.plugin.java.JavaPlugin;


public class main extends JavaPlugin implements Listener{
    
    public void onEnable(){
        System.out.println("Plugin de freeze actif !");
        getCommand("freeze").setExecutor(this);
        getCommand("unfreeze").setExecutor(this);
        Bukkit.getServer().getPluginManager().registerEvents(this, this);
    }
    
    public void onDisable(){
        System.out.println("Plugin de freeze inactif !");
    }
    
    ArrayList<Player> frozen = new ArrayList<Player>();

    
    public void onPlayerMoveEvent(PlayerMoveEvent e){
        Player p = e.getPlayer();
        if(frozen.contains(p)){
            Location loc = new Location(p.getWorld(), p.getLocation().getX(), p.getLocation().getY(), p.getLocation().getZ());
            p.teleport(loc);
            p.sendMessage("§cTu es freeze !");
            }
        }
    
    public void onDamage(EntityDamageEvent d){
        if(frozen.contains(d)){
            d.setCancelled(true);
        }
    }
    
    @Override
    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
        
        Player p = (Player) sender;
        
        if(label.equalsIgnoreCase("freeze") && sender instanceof Player){
            if(args.length==1){
                Player f = Bukkit.getPlayer(args[0]); //freeze
                if(f == null){
                    return false;
                }else {
                    f.setWalkSpeed(0);
                    f.sendMessage("§cTu as été freeze par " + ChatColor.RED + p.getName());
                    frozen.add(f);
                }
                p.sendMessage("§2" + args[0] + " a été freeze !");
                return true;
            }
            
        }else if(label.equalsIgnoreCase("unfreeze") && sender instanceof Player){
            if(args.length==1){
                Player f = Bukkit.getPlayer(args[0]); //unfreeze
                if(f == null){
                    return false;
                }else {
                    f.setWalkSpeed((float) 0.2);
                    f.sendMessage("§2Tu as été unfreeze par " + ChatColor.RED + p.getName());
                    frozen.remove(f);
                }
                p.sendMessage("§2" + args[0] + " a été unfreeze !");
                return true;
            }
        }

        return false;
    }
    

}

Même ceci ne marche pas :(

PHP:
    public void onPlayerMoveEvent(PlayerMoveEvent e){
        Player p = e.getPlayer();
        if(frozen.contains(p)){
            Location loc = new Location(p.getWorld(), p.getLocation().getX(), p.getLocation().getY(), p.getLocation().getZ());
            p.teleport(loc);
            p.sendMessage("§cTu es freeze !");
            }
        }

J'ai enlevé l'effet de potion de jump boost à 128 (si je le remet ca empêchera juste le joueur de sauter mais il pourra quand même se déplacer en faisant des micro-sauts :/ )

Là je suis vraiment bloqué xD

Je sais pas si c'est bien clair ce que je dit xD Si tu as des questions pour que t'éclairer n'hésites pas xD

AlexFatta
 
J'ai crée la location à la ligne 59:
PHP:
Location loc = new Location(po.getWorld(), po.getLocation().getBlockX(), po.getLocation().getBlockY(), po.getLocation().getBlockZ());

PHP:
if(label.equalsIgnoreCase("freeze") && sender instanceof Player){
            if(args.length==1){
                Player po = Bukkit.getPlayer(args[0]); //freeze
                if(po == null){
                    return false;
                }else {
                    Location loc = new Location(po.getWorld(), po.getLocation().getBlockX(), po.getLocation().getBlockY(), po.getLocation().getBlockZ());
                    po.setWalkSpeed(0);
                    po.sendMessage("§cTu as été freeze par " + ChatColor.RED + p.getName());
                    frozen.add(po);
                    po.teleport(loc);
                }
                p.sendMessage("§2" + args[0] + " a été freeze !");
                return true;
            }

Mais dans mon OnMoveEvent, comment je relis cette location loc à l'event ? :/

AlexFatta

[Messages Fusionnés]

Oui je sais double post c'est pour la notification x) @Detobel36

PHP:
    public void onPlayerMoveEvent(PlayerMoveEvent e){
        Player p = e.getPlayer();
        if(frozen.contains(p)){
            p.teleport();
            p.sendMessage("§cTu es freeze !");
            }
        }

Cette partie est bien sûr à mettre en relation avec le message précédent.

Le p.teleport est en rouge. Evidemment puisqu'il n'a pas de location appropriée. Mais la question est la suivante : comment attribuer une location a p.teleport(); alors que la location en question est définie dans une commande bien plus bas et qui est indépendante. J'ai bien chercher pour faire un public void mais là encore je me retrouve bloqué : je ne peux pas définir le "world" ni même le p.getWorld(); puisque le p n'est pas définie (ou alors pas sur le joueur en question) et le getWorld prendrai ne pas prendre le bon monde en question. Je suis vraiment bloqué :/ Comment je peux définir la location ? :)

AlexFatta
 
Dernière édition par un modérateur:
Salut,

Une class peut avoir un attribut. Il s'agit donc d'une variable qui sera commun à toutes les méthodes se trouvant dans cette class. Tu peux également avoir des attributs ou des méthodes static, cela signifie qu'elles n'appartiennent pas à une instance (un "new" que tu aurais fait sur cet objet) mais seulement à la class/le fichier en elle/lui-même.

En d'autres mots, tu peux faire ceci:
PHP:
class Test {

    private static int valeur1 = 10;
    private int valeur2;

    public Test(int newValeur) {
        valeur2 = newValeur;
    }

    private void fonction1() {
        System.out.println("Résultat: " + (Test.valeur1 + this.valeur2));
    }

    public static int getValeur1() {
        return valeur1;
    }

}

Au lieu d'expliquer, je vais essayer de te montrer:
PHP:
Test classTest1 = new Test(1);
Test classTest10 = new Test(10);

classTest1.fonction1(); // Affiche 11
classTest10.fonction1(); // affiche 20

System.out.println(Test.getValeur1()); // affiche 10

Le code ici met plus en évidence ce qu'est une variable static bien que ce ne soit pas ce qui nous intéresse ici. Je m'en rend compte maintenant, "my bad"... Je vais pas supprimer tout ça, ça peut te servir. Bref, revenons à ton problème (car la je me suis égaré).

Essayons d'abord d'écrire ce qu'on veut faire (la logique):
  • Lorsque l'on fait la commande, il faut que l'on enregistre que le joueur doit être "freeze" mais également sa position
  • Lorsque le joueur essaye de se déplacer, il faut regarde s'il doit être freeze et le retéléporté à sa position de départ
  • Lorsque l'on refait cette commande, on doit supprimer le joueur de la liste des personnes "freeze".

Que dirais-tu de sauvegarder en même temps, la "location" où le joueur est au moment où tu fais la commande et le joueur à freeze ? Cela signifie qu'au lieu d'utiliser une ArrayList, on va utiliser un HashMap.

Plus précisément, on va avoir ça:
PHP:
package com.freeze.fr;
// DETO: Déjà la, il y a un truc qui cloche... La convention c'est: pays.pseudo.projet
// Exemple: be.detobel36.superprojet


import java.util.ArrayList;

import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.plugin.java.JavaPlugin;


// DETO: pour les gros projet, il vaut mieux séparer le listener et le main.  Car le main doit être
// le plus petit possible
public class main extends JavaPlugin implements Listener{
  
    public void onEnable() {
        // DETO: Au lieu d'utiliser des "System.out...", il vaut mieux utiliser un getLogger()
        // Car le systeme.out c'est pour java et le Logger est adatpé à bukkit
        System.out.println("Plugin de freeze actif !");
        getCommand("freeze").setExecutor(this);
        getCommand("unfreeze").setExecutor(this);
        Bukkit.getServer().getPluginManager().registerEvents(this, this);
    }
  
    public void onDisable() {
        System.out.println("Plugin de freeze inactif !");
    }
  
    // DETO: ça c'est un attribut.  Il vaut mieux devant mettre s'il est "private", "protected" ou
    // "public"
    // Je te conseil également de le mettre tout en haut, car en plein milieu, il risque de se "perdre"
    // dans la masse
    ArrayList<Player> frozen = new ArrayList<Player>();

  
    public void onPlayerMoveEvent(PlayerMoveEvent e) {
        // DETO: les variables doivent être le plus parlante possible.  "e" et "p" ça veut rien dire
        // ça coute pas grand chose d'écrire "event" ou "player"
        Player p = e.getPlayer();
        if(frozen.contains(p)){
            // DETO: Pourquoi ne pas faire un Location loc = p.getLocation() ?  au final ici tu ne
            // fais rien... c'est complètement inutile
            Location loc = new Location(p.getWorld(), p.getLocation().getX(), p.getLocation().getY(), p.getLocation().getZ());
            p.teleport(loc);
            p.sendMessage("§cTu es freeze !");
    // DETO: attention au alignement d'accolade (j'ai corrigé)
        }
    }
  
    // DETO: Encore une fois, "d" ça veut rien dire
    public void onDamage(EntityDamageEvent d) {
        if(frozen.contains(d)){
            d.setCancelled(true);
        }
    }
  
    @Override
    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
        // DETO: qui te dis que c'est obligatoirement un player ?  Tu test ça dans le "if" après...
        // pourquoi déjà le convertir alors que tu ne sais même pas si c'est le cas
        Player p = (Player) sender;
      
        if(label.equalsIgnoreCase("freeze") && sender instanceof Player){
            if(args.length==1){
                Player f = Bukkit.getPlayer(args[0]); //freeze
                if(f == null){
                    return false;
                }else {
                    f.setWalkSpeed(0);
                    // DETO: Reste logique avec toi même... tu met des "§c" partout et la tu met un
                    // ChatColor... c'est pas logique tout ça
                    f.sendMessage("§cTu as été freeze par " + ChatColor.RED + p.getName());
                    frozen.add(f);
                }
                p.sendMessage("§2" + args[0] + " a été freeze !");
                return true;
            }
          
        }else if(label.equalsIgnoreCase("unfreeze") && sender instanceof Player){
            if(args.length==1){
                Player f = Bukkit.getPlayer(args[0]); //unfreeze
                if(f == null){
                    return false;
                }else {
                    f.setWalkSpeed((float) 0.2);
                    f.sendMessage("§2Tu as été unfreeze par " + ChatColor.RED + p.getName());
                    frozen.remove(f);
                }
                p.sendMessage("§2" + args[0] + " a été unfreeze !");
                return true;
            }
        }

        return false;
    }

    // DETO: à quel moment tu vérifies que le joueur a déjà été freeze ?
  
}


Bon, maintenant la "correction" (enfin, une correction possible... Car il y a autant de code qu'il n'y a de développeur)


PHP:
package com.freeze.fr;
// DETO: Je te laisse corriger tes packages toi même


import java.util.ArrayList;

import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.entity.Entity; // ajout d'un import
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.plugin.java.JavaPlugin;


// Je vais pas split le fichier en deux, mais regarde bien la remarque du code précédent
public class main extends JavaPlugin implements Listener{
  
    // On change donc le ArrayList en HashMap
    private HashMap<Player, Location> frozenPlayerAndLocation = new HashMap<>();

  
    public void onEnable() {
        getLogger().info("Plugin de freeze actif !");
        getCommand("freeze").setExecutor(this);
        getCommand("unfreeze").setExecutor(this);
        Bukkit.getServer().getPluginManager().registerEvents(this, this);
    }

  
    public void onDisable() {
        getLogger().info("Plugin de freeze inactif !");
    }
  

    public void onPlayerMoveEvent(PlayerMoveEvent event) {
        Player player = e.getPlayer();
        if(frozenPlayerAndLocation.containsKey(player)) {
            Location loc = frozenPlayerAndLocation.get(player);
            player.teleport(loc);
            player.sendMessage("§cTu es freeze !");
        }
    }

  
    public void onDamage(EntityDamageEvent event) {
        Entity entite = event.getEntity();

        if(entite instanceof Player && frozenPlayerAndLocation.containsKey((Player) entite)){
            event.setCancelled(true);
        }
    }

  
    @Override
    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {

        if(sender instanceof Player) {
            Player player = (Player) sender;
            Player freezedPlayer;

            // On vérifie que les paramètre sont bon (qu'il y en ai au moins un)
            // et que le joueur existe bien
            if(args.length < 1) {
                player.sendMessage("§cIl manque des information pour utiliser cette commande");
                return false;
            } else {
                freezedPlayer = Bukkit.getPlayer(args[0]);
                if(freezedPlayer == null) {
                    player.sendMessage("§cLe joueur indiqué §7(" + args[0] + ")§c n'existe pas");
                    return false;
                }
            }

            boolean isOk = false;
            switch(label.toLowerCase()) { // on force la commande à être en minuscule

                case "freeze":
                    isOk = freeze(freezedPlayer, player);
                    break;

                case "unfreeze":
                    isOk = unfreeze(freezedPlayer, player);
                    break:

                default:
                    player.sendMessage("§cCette commande n'existe pas");
                    return false;

            }

            if(!isOk) {
                player.sendMessage("§cImpossible de " + label + " " + freezedPlayer.getName() + " ("
                    "vérifiez qu'il n'est pas déjà " + label + ")");
            } else {
                return true;
            }

        }

        return false;
    }

    /**
     * Permet de freeze un joueur
     *
     * @param newFreezePlayer le joueur qui doit être freeze
     * @param playerWhoFreeze le joueur ayant décidé de freeze (celui qui fait la commande)
     * @return True si tout c'est bien passé, False sinon
     */
    private boolean freeze(Player newFreezePlayer, Player playerWhoFreeze) {
        boolean resultat = false;
        // S'il n'est pas déjà freeze
        if(!frozenPlayerAndLocation.containsKey(newFreezePlayer)) {
            newFreezePlayer.setWalkSpeed(0);
            frozenPlayerAndLocation.put(newFreezePlayer, newFreezePlayer.getLocation());
            newFreezePlayer.sendMessage("§cTu as été freeze par " + playerWhoFreeze.getName());
            resultat = true;
        }
        return resultat;
    }

    /**
     * Permet de unfreeze un joueur
     *
     * @param newFreezePlayer le joueur qui doit être unfreeze
     * @param playerWhoFreeze le joueur ayant décidé de unfreeze (celui qui fait la commande)
     * @return True si tout c'est bien passé, False sinon
     */
    private boolean unfreeze(Player unfreezePlayer, Player playerWhoUnfreeze) {
        boolean resultat = false;
        // S'il n'est pas déjà unfreeze
        if(frozenPlayerAndLocation.containsKey(unfreezePlayer)) {
            unfreezePlayer.setWalkSpeed(0.2);
            frozenPlayerAndLocation.remove(unfreezePlayer);
            unfreezePlayer.sendMessage("§2Tu as été unfreeze par " + playerWhoUnfreeze.getName());
            resultat = true;
        }
        return resultat;
    }

  
}



Cordialement,
Detobel36
 
Bonsoir !

Waow.... J'ai ouvert ça au lycée aujourd'hui, j'ai passé 1 heure à tout comprendre et tout chercher comment les syntaxes fonctionnent et ce qu'elles font. C'est très clair et limpide quand on prend le temps de bien lire le code. Il y a juste 2 ou 3 bouts que je n'ai pas compris :
private boolean freeze(Player newFreezePlayer, Player playerWhoFreeze) {
private boolean unfreeze(Player unfreezePlayer, Player playerWhoUnfreeze) {
Ca crée une commande ceci ?

Et cela, j'ai pas bien compris comment ca fonctionne ;) :

switch(label.toLowerCase()) { // on force la commande à être en minuscule

case "freeze":
isOk = freeze(freezedPlayer, player);
break;

case
"unfreeze":
isOk = unfreeze(freezedPlayer, player);
break:

default:
player.sendMessage("§cCette commande n'existe pas");
return
false;

En tout cas en grand merci à toi ! Je vais taper ça dans la soirée (pas copier coller sinon c'est moins amusant et éducatif :p ) Et puis je vous tiendrai informé. Mais en tout cas j'ai appris beaucoup de chose ;) Merci :D

AlexFatta
 
Salut,

Je veux bien expliquer mais faut quand même un peu de bases.

La première question ce sont des fonctions/méthode. C'est la base du développement.

Le switch je suis sur que tu n'as pas cherché sur internet.


Cordialement,
Detobel36
 
Dernière édition:
D'accord ! Cette fois c'est clair xD J'étais allé sur le site d'openclasroom mais j'avais pas trouvé de suite. J'ai recherché et cette fois c'est bon ;) Donc là j'ai bien compris le code. Faut que je sache le refaire maintenant xD Merci à toi en tout cas Detobel je te tiendrai au courant :p

AlexFatta
 
Bonjour !

Alors j'ai tester et le code et toujours le même problème. Le joueur peut quand même sauter. J'ai copier coller le code aussi pour voir si c'était pas mon texte qui foirait, mais non, le joueurs peut quand même sauter et donc se déplacer. C'est vraiment curieux parce que sur certains tutos ils utilisent le PlayerMoveEvent et chez eux ca marche xDDD

AlexFatta