Quêtes customisées API

ALERTE: Ces informations sont destinées aux développeurs. Apprenez d'abord à utiliser Java !

Ajouter à votre projet

Pour un démarrage rapide, un projet de modèle de module est disponible sur Github ici.

Si vous utilisez Maven ou un autre outil de gestion de projet, ajoutez la dernière version de Quests via le service CodeMC.

<repository>
  <id>codemc-repo</id>
  <url>https://repo.codemc.io/repository/maven-public/</url>
</repository>

À moins de concevoir un projet multiplateforme, vous devez définir l'artefact principal.

<dependency>
  <groupId>me.pikamug.quests</groupId>
  <artifactId>quests-core</artifactId>
  <version>VERSION</version>
</dependency>

Apprendre l'interface

Quests fournit une API simple pour créer des exigences, des récompenses et des objectifs personnalisés. Pour commencer, assurez-vous que vous compilez avec la version 4.0.0 ou supérieure. Une fois que vous avez fini de suivre ce guide, utilisez le dossier /Quests/modules comme destination pour votre fichier jar fini et compilé. Si vous distribuez votre module, assurez-vous d'informer l'utilisateur de l'emplacement final et correct du dossier.

Les exemples suivants supposent que vous créez un projet pour un logiciel basé sur Bukkit.

API des exigences

Construire une exigence de quêtes est très simple. Pour commencer, créez une classe Java qui étend la classe CustomRequirement. Après cela, consultez cet exemple d'exigence personnalisée où le joueur doit avoir un nom particulier pour entreprendre la quête :

package xyz.janedoe;

import java.util.Map;
import org.bukkit.entity.Player;
import me.pikamug.quests.module.BukkitCustomRequirement;

public class NameRequirement extends BukkitCustomRequirement {
    // Construire l'exigence
    public NameRequirement() {
        setName("Exigence de nom");
        setAuthor("Jane Doe");
        setItem("NAME_TAG", (short)0);
        addStringPrompt("Name", "Entrez la valeur que le nom du joueur doit contenir afin de prendre la quête", null);
        addStringPrompt("Case-Sensitive", "La vérification doit-elle être sensible à la casse ou non ? (Entrer \'true\' ou \'false\')", null);
	setDisplay("Désolé, vous n'êtes pas sur la liste.");
    }
    
    // Tester si un joueur a satisfait à l'exigence
    @Override
    public boolean testRequirement(Player player, Map<String, Object> data) {
	String caseSensitive = (String) data.get("Case-Sensitive");
		
	// Vérifiez si le nom doit être sensible à la casse
	if (caseSensitive.equalsIgnoreCase("true")) {
	    // Marquer l'exigence comme satisfaite si le nom correspond
	    return player.getName().contains((String)data.get("Name"));
	} else {
	    // Marquer l'exigence comme satisfaite si le nom correspond, en ignorant la casse
	    return player.getName().toLowerCase().contains(((String)data.get("Name")).toLowerCase());
	}
    }
}

Dans le constructeur de votre classe, vous pouvez utiliser l'une des méthodes suivantes :

MéthodeDescription

setName()

Définit le nom de l'objectif personnalisé.

setAuthor()

Définit l'auteur de l'objectif personnalisé (vous !).

setItem()

Définissez un élément qui peut apparaître dans les plugins de superposition comme QuestsGUI.

setDisplay

Définit le mode d'affichage de l'exigence en cas d'échec.

addStringPrompt()

Ajoute une nouvelle invite d'éditeur avec le titre, la description et la valeur par défaut spécifiés pour votre objectif personnalisé. Les éditeurs de quête peuvent saisir une chaîne que vous devez analyser.

À l'intérieur de #testRequirement, vous exécutez votre logique pour déterminer si le joueur satisfait à l'exigence, renvoyant true s'il le fait et false s'il ne le fait pas.

La carte de données contient les données que la personne qui a créé la quête lui a données. Dans cet exemple, la carte de données contient les deux valeurs pour 'Name' et 'Case-Sensitive'. Notez également que même si les valeurs sont de type Object, elles ont été converties en type String en interne. Vous devez effectuer une conversion de type manuelle si vous souhaitez obtenir des entiers, des booléens, etc.

API de récompense

Construire une récompense de quêtes est très simple. Pour commencer, créez une classe Java qui étend la classe CustomReward. Après cela, consultez cet exemple de récompense personnalisée où un joueur obtient un inventaire GUI contenant du fer, de l'or et des diamants :

package xyz.janedoe;

import java.util.Map;

import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;

import me.pikamug.quests.module.BukkitCustomReward;

