/Quetes

Documentation - Quêtes et Dialogues (Questions/Réponses)

Vue d'ensemble

Le système de quêtes gère les missions que les joueurs peuvent accomplir. Chaque quête est composée d'étapes, d'objectifs, et d'un système de dialogue avec les PNJ basé sur des questions et réponses.

Architecture

Hiérarchie des Classes

Quest (Quête principale)
├── QuestStep (Étapes de la quête)
│   └── QuestObjectif (Objectifs et récompenses)
└── NpcQuestion (Questions du PNJ)
    └── NpcAnswer (Réponses possibles)
        └── Action (Actions déclenchées)

Quest - Quête Principale

Définition

La classe Quest représente une quête complète avec ses étapes et objectifs.

Localisation: src/main/java/quest/Quest.java

Propriétés

private int id;                              // ID unique de la quête
private ArrayList<QuestStep> questEtapeList; // Liste des étapes
private ArrayList<QuestObjectif> questObjectifList; // Objectifs
private NpcTemplate npc;                     // PNJ qui donne la quête
private ArrayList<Action> actions;           // Actions au démarrage
private boolean delete;                      // Supprimer après complétion
private Pair<Integer, Integer> condition;    // Conditions de démarrage

Chargement depuis la Base de Données

Table: quest_data

SELECT * FROM quest_data WHERE id = ?

Colonnes:

  • id: INT - ID unique
  • etapes: VARCHAR - IDs des étapes (format: "1;2;3")
  • objectif: VARCHAR - IDs des objectifs (format: "1;2")
  • npc: INT - ID du PNJ qui donne la quête
  • action: VARCHAR - Actions au démarrage (format: "1,2,3")
  • args: VARCHAR - Arguments des actions (format: "arg1;arg2;arg3")
  • deleteFinish: BOOLEAN - Supprimer après complétion
  • condition: VARCHAR - Conditions de démarrage (format: "questId:level")

Exemple de Quête

// Créer une quête
Quest quest = new Quest(
    1,                          // ID
    "1;2;3",                    // Étapes: 1, 2, 3
    "1;2",                      // Objectifs: 1, 2
    10,                         // PNJ ID: 10
    "1,2",                      // Actions: 1, 2
    "arg1;arg2",                // Arguments
    false,                      // Ne pas supprimer
    "0:1"                       // Condition: quête 0 complétée, niveau 1+
);

QuestStep - Étapes de Quête

Définition

La classe QuestStep représente une étape individuelle d'une quête.

Localisation: src/main/java/quest/QuestStep.java

Propriétés

private int id;                              // ID unique
private short type;                          // Type d'étape
private int objectif;                        // ID de l'objectif
private Quest quest;                         // Référence à la quête
private Map<Integer, Integer> itemNecessary; // Items requis (ID, Quantité)
private NpcTemplate npc;                     // PNJ de l'étape
private int monsterId;                       // Monstre à combattre
private short qua;                           // Quantité de monstres
private String condition;                    // Conditions
private int validationType;                  // Type de validation

Types d'Étapes

Type Description Exemple
0 Parler à un PNJ Parler au PNJ 10
1 Collecter des items Collecter 5x Item 100
2 Combattre des monstres Combattre 3x Gobelin
3 Aller à une localisation Aller à la carte 50
4 Utiliser un objet Utiliser l'item 200
5 Compléter une sous-quête Compléter la quête 5

Chargement depuis la Base de Données

Table: quest_step

SELECT * FROM quest_step WHERE id = ?

Colonnes:

  • id: INT - ID unique
  • type: INT - Type d'étape
  • objectif: INT - ID de l'objectif
  • items: VARCHAR - Items requis (format: "100,5;200,3")
  • npc: INT - ID du PNJ
  • monsters: VARCHAR - Monstres (format: "1,5" = monstre 1, quantité 5)
  • condition: VARCHAR - Conditions
  • validationType: INT - Type de validation

Exemple d'Étape

// Étape: Collecter 5 potions
QuestStep step = new QuestStep(
    1,                          // ID
    1,                          // Type: Collecter
    1,                          // Objectif ID: 1
    "5001,5",                   // Items: 5x Potion (ID 5001)
    10,                         // PNJ: 10
    "",                         // Pas de monstre
    "",                         // Pas de condition
    0                           // Validation: automatique
);

QuestObjectif - Objectifs et Récompenses

Définition

La classe QuestObjectif définit les récompenses et conditions de complétion d'une étape.

Localisation: src/main/java/quest/QuestObjectif.java

Propriétés

private int id;                              // ID unique
private int xp;                              // XP à gagner
private int kamas;                           // Kamas à gagner
private Map<Integer, Integer> objects;       // Items à recevoir (ID, Quantité)
private ArrayList<Action> actions;           // Actions à exécuter
private ArrayList<QuestStep> questSteps;     // Étapes associées

Chargement depuis la Base de Données

