Un système de quêtes extrêmement riche !
{Script RGSS3 pour VXAce}
Chers amis, nous voici de retour pour la publication d'un système de quêtes offrant, actuellement le plus de possibilité... au monde :) ... (enfin, je crois).
- Nuki, 06/11/2014 à 01h41.


Un système de quêtes extrêmement riche ! - Nuki

Un système de quêtes révolutionnaire

{Scripts RGSS3 pour VXAce}


Raho commençait son tutoriel impérial sur la création d'un système de quêtes en proposant d'apprendre à créer son propre système plutôt que de coder le système le plus riche... sachez que moi Nuki, je l'ai fait... probablement le système le plus permissif !


icone Préambule


Après avoir rédigé un système de base de données étendue encore plus riche que ma précédente version, que vous pourrez trouver ici. J'ai décidé de m'en servir pour implémenter des systèmes configurables et permissifs. Je me suis d'abord fait les dents sur un tout petit système de quêtes, que j'ai fait évoluer en quelque chose de réellement flexible. Vous l'aurez compris, l'installation du script CustomDatabase est donc un pré-requis. (Toutes les informations d'installation sont disponibles sur la page du script Smiley)

icone Version minimaliste



Cette version, présentée ci-dessous, n'a rien de révolutionnaire... elle présente juste une implémentation minimaliste en utilisant mon système de base de données.


Avant toute chose, ce script est avant tout une manière d'expérimenter la flexibilité (et le gain de temps) offert par le script de base de données personnalisable. L'objectif, ici, n'est donc pas de produire "le script le plus puissant" (le plus personnalisable et avec le plus de fonction) des systèmes de quêtes, mais plutôt un micro système, facile à prendre en main (qui donnera peut être naissance à un système plus conséquent dans le futur). Ce script permet donc de déployer rapidement des quêtes dans son projet.

Image du journal des quêtes





Installation



Ce script requiert l'installation de CustomDatabase pour fonctionner.
Copiez le script dans votre éditeur de script au dessus de Main, dans la rubrique Materials. Vous pouvez lui attribuer un emplacement réservé. Et le nommer comme vous l'entendez. Personnellement, j'ai choisi le nom MicroQuestSystem (original :P !)
Je conseil de préparer un espace script en dessous de ce script qui servira à insérer les quêtes.

Lien du micro système de quêtes

Création de quêtes


Comme précisé dans l'installation, je conseilles de préparer un espace vierge en dessous du script (mais vous pouvez écrire vos quêtes à la suite du script, sans créer d'autre espace).
La création d'une quête ne peut pas être faite ingame. Il faut impérativement les créer avant. Cependant, vous pouvez les modifier, supprimer et en ajouter durant la réalisation de votre jeu.

Syntaxe de la création d'une quête
Code (Ruby):
  1. Quest.insert(ID, NOM, DESCRIPTION, GOLD, EXP, ITEMS, WEAPONS, ARMORS)

Voyons maintenant quels sont les paramètres de l'insertion :

1.) ID Correspond à un identifiant (UNIQUE) que vous attribuerez pour accéder rapidement à une quête.
2.) NOM Le nom de la quête. Il sera affiché dans le journal des quêtes
3.) DESCRIPTION Une note plus explicite que le nom
4.) GOLD et EXP correspondent à l'argent et l'expérience reçue quand la quête est finie.
5.) ITEMS, WEAPONS, ARMORS sont des listes qui contiennent les ID's des objets/armes/armures à recevoir en fin de quête.

Par exemple :
Code (Ruby):
  1. Quest.insert(1, "Tuer slimes",
  2. "Il faut protéger le village en tuant des slimes",
  3. 100, 777, [10],[2,3],[2,2,4]
  4. )


Cette quête, une fois finie, donnera 100 d'or, 777 d'expérience et l'objet 10, l'arme 2 et l'arme 3, deux armures 2 et une armure 4. Alors que celui-ci :

Code (Ruby):
  1. Quest.insert(2, "Manger un chat",
  2. "C'est très bon ... miam",
  3. 10, 78, [],[],[]
  4. )


Ne donne que 10 d'or, 78 d'expérience et aucun objet/arme/armur.
Vous pouvez créer autant de quêtes que vous le désirez. Il faudra utiliser l'ID pour y accéder.

Lancer une quête


