/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 uniqueetapes: 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êteaction: VARCHAR - Actions au démarrage (format: "1,2,3")args: VARCHAR - Arguments des actions (format: "arg1;arg2;arg3")deleteFinish: BOOLEAN - Supprimer après complétioncondition: 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 uniquetype: INT - Type d'étapeobjectif: INT - ID de l'objectifitems: VARCHAR - Items requis (format: "100,5;200,3")npc: INT - ID du PNJmonsters: VARCHAR - Monstres (format: "1,5" = monstre 1, quantité 5)condition: VARCHAR - ConditionsvalidationType: 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 uniquexp: INT - XP à gagnerkamas: INT - Kamas à gagnerobjects: 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 uniqueanswers: VARCHAR - IDs des réponses (format: "1;2;3")args: VARCHAR - Arguments (format: "arg1;arg2;arg3")condition: VARCHAR - ConditionsfalseQuestion: 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 uniqueactions: 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.