import java.util.UUID;

public class LootReward extends BukkitCustomReward {
    // Construire la récompense
    public LootReward() {
        setName("Butin de récompense");
        setAuthor("Jane Doe");
        setItem("CHEST", (short)0);
        setDisplay("Coffre de butin: %Title%");
        addStringPrompt("Title", "Titre de l'interface d'inventaire de butin.", null);
        addStringPrompt("NumIron", "Entrez le nombre de lingots de fer à donner dans le coffre à butin.", null);
        addStringPrompt("NumGold", "Entrez le nombre de lingots d'or à donner dans le coffre à butin.", null);
        addStringPrompt("NumDiamond", "Entrez le nombre de diamants à donner dans le coffre à butin.", null);
    }
    
    // Donner une récompense de butin à un joueur
    @Override
    public void giveReward(UUID uuid, Map<String, Object> data) {
        final Player player = Bukkit.getPlayer(uuid);
        if (player == null) {
            Bukkit.getLogger().severe("Player was null for UUID " + uuid);
            return;
        }
        String title = (String) data.get("Title");
        int numIron = 0;
        int numGold = 0;
        int numDiamond = 0;
        
        // Tentative de chargement de l'entrée utilisateur sous forme d'entiers
        try {
            numIron = Integer.parseInt((String) data.get("NumIron"));
        } catch (NumberFormatException nfe) {
        	Bukkit.getLogger().severe("La récompense de butin a un numéro de fer invalide: " + numIron);
        }
        try {
            numGold = Integer.parseInt((String) data.get("NumGold"));
        } catch (NumberFormatException nfe) {
        	Bukkit.getLogger().severe("La récompense de butin a un numéro d'or invalide: " + numGold);
        }
        try {
            numDiamond = Integer.parseInt((String) data.get("NumDiamond"));
        } catch (NumberFormatException nfe) {
        	Bukkit.getLogger().severe("La récompense de butin a un numéro de diamands invalide: " + numDiamond);
        }
        
        // Créer un inventaire temporaire pour y ajouter des objets
        Inventory inv = Bukkit.getServer().createInventory(player, 3, title);
        int slot = 0;

        // Vérifier si le montant est supérieur à la valeur par défaut
        if (numIron > 0) {
            // Ajoutez un objet à l'emplacement actuel dans l'inventaire temporaire, puis préparez l'emplacement suivant
            inv.setItem(slot, new ItemStack(Material.IRON_INGOT, numIron > 64 ? 64 : numIron));
            slot++;
        }
        if (numGold > 0) {
            inv.setItem(slot, new ItemStack(Material.GOLD_INGOT, numGold > 64 ? 64 : numGold));
            slot++;
        }
        if (numDiamond > 0) {
            inv.setItem(slot, new ItemStack(Material.DIAMOND, numDiamond > 64 ? 64 : numDiamond));
        }
        
        // Ouvrir l'inventaire temporaire pour que le joueur accepte les objets
        player.openInventory(inv);
    }
}

Dans le constructeur de votre classe, vous pouvez utiliser l'une des méthodes suivantes :

MéthodeDescription

setName

Définit le nom de l'objectif personnalisé.

setAuthor

Définit l'auteur de l'objectif personnalisé (vous !).

setItem

Définissez un élément qui pourrait apparaître dans les plugins de superposition comme QuestsGUI.

setDisplay

Définit le nom de la récompense (texte qui apparaîtra lorsque le joueur termine la quête) de la récompense personnalisée.

addStringPrompt

Ajoute une nouvelle invite d'éditeur avec le titre, la description et la valeur par défaut spécifiés pour votre objectif personnalisé. Les éditeurs de quête peuvent saisir une chaîne que vous devez analyser.

À l'intérieur de #giveReward est l'endroit où vous exécutez votre logique pour donner au joueur tout ce que votre récompense personnalisée donne. La carte de données contient les données que la personne qui a créé la quête lui a données. Dans cet exemple, la carte de données contient quatre valeurs : une pour le titre de l'interface graphique et trois pour la quantité de fer/or/diamants. Notez également que même si les valeurs sont de type Object, elles ont été converties en type String en interne. Vous devez effectuer une conversion de type manuelle si vous souhaitez obtenir des entiers, des booléens, etc.

API des objectifs