Le démarrage d'une quête indique qu'elle est en cours. Il suffit de faire : start_quest(ID). Dans un appel de script (ou ailleurs). Il est donc très commode de démarrer une quête au moyen d'un appel de script dans un évènement.

Finir une quête


Une quête ne peut être finie que si elle a été commencée. Il suffit de faire finish_quest(ID). Lorsqu'une quête est finie, la distribution de l'or, de l'expérience et des objets est effectuée toute seule.
Une quête finie est indiquée en vert dans le journal de quête, et une quête en cours est de la couleur standard.

Fonctions annexes


1.) quest_on_the_road?(ID) ou quest_in_curse?(ID) renvoi true si la quête est en cours, false sinon.
2.) quest_done?(ID) ou quest_finished?(ID) renvoi true si la quête est finie, false sinon.


Configuration complémentaire



Il est possible de modifier les textes utilisés en modifiant le module Vocab mais aussi d'annuler l'affichage du journal dans le menu en désactivant la constante QUEST_IN_MENU du module [/strong]Config[/strong]

Conclusion


Ce script est assez "minimaliste" mais offre toute la base nécéssaire à la construction d'un système de quête. Il s'inscrit dans le RGSS et l'usage de la base de données alternative le rend très court et très facile à maintenir (mais aussi à modifier). Il ne faut pas prendre ce script comme une tentative d'évolution mais juste comme un essai de l'usage de ma petite base de données étendue.
Le script présenté dans la suite est beaucoup, beaucoup plus impressionnant Smiley!

icone Le vrai script (super badass) :D


La première version de ce script n'offre absolument rien de novateur... Il est même assez simplet. Maintenant il est temps de passer à la vraie présentation ... mesdames, messieurs, mesdemoiselles... je vous présente mon Ultra Quest System !


Un des enjeux de ce script est surtout de permettre d'automatiser la terminaison de certaines quêtes... comme par exemple celle présentée en exemple : tuer deux slimes. Qui, à implémenter en évènement est assez compliqué !
Le script est aussi doté d'un magasin de quête, de conditions de structures internes et de pleins d'autres fonctionnalités flexible pour customiser son jeu !

Il est important de noter que les "vues" du script sont génériques pour inciter le maker à concevoir ses propres rendus visuels !


Vues du script



Journal de quêtes


Magasin de quêtes



Installation



Ce script requiert l'installation de CustomDatabase pour fonctionner.
Copiez le script dans votre éditeur de script au dessus de Main, dans la rubrique Materials. Vous pouvez lui attribuer un emplacement réservé. Et le nommer comme vous l'entendez. Personnellement, j'ai choisi le nom Super système de quêtes trop swagg ! (original :P !)
Je conseil de préparer un espace script en dessous de ce script qui servira à insérer les quêtes.

[url=https://raw.githubusercontent.com/nukiFW/RPGMaker/master/QuestSystem/script.rb[/url]

Création d'une quête



Comme conseillé dans la directive d'installation, il est recommandé de créer un espace libre en-dessous du script qui servira à écrire les quêtes. Lorsque je parlerai de création de quêtes, je partirai du principe que vous les décrivez dans cet espace.
Syntaxe de création d'une quête

Pour créer une quête, il suffit d'ajouter ceci dans l'espace libre :

Code (Ruby):
  1. Quest.create(
  2. :id => NUMERO_DE_LA_QUETE,
  3. :name => "Nom de la quête",
  4. :desc => "Description de la quête"
  5. )


Il s'agit de la syntaxe minimale pour créer une quête. Cependant, il existe une foultitude de paramètres en plus.

Paramètres complémentaires



Les paramètres complémentaires permettent de spécialiser une quête pour lui permettre par exemple, de définir les récompenses, la condition de déclenchement, ou encore le prix de la quête (car nous verrons plus tard que les quêtes peuvent être achetées). Chaque paramètre doit être séparé par une virgule.


:gold

Il est possible de paramétrer la quantité d'Or que rendra la quête une fois terminée. Pour cela, il suffit d'ajouter l'option :gold => QUANTITE_DOR_RECUE.

:exp

Une quête peut aussi faire gagner de l'expérience à l'équipe une fois terminée au moyen de l'option :exp => NOMBRE_DE_POINT_D_EXPERIENCE_RECUS.

Exemple de quêtes donnant de l'expérience et de l'or

Code (Ruby):
  1. Quest.create(
  2. :id => 1,
  3. :name => "Rencontrer Pierre",
  4. :desc => "Aller parler à Pierre, au nord du Village",
  5. :gold => 200,
  6. :exp => 120
  7. )


:items

Comme pour l'or et l'expérience il est possible de paramétrer une liste d'objets à recevoir en cas de succès de la quête : :items => [listes des identifiants d'objets à recevoir séparé par une virgule].