Table: quest_objective

SELECT * FROM quest_objective WHERE id = ?

Colonnes:

  • id: INT - ID unique
  • xp: INT - XP à gagner
  • kamas: INT - Kamas à gagner
  • objects: VARCHAR - Items (format: "100,5;200,3")
  • actions: VARCHAR - Actions (format: "1|arg1;2|arg2")

Exemple d'Objectif

// Objectif: Gagner 1000 XP, 500 Kamas, et 1x Item 100
QuestObjectif objectif = new QuestObjectif(
    1,                          // ID
    1000,                       // XP
    500,                        // Kamas
    "100,1",                    // Items: 1x Item 100
    "1|arg1;2|arg2"             // Actions
);

Système de Dialogue - Questions et Réponses

Vue d'ensemble

Le système de dialogue permet aux PNJ de poser des questions aux joueurs, avec des réponses conditionnelles basées sur l'état du joueur.

NpcQuestion - Questions du PNJ

Localisation: src/main/java/entity/npc/NpcQuestion.java

Propriétés

private int id;                    // ID unique de la question
private String answers;            // IDs des réponses possibles (format: "1;2;3")
private String args;               // Arguments pour les réponses
private String condition;          // Conditions d'affichage
private String falseQuestion;      // Question alternative si condition fausse

Chargement depuis la Base de Données

Table: npc_question

SELECT * FROM npc_question WHERE id = ?

Colonnes:

  • id: INT - ID unique
  • answers: VARCHAR - IDs des réponses (format: "1;2;3")
  • args: VARCHAR - Arguments (format: "arg1;arg2;arg3")
  • condition: VARCHAR - Conditions
  • falseQuestion: INT - Question alternative

Exemple de Question

// Question: "Veux-tu m'aider?"
NpcQuestion question = new NpcQuestion(
    1,                          // ID
    "1;2",                      // Réponses: 1 (Oui), 2 (Non)
    "arg1;arg2",                // Arguments
    "level:10",                 // Condition: niveau 10+
    "3"                         // Question alternative: 3
);

NpcAnswer - Réponses Possibles

Localisation: src/main/java/entity/npc/NpcAnswer.java

Propriétés

private int id;                    // ID unique de la réponse
private ArrayList<Action> actions; // Actions déclenchées
private Quest quest;               // Quête associée

Chargement depuis la Base de Données

Table: npc_answer

SELECT * FROM npc_answer WHERE id = ?

Colonnes:

  • id: INT - ID unique
  • actions: VARCHAR - Actions (format: "1|arg1;2|arg2")
  • quest: INT - ID de la quête

Exemple de Réponse

// Réponse: "Oui, je vais t'aider!"
NpcAnswer answer = new NpcAnswer(1);  // ID: 1
answer.addAction(new Action(40, "1", "-1", null));  // Action: Démarrer quête 1

Actions Déclenchées

Les actions sont exécutées lorsqu'une réponse est sélectionnée.

Types d'Actions

ID Type Description Arguments
1 Dialogue Afficher un dialogue dialogueId
15 Donner Item Donner un item au joueur itemId,quantité,itemId
16 Montrer Item Vérifier que le joueur a un item itemId,quantité,itemId
40 Quête Démarrer/Compléter une quête questId
41 Téléportation Téléporter le joueur mapId,cellId
42 Argent Donner de l'argent montant

Exemple d'Action

// Action: Donner 1000 Kamas
Action action = new Action(
    42,                         // Type: Argent
    "1000",                     // Montant
    "-1",                       // Pas de condition
    null                        // Pas de paramètres supplémentaires
);

Flux de Dialogue Complet

Étape 1: Afficher la Question

// Le joueur parle au PNJ
NpcQuestion question = Main.world.getQuestion(questionId);

// Vérifier les conditions
if (ConditionParser.checkConditions(player, question.getCondition())) {
    // Afficher la question
    String questionText = question.getText();
    SocketManager.sendMessage(player, "NPC: " + questionText);
    
    // Afficher les réponses possibles
    String[] answerIds = question.getAnwsers().split(";");
    for (int i = 0; i < answerIds.length; i++) {
        NpcAnswer answer = Main.world.getAnswers().get(Integer.parseInt(answerIds[i]));
        SocketManager.sendMessage(player, (i+1) + ". " + answer.getText());
    }
} else {
    // Afficher la question alternative
    NpcQuestion falseQuestion = Main.world.getQuestion(question.getFalseQuestion());
    // ... afficher la question alternative
}

Étape 2: Sélectionner une Réponse

// Le joueur sélectionne une réponse
int selectedAnswerId = 1;  // Réponse 1
NpcAnswer answer = Main.world.getAnswers().get(selectedAnswerId);

// Appliquer les actions
for (Action action : answer.getActions()) {
    action.apply(player, null, -1, -1, selectedAnswerId);
}

Étape 3: Exécuter les Actions