Construire un objectif de quête est un peu plus compliqué que les exigences ou les récompenses. Pour commencer, créez une classe Java qui étend la classe CustomObjective. Si vous souhaitez capturer l'un des événements de Bukkit, vous devrez implémenter la classe d'écoute (Les quêtes se chargeront de l'enregistrer pour vous). Après cela, consultez ces exemples d'objectif personnalisé :

// Le joueur doit acquérir une certaine expérience pour avancer

package xyz.janedoe;

import me.pikamug.quests.module.BukkitCustomObjective;
import me.pikamug.quests.Quest;
import me.pikamug.quests.Quests;

import org.bukkit.Bukkit;
import org.bukkit.event.EventHandler;
import org.bukkit.event.player.PlayerExpChangeEvent;

public class ExperienceObjective extends BukkitCustomObjective {
    // Obtenir le plugin Quêtes
    Quests qp = (Quests) Bukkit.getServer().getPluginManager().getPlugin("Quests");
	
    // Construire l'objectif
    public ExperienceObjective() {
        setName("Objectif d'expérience");
        setAuthor("Jane Doe");
        setItem("BOOK", (short)0);
        setShowCount(true);
        setCountPrompt("Saisissez les points d'expérience que le joueur doit acquérir:");
        setDisplay("Acquérir des points d'expérience : %count%");
    }

    // Attrapez l'événement Bukkit pour un joueur gagnant / perdant de l'expérience
    @EventHandler
    public void onPlayerExpChange(PlayerExpChangeEvent evt) {
        Quester quester = qp.getQuester(evt.getPlayer().getUniqueId());
        // Assurez-vous d'évaluer toutes les quêtes actuelles du joueur
        for (Quest quest : qp.getQuester(evt.getPlayer().getUniqueId()).getCurrentQuests().keySet()) {
            // Vérifie si le joueur a gagné plus d'expérience qu'il n'en a perdu
            if (evt.getAmount() > 0) {
                // Ajoutez à la progression de l'objectif, en le complétant si les exigences ont été remplies
                incrementObjective(evt.getPlayer(), this, quest, evt.getAmount());
                // Facultatif : partagez la progression avec les membres du groupe (le cas échéant)
                quester.dispatchMultiplayerEverything(quest, ObjectiveType.CUSTOM,
                        (final Quester q, final Quest cq) -> {
                            incrementObjective(q.getUUID(), this, quest, evt.getAmount());
                            return null;
                });
            }
        }
    }
}

Dans le constructeur de votre classe, vous pouvez utiliser l'une des méthodes suivantes :

MéthodeDescription

setName

Définit le nom de l'objectif personnalisé.

setAuthor

Sets l'auteur de l'objectif personnalisé (vous !).

setItem

Définissez un élément qui pourrait apparaître dans les plugins de superposition comme QuestsGUI.

setShowCount

Définit si l'éditeur de quête peut définir le décompte (nombre de fois où le joueur doit répéter la tâche). La valeur par défaut est "vrai". Cela s'appliquera à toutes les invites ajoutées avec #addStringPrompt, sauf si elles sont désactivées.

setCountPrompt

Définit la description de l'invite permettant à l'utilisateur d'entrer le nombre pour l'objectif. La valeur par défaut est "Entrer le numéro".

setDisplay

Définit la façon dont l'objectif est affiché dans la liste /quests et le journal des quêtes. Pour les espaces réservés, utilisez %count% pour obtenir la valeur de #setShowCount et les titres #addStringPrompt pour l'entrée utilisateur (comme %Item Name% dans le deuxième exemple). La valeur par défaut est « Progression : %count% ».

addStringPrompt

Ajoute une nouvelle invite d'éditeur avec le titre, la description et la valeur par défaut spécifiés pour votre objectif personnalisé. Les éditeurs de quête peuvent saisir une chaîne que vous devez analyser.

À l'intérieur de vos EventHandlers (le cas échéant), déterminez si le joueur a atteint tout ou partie de l'objectif, puis utilisez #incrementObjective pour faire avancer le joueur. Le premier et le deuxième argument de #incrementObjective doivent toujours être respectivement le joueur et 'this'. Le troisième argument est de combien incrémenter l'objectif, tandis que le dernier est la quête à laquelle appliquer l'incrément. Même si votre objectif n'a pas de décompte, vous devez toujours utiliser #incrementObjective - utilisez un incrément de 1 pour signaler que l'objectif a été atteint.

Le Map<String, Object> contient les données fournies par l'éditeur de quête. Dans cet exemple, les clés de données sont les noms des éléments, tandis que les valeurs sont l'entrée de l'utilisateur pour votre invite (qui peut être null). Notez également que même si les valeurs sont de type objets, elles ont été converties en type String en interne. Vous devez effectuer une conversion de type manuelle si vous souhaitez obtenir des entiers, des booléens, etc.

Dernière mise à jour