:weapons

Comme pour les objets il est possible de paramétrer une liste d'armes à recevoir en cas de succès de la quête : :weapons => [listes des identifiants d'armes à recevoir séparé par une virgule].

:armors

Comme pour les armes il est possible de paramétrer une liste d'armures à recevoir en cas de succès de la quête : :armors => [listes des identifiants d'armures à recevoir séparé par une virgule].

Exemple de quêtes donnant de l'expérience et de l'or et des objets

Code (Ruby):
  1. Quest.create(
  2. :id => 1,
  3. :name => "Rencontrer Pierre",
  4. :desc => "Aller parler à Pierre, au nord du Village",
  5. :gold => 200,
  6. :exp => 120,
  7. :items => [1,1,2],
  8. :weapons => [2],
  9. :armors => [3]
  10. )


Voici une quête qui donne en cas de réussite, 200 d'or, 120 points d'expérience à toute l'équipe, 2 fois l'objet 1, une fois l'objet 2, l'arme 2 et l'armure 3.

:label

Généralement, les quêtes sont référencées par leur id. Nous verrons plus tard comment démarrer des quêtes, ou vérifier si une quête est finie, en nous servant de leur id. Cependant, les ids étant des nombres, on peut leur attribuer un label, qui est un petit mot pour qu'elles soient plus faciles à référencer. Le label est très utile lorsqu'on a une très grande collection de quêtes à manipuler. Il s'ajoute de cette manière : :label => :nom_du_label. Par défaut, le label d'une quête est :quest_ suivi de son ID, par exemple :quest_1.

:cost

La notion de coût d'une quête intervient lorsque l'on verra les magasins de quêtes, pour qu'une quête soit accessible dans un magasin, elle doit impérativement avoir un coût, c'est le prix d'achat de la quête. Le coût s'ajoute avec :cost => PRIX_DE_LA_QUETE. Si une quête n'a pas de coût, elle se sera pas affichable dans un magasin malgré la possibilité que celui-ci la contienne dans son stock.

:repeatable

Par défaut, une quête déjà lancée (donc présente dans le journal de quêtes) ne peut être relancée. Une quête répétable sera donc, une fois terminée, supprimée du journal de quête et pourra être relancée. On ajoute cette option de cette manière : :repeatable => true (Ou alors false. Cependant, autant ne pas spécifier l'option de répétition si une quête ne doit pas l'être).

:need_confirmation