// Exemple: Démarrer une quête
if (action.getId() == 40) {
    int questId = Integer.parseInt(action.getArgs());
    Quest quest = Quest.getQuestById(questId);
    
    // Créer une instance de quête pour le joueur
    QuestPlayer questPlayer = new QuestPlayer(player, quest);
    player.addQuest(questPlayer);
    
    // Notifier le client
    SocketManager.sendMessage(player, "Quête acceptée: " + quest.getName());
}

Conditions de Dialogue

Format

condition1:val1;condition2:val2

Types de Conditions

Condition Format Exemple
Niveau level:50 Niveau minimum 50
Classe class:1,2,3 Classes 1, 2 ou 3
Quête complétée quest:50 Quête 50 complétée
Quête non complétée questNot:50 Quête 50 non complétée
Item possédé item:100,5 Possède 5x Item 100
Stat stat:forc:100 Force minimum 100
Sexe gender:0 Masculin uniquement

Exemple Complet - Quête Simple

1. Créer la Quête en Base de Données

-- Créer la quête
INSERT INTO quest_data (id, etapes, objectif, npc, action, args, deleteFinish, condition)
VALUES (1, "1;2", "1;2", 10, "1,2", "arg1;arg2", 0, "0:1");

-- Créer les étapes
INSERT INTO quest_step (id, type, objectif, items, npc, monsters, condition, validationType)
VALUES 
(1, 0, 1, "", 10, "", "", 0),  -- Étape 1: Parler au PNJ 10
(2, 1, 2, "5001,5", 10, "", "", 0);  -- Étape 2: Collecter 5x Potion

-- Créer les objectifs
INSERT INTO quest_objective (id, xp, kamas, objects, actions)
VALUES 
(1, 500, 100, "", ""),  -- Objectif 1: 500 XP, 100 Kamas
(2, 1000, 500, "100,1", "");  -- Objectif 2: 1000 XP, 500 Kamas, 1x Item 100

-- Créer les questions/réponses
INSERT INTO npc_question (id, answers, args, condition, falseQuestion)
VALUES (1, "1;2", "arg1;arg2", "level:1", "");

INSERT INTO npc_answer (id, actions, quest)
VALUES 
(1, "40|1", 1),  -- Réponse 1: Accepter la quête 1
(2, "", NULL);  -- Réponse 2: Refuser

2. Charger la Quête

// Charger la quête
Quest quest = Quest.getQuestById(1);

// Afficher la question du PNJ
NpcQuestion question = Main.world.getQuestion(1);
String[] answerIds = question.getAnwsers().split(";");

// Afficher les réponses
for (int i = 0; i < answerIds.length; i++) {
    NpcAnswer answer = Main.world.getAnswers().get(Integer.parseInt(answerIds[i]));
    System.out.println((i+1) + ". " + answer.getText());
}

3. Accepter la Quête

// Le joueur sélectionne la réponse 1
NpcAnswer answer = Main.world.getAnswers().get(1);

// Appliquer les actions
for (Action action : answer.getActions()) {
    if (action.getId() == 40) {
        int questId = Integer.parseInt(action.getArgs());
        Quest q = Quest.getQuestById(questId);
        
        // Créer une instance de quête
        QuestPlayer questPlayer = new QuestPlayer(player, q);
        player.addQuest(questPlayer);
        
        System.out.println("Quête acceptée!");
    }
}

4. Compléter la Quête

// Vérifier si toutes les étapes sont complétées
QuestPlayer questPlayer = player.getQuest(1);

if (questPlayer.isCompleted()) {
    // Appliquer les récompenses
    for (QuestObjectif objectif : quest.getObjectifList()) {
        player.addXP(objectif.getXp());
        player.addKamas(objectif.getKamas());
        
        // Ajouter les items
        for (Entry<Integer, Integer> item : objectif.getObjects().entrySet()) {
            player.addItem(item.getKey(), item.getValue());
        }
    }
    
    // Supprimer la quête si nécessaire
    if (quest.isDelete()) {
        player.removeQuest(1);
    }
    
    System.out.println("Quête complétée!");
}

Gestion des Erreurs

Validations Courantes

// Vérifier le niveau requis
if (player.getLevel() < 1) {
    throw new Exception("Niveau insuffisant");
}

// Vérifier les items requis
for (Entry<Integer, Integer> item : step.getItemNecessary().entrySet()) {
    if (!player.hasItemTemplate(item.getKey(), item.getValue())) {
        throw new Exception("Items manquants");
    }
}

// Vérifier les conditions
if (!ConditionParser.checkConditions(player, step.getCondition())) {
    throw new Exception("Conditions non remplies");
}

Conclusion

Le système de quêtes et de dialogues offre une grande flexibilité pour créer des missions complexes avec des dialogues interactifs. Les conditions et actions permettent de créer des expériences de jeu riches et variées.

Powered by hosted.md