Cet attribut est un peu particulier. En effet, il distingue la réussite d'une quête d'avec sa complétude. Par exemple, si une quête est achetée en magasin, une fois terminée, le joueur recevra automatiquement les récompenses. Si elle doit être complétée (via l'option : :need_confirmation => true), le joueur devra se rendre dans un magasin qui peut vendre cette quête pour la compléter. Il est aussi possible de compléter manuellement une quête (via un appel de script que nous détaillerons plus tard). La confirmation des quêtes permet de forcer le joueur à retourner au lieu de démarrage de la quête pour gagner ses récompenses. Dans le menu des quêtes (le journal), on distingue une quête complète d'une quête finie.

Conditions internes



Les conditions internes sont des éléments qui rendent la création d'un jeu plus facile. En effet, lorsque je présente un exemple de quête, "tuer 3 slimes", le souci c'est que la condition de réussite de la quête est extrêmement compliquée à représenter. Nous allons voir qu'il est possible d'automatiser le succès (ou l'échec) d'une quête dans certains contextes.


:success_trigger

L'option :success_trigger => condition_de_fin_avec_succes permet de définir une condition de succès d'une quête. Nous verrons comment concevoir des conditions de déclenchement un peu plus tard.

:fail_trigger

L'option :fail_trigger => condition_de_fin_avec_echec permet de définir une condition d'échec d'une quête.

Créer une condition



var_check(id, value)

Cette primitive permet de vérifier la valeur d'une variable. En effet, la primitive var_check(5, 10) sera considérée comme étant valide quand la variable 5 sera égale à 10. Il est possible de spécifier des opérateurs en 3ème argument :

var_check(5, 10) => vérifie que la variable 5 est égale à 10
var_check(5, 10, :>) => vérifie que la variable 5 est plus grande que 10
var_check(5, 10, :<) => vérifie que la variable 5 est plus petite que 10
var_check(5, 10, :>=) => vérifie que la variable 5 est plus grande ou égale à 10
var_check(5, 10, :<=) => vérifie que la variable 5 est plus petite ou égale à 10
var_check(5, 10, :!=) => vérifie que la variable 5 est différente 10

switch_check(id, :activated | :deactivated)

switch_check(2, :activated) => vérifie si l'interrupteur 2 est activé
switch_check(2, :deactivated) => vérifie si l'interrupteur 2 est désactivé

Conditions de possessions d'objets

has_item(id, total) => vérifie que le joueur possède bien l'objet référencé par id, au moins un certain nombre de fois (défini par total)
has_weapon(id, total) => vérifie que le joueur possède bien l'arme référencée par id, au moins un certain nombre de fois (défini par total)
has_armor(id, total) => vérifie que le joueur possède bien l'armure référencée par id, au moins un certain nombre de fois (défini par total)

monster_killed(id, total)

A partir du déclenchement de la quête, cette primitive oblige de battre un nombre de fois (défini par total) le monstre référencé par id.

Opérations logiques entre les primitives



Avec ces primitives, il n'est pas possible de représenter par exemple, comme condition, le meurtre de 5 slimes ET la possession de l'arme 1. De même qu'il n'est pas possible de représenter la disjonction "tuer 5 slimes OU posséder 5 objets de peaux de slimes". C'est pour ça que ce script permet de lier les primitives entre elles au moyen de connecteurs logiques. Soit & pour représenter le ET, et | pour représenter le OU. Par exemple, imaginons une quête qui est réussie par la mort de 5 monstres 1 et par la possession de l'arme 1 : :success_trigger => monster_killed(1, 5) & has_weapon(1, 1). De même que l'on pourrait admettre qu'une quête est réussie si la variable 10 est plus grande que 7 et si l'interrupteur 10 est activé, ou que l'arme 10 est possédée en 13 exemplaires : :success_trigger => (var_check(10, 7, :>) & switch_check(10, :activated)) | has_weapon(10, 13). Il est possible de composer des motifs vraiment raffinés de quêtes pour ne pas devoir coder, en eventmaking, chaque embranchement d'une quête. Cependant, il est tout de même possible de terminer manuellement ces quêtes.

Exemple de quêtes avec succès automatique

Code (Ruby):
  1. Quest.create(
  2. :id => 2,
  3. :name => "Le slime et la potion",
  4. :desc => "Tuer deux slimes et trouver une potion",
  5. :gold => 100,
  6. :exp => 100,
  7. :success_trigger => monster_killed(1, 2) & has_item(1, 1)
  8. )


Cette quête se terminera une fois que le joueur aura tué deux slimes et possèdera une potion. Il ne faut pas implémenter le test, et les récompenses seront données automatiquement. Un autre exemple serait :

Code (Ruby):
  1. Quest.create(
  2. :id => 2,
  3. :name => "Le slime et la potion",
  4. :desc => "Tuer deux slimes et trouver une potion",
  5. :gold => 100,
  6. :exp => 100,
  7. :success_trigger => monster_killed(1, 2) & has_item(1, 1),
  8. :fail_trigger => switch_check(3, :activated)
  9. )


Qui échouerait si l'interrupteur 3 est activé.

Condition de lancement d'une quête



Il est aussi possible d'avoir une condition de déclenchement (ou d'achat, dans les magasins) de quêtes. Pour cette section, il vaut mieux avoir des connaissances en Ruby, ou se servir de l'Event Extender pour avoir des fonctionnalités plus faciles. Il s'agit de l'option : :verify => check{condition de lancement}. Par exemple, pour qu'une quête soit lançable seulement si le niveau du premier héros est plus grand que 3: :verify => check{$game_actors[1].level > 3}. (Les connecteurs logiques && et || sont utilisables, évidemment).
Déclenchement d'action en fin de quête

Une fois qu'une quête est finie, il est possible de lancer une action, via l'option : :end_action => action{Liste d'actions à effectuer en fin de quête} (L'action est déclenchée après la finition de la quête, il est donc possible de savoir, dans les actions, si la quête a été finie ou non).


Usage des appels de scripts



Dans cette section, tous les arguments id peuvent être remplacés par le label d'une quête.

Quest.start(id) : Démarre la quête référencée par son id (même si la condition de lancement n'est pas respectée)
Quest.finished?(id) : Renvoie true si la quête est finie, [strong]false sinon
Quest.succeeded?(id) : Renvoie true si la quête a été finie avec succès, false sinon
Quest.failed?(id) : Renvoie true si la quête a été finie avec échec, false sinon
Quest.ongoing?(id) : Renvoie true si la quête est en cours, false sinon
Quest.finish(id) : Finit la quête avec succès
Quest.fail(id) : Finit la quête avec échec
Quest.need_confirmation?(id) : Renvoie true si la quête demande une confirmation, false sinon
Quest.confirm(id) : Confirme une quête finie, donne la récompense
Quest.launchable?(id) : Renvoie true si la condition de lancement de la quête est respectée, false sinon SceneManager.questShop([liste_des_quetes_vendables]) : Lance un magasin de quêtes, avec un stock, la liste des quêtes passée en argument.


Configuration du script



En début de script, il existe un module de configuration, qui permet de changer le vocabulaire du script, mais aussi l'accès au journal des quêtes dans le menu.

Journal des quêtes et magasins



Le script dispose d'un journal des quêtes, basé sur le menu d'objets (respectant son architecture visuelle) et d'un magasin de quêtes, ressemblant aux magasins natifs. Je vous invite tout de même à faire votre propre script de magasin/journal, pour avoir quelque chose de très original.

Bonne utilisation !

icone Conclusion


Ces deux scripts présentent des usages concrets d'un système de base de données étendue. Et même si (surtout le deuxième) ils restent "longs", la base de données automatise beaucoup de partie ennuyantes et le scripteur peut donc se focaliser sur des choses que je trouve (IMHO) plus intéressantes. J'espère que le deuxième script vous sera utile et je vous souhaites une bonne soirée Smiley!

Index

Tags

Annonces
Bilou Concept
BilouCorp
Découvertes
Event Extender
Jeux
RPG Maker
Script
Tutoriel

Auteurs

2cri
Grim
Hiino
Joke
Nuki
PypeBros
Raho
S4suk3

Suivez nous
Rss

Poster un commentaire



Commentaires

nuki
En fait c'est une faute de frappe; y'a pas besoin d'échapper. Mais merci. Posté le : 02/03/2015 à 22h36
Fridjah
Bravo pour ton scriptage et respect pour tes connaissances en ce domaine.
Je ne suis absolument pas scripteur, mais j'aimerais juste faire part d'un
petit détail. Dans le script, tu écris: "il n 'y a pas de quêtes" avec un double espace entre (n et ').
Si tu écris: "il n\'y a pas de quêtes" sans espace entre (n et \ et ') tout
s'écrit parfaitement bien ^^.
J'ai découvert ça par hasard il y a quelque jour en bidouillant un autre
script.
Sans aucune prétention, j'espère avoir rendu service.
Encore bravo et bonne continuation!
Posté le : 08/02/2015 à 11h31
Lothang
Merci.
Ce script est vraiment génial... Je m'en sers avec des ajouts pour pouvoir modifier la description des quêtes de manière dynamique. Et pour réussir à faire cela j'ai eu le plaisir de lire les autres tutos disponibles sur le site.
Encore merci à toute la Corp. Posté le : 30/01/2015 à 20h40
Spyrojojo
quand je vois l'utilisation que l'ont peu en faire ,je me dit que mon atlas serait bien plus présentable avec ce system ^^.Une fois de plus j'approuve totalement . Posté le : 13/11/2014 à 10h34
Nuki
C'est en réflexion ... Posté le : 12/11/2014 à 11h49
Joke
Et un script qui mérite de la visibilité.
Une démo un jour, peut-être ? :) Posté le : 11/11/2014 à 19h46
Grim
Ohwooooi ! Chic chic ! Posté le : 08/11/2014 à 11h13
Rajang
Bilou de retour !!! Posté le : 06/11/2014 à 17h40