Ajouter des champs à la base de données
Script RGSS3 Ace
La présentation de ce script est destinée aux scripteurs, qu'ils soient novices ou confirmé. Il ne s'agit pas vraiment d'un tutoriel mais d'une présentation de script.
Introduction
La base de données de RPG Maker offre une structure statique. Ce que j'entend par une structure statique c'est qu'il est impossible de modifier les champs de la base de données. Par exemple, si voulais rajouter une caractéristiques aux objets, je serais "à priori", bien ennuyé. ;)
Pour ce faire, j'ai écrit un script pour étendre les champs de la base de données au moyen du champs "Notes":
L'objectif de cet espace dans la Base de données est de permettre d'écrire des informations sur une entrée. L'avantage, c'est qu'il nous est possible d'écrire ce que l'on veut. C'est donc via cet espace que nous spécifierons les caractéristiques complémentaires que nous voulons ajouter.
Un peu de vocabulaire
Je vous parle de tables, de champs, d'entrées, je pense qu'une petite spécification de vocabulaire serait le bienvenu !
Premièrement, une base de données est constituée de tables. Une table est un espace où seront rangées des entrées qui respectent la structure d'une table. (Par exemple, la table "objets" est caractérisé par un nom, une description, une icone, un type, un prix etc.), ces caractéristiques sont des champs, une potion serait une entrée de la table "objets" car elle respecte la structure "d'objets" (et qu'elle est rangée dans cet espace). Voici un petit schéma pour plus de clarté :
L'objectif de cet article et de ce script est de pouvoir ajouter des champs (donc des caractéristiques) à des entrées dans une table de la base de données. Par exemple une caractéristique "coût_mp" qui permettrait de spécifier un coût_mp à chaque utilisation de l'objet. (Ce qui serait tout à fait faisable via les effets mais nous verrons, un peu plus bas, une utilisation plus pratique).
Obtenir le script
Le code source du script est disponible à l'adresse suivante :
Lien vers le script et c'est sur cette page que le script sera maintenu.
Ecrire des commandes
L'écriture de commande est très simple, il suffit de vous rendre dans un espace "Notes" de votre base de données et d'écrire des commandes. Leur syntaxe est du XML, très semblable à du HTML pour ceux qui connaissent, nous allons nous empresser d'étudier la structure de ces commandes. Il existe deux types de commandes, nous allons les détailler tout de suite.
La commande simple
La commande simple est la manière la plus simple (logique me direz-vous
) de présenter une donnée. Elle respecte ce motif:
Code (XML): <identifiant>valeur</identifiant>
"identifiant" et "valeur" sont des données variables. Par exemple, si j'avais eu envie d'ajouter un champ "petit_nom" et un champ "orientation_sexuelle" à ma table "Héros", j'aurais pu ajouter à mes héros les données suivantes :
Code (XML): <petit_nom>Ralphounet</petit_nom>
<orientation_sexuelle>Femmes</orientation_sexuelle>
Il suffirait simplement de rajouter ces deux lignes dans le champs "Notes" de chaque héros pour pouvoir caractériser ces deux données en plus de la structure déjà proposée par RPG Maker.
Il est important de noter qu'il n'est pas obligatoire de rajouter les champs à toutes les entrées car nous verrons plus tard qu'il est possible de tester l'existence d'une commande.
La commande complexe
Ecrire une commande simple est assez facile, cependant, ça peut être assez lourd. Admettons que je veuille rajouter des champs pour décrire une couleur (référencé par une valeur pour du rouge, une valeur pour du vert et une valeur pour du bleu), je devrais ajouter 3 champs:
Code (XML): <red>255</red>
<green>120</green>
<blue>120</blue>
Premièrement c'est lourd, 3 lignes pour des commandes aussi simples. En plus, il faudrait idéalement que je place un préfixe pour être sur de ne pas devoir ajouter une commande "red" qui n'aurait rien à voir avec la couleur (pour l'exemple
), c'est pour ça que j'ai implémenté une deuxième forme de commande :
Code (XML): <color red="255" green="120" blue="120" />
Vous ne trouvez pas ça plus confort pour stocker plus de données sous un seul libellé?
Donc concrètement, la syntaxe pour écrire une commande dite "complexe" est :
Code (Autre): <nom_commande [list d'attributs séparé par un espace] />
Et la syntaxe d'un attribut est :
N'oubliez pas de mettre les valeurs entre guillemets pour savoir quand la valeur de l'attribut se termine. Personnellement, je me sers de cette notation quand je veux grouper plusieurs valeurs pour construire une caractéristique. Mais c'est à vous de choisir selon votre préférence.
Récupérer des commandes
Maintenant que nous savons comment greffer des entités à nos entrées dans la base de données, nous allons nous intéresser à leur récupération. Ce qui est relativement pratique sinon ça ne servirait à rien :)
Récupération du champs "notes" d'une entrée
La lecture des entités fonctionne sur toute chaîne de caractères, mais comme la base de données est le seul emplacement où il est possible d'attribuer du texte de manière libre, nous allons nous focaliser sur cet aspect. Pour lire les notes j'ai créé une petite API pour rendre cette lecture facile. Il s'agit d'une fonction
notes:
L'argument "type" peut prendre plusieurs valeur que je donne juste en dessous et l'argument "id" prend l'id de l'entrée dans la base de données voulu. Concrètement, on spécifie la table ensuite l'id de l'entrée voulu:
• :actors
• :classes
• :skills
• :items
• :armors
• :weapons
• :ennemies
• :states
• :tilesets
Donc par exemple
notes(:actors, 2) donnera les notes de l'acteur 2. Si l'argument type est mauvais, la fonction renverra
nil. Cette fonction est accessible de partout une fois que le jeu a été lancé. Donc il est possible de l'utiliser dans n'importe quel script qui se lance une fois qu'une partie est lancée.
Récupérer les entités d'une note
Maintenant que nous avons vu a quel point il est facile de récupérer les notes de la base de données, nous allons extraire les données expressives d'une note. Pour ça il suffit d'utiliser la commande
entities, par exemple :
Code (Ruby): acteur_info = notes(:actors, 2).entities
Admettons que notre acteur référencé par l'identifiant 2 ait eu pour notes :
Code (XML): <red>255</red>
<green>120</green>
<blue>120</blue>
J'aurais pu faire :
Code (Ruby): acteur_info = notes(:actors, 2).entities
red = acteur_info["red"].value
green = acteur_info["green"].value
blue = acteur_info["blue"].value
Pour récupérer chaque valeur de même que j'aurais pu compresser cet appel sans passer par une variable :
red = notes(:actors, 2).entities["red"].value
Pour récupérer une note complexe, le procédé est le même. Admettons que notre acteur 2 ait pour notes cette valeur :
Code (XML): <color red="255" green="120" blue="120" />
Voici de quelle manière j'aurais pu isoler ses composantes :
Code (Ruby): acteur_info = notes(:actors, 2).entities
red = acteur_info["color"]["red"].value
green = acteur_info["color"]["green"].value
blue = acteur_info["color"]["blue"].value
Ou alors avec une forme sans passer par une variables :
red = notes(:actors, 2).entities["color"]["red"].value
Le rôle du ".value" ?
Certains trouveront l'obligation d'utiliser la méthodes ".value" douteuse mais c'est car l'appel de
notes(:actors, 2).entities["color"]["red"] renvoi une entité, soit un objet entité, il faut donc en extraire sa valeur. L'objectif est de conserver les méthodes d'une entité est d'altérer son type (concept que nous verrons plus tard). Il ne faut donc pas oublier de spécifier que vous voulez récupérer la valeur et non uniquement l'entité !
Un système de type minimaliste
Nous savons créer des champs, les récupérer. Mais un problème se pose à nous. Toutes les données que nous récupérons sont sous forme de chaîne de caractères. Ce script possède donc son propre système de type (minimaliste) pour créer des conversions potentiellement pertinente. Nous allons donc voir comment établir une conversation pour les données extraites au moyen d'une méthode qui offre "plus de possibilités" facilement accessible que via les méthodes du cœur de Ruby.
Décrire une altération de type
En parlant de typage, je mens... pour dire la vérité, ce script n'est pas "typé", il permet juste de faire des conversions de type "un peu plus raffinées" que Ruby (enfin, plus spécifiques). Pour modifier le type d'une valeur d'une entité, il suffit de faire
mon_entité.coercion(:type_désiré). Voici la liste des types disponible pour la conversion :
• :int (nombre entier)
• :float (nombre à virgule)
• :bool (booléan, true ou false)
• :string (du texte)
• :string_list (une liste de chaine, "aha, ohoho, hihih" donnera ["aha", "ohoho", "hihih"]
• :int_list (utilise aussi la virgule comme séparateur)
• :float_list (utilise aussi la virgule comme séparateur)
• :bool_list (utilise aussi la virgule comme séprateur)
Par exemple pour changer le type de retour dans mon exemple précédent et recevoir des entiers pour les couleurs, j'aurais pu faire :
Code (Ruby): acteur_info = notes(:actors, 2).entities
acteur_info["color"]["red"].coercion(:int)
acteur_info["color"]["green"].coercion(:int)
acteur_info["color"]["blue"].coercion(:int)
red = acteur_info["color"]["red"].value
green = acteur_info["color"]["green"].value
blue = acteur_info["color"]["blue"].value
Ou encore, comme la coercion renvoi l'entité elle même :
Code (Ruby): acteur_info = notes(:actors, 2).entities
red = acteur_info["red"].coercion(:int).value
green = acteur_info["green"].coercion(:int).value
blue = acteur_info["blue"].coercion(:int).value
La conversion agit toujours sur le format source (en texte) donc pas de panique si vous faites une conversion douteuse !
Cas pratique
Maintenant que nous sommes capable de manipuler avec précisions nos entités, je vais vous présenter un petit cas pratique, un petit script que j'ai du rédiger récemment qui tirait partit de ce script pour étendre la base de données.
Objectif du script
Olowynd a dit : Vous avez l'honneur de recevoir une demande d'aide de la part du grand Olowynd :troll:
Je me demandais comment faire pour colorer les noms des items, armes, armures... en fonction de leur ID. Je ne pense pas que ce soit très compliqué, aussi si vous en avez le courage, vous pouvez m'aider à faire ce script, mais comme je suis une quiche en script il sera plus pratique et moins long pour vous de me le faire déjà tout prêt et j'essayerais de comprendre. C'est comme vous voulez ( en supposant qu'il y ait une bonne âme qui a le temps et l'envie de venir m'aider \o/ ).
Par exemple, quelque chose comme ceci :
Extension des champs
Plutôt que de m'ennuyer à créer une liste des éléments qui doivent prendre une certaine couleur, j'ai préféré ajouter aux objets/armes/armures des champs pour les données qui doivent être colorées. C'est ici que cet excellent script (
) intervient ! Nous allons ajouter une commande qui aura cette forme :
Code (XML): <color r="valeur rouge" v="valeur vert" b="valeur bleu" />
Où les valeurs de r, v et b correspondraient à des entiers compris entre 0 et 255 pour composer une couleur. Par exemple, pour la potion, je mettrais :
Code (XML): <color r="255" g="120" b="120" />
Nous pouvons maintenant passer à l'implémentation !
Implémentation du script
J'aimerais que cette modification de la couleur n'agisse que dans la liste des objets (inventaire), pour ça je vais modifier la méthodes qui se charge de dessiner un objet, elle se trouve dans
Window_Base :
Code (Ruby): #--------------------------------------------------------------------------
# * Draw Item Name
# enabled : Enabled flag. When false, draw semi-transparently.
#--------------------------------------------------------------------------
def draw_item_name(item, x, y, enabled = true, width = 172)
return unless item
draw_icon(item.icon_index, x, y, enabled)
change_color(normal_color, enabled)
draw_text(x + 24, y, width, line_height, item.name)
end
Nous allons la réécrire dans
Window_ItemList (pour qu'elle n'agisse que dans la liste d'objets). Si vous voulez que la coloration agisse partout, modifiez celle de
Window_Base. Je vous invite donc à créer un nouveau script en dessous du script d'entités. Vous pouvez l'appeler "Colorisation des objets" et voici la modification que je vous propose, j'ai essayé de l'a commenter aux mieux !
Code (Ruby): # Colorise certains objets
# Depend du Script Typed Entities
# ici : https://github.com/Funkywork/Scripts-rm/blob/master/VXAce/Typed-Entity.rb
# Pour qu'un objet (objet, arme, armure) soit colorisé, il faut que dans sa "note" (BDD)
# il y ait : <color r="valeur" v="valeur" b="valeur" />
# la valeur peut aller de 0 à 255
# Auteur : S4suk3 (Biloucorp http://www.biloucorp.com)
#==============================================================================
# ** Window_ItemList
#------------------------------------------------------------------------------
# This window displays a list of party items on the item screen.
#==============================================================================
class Window_ItemList
#--------------------------------------------------------------------------
# * Draw Item Name
# enabled : Enabled flag. When false, draw semi-transparently.
#--------------------------------------------------------------------------
def draw_item_name(item, x, y, enabled = true, width = 172)
return unless item
# Récupération des entités
command = item.note.entities
# On établit la couleur "normal" (définie dans le RGSS)
color = normal_color
# On vérifie si notre entité "color" existe ?
if command["color"]
# Si oui on modifie le type de leur valeur (pour avoir des entiers)
red = command["color"]["r"].coercion(:int).value
green = command["color"]["g"].coercion(:int).value
blue = command["color"]["b"].coercion(:int).value
# On remplace la variable color par un objet Color créé avec les données de la BDD.
color = Color.new(red, green, blue)
end
# Si on n'est pas rentré dans la condition, color sera identiqué à normal_color
# sinon elle contiendra la couleur composée par les champs de la BDD
draw_icon(item.icon_index, x, y, enabled)
change_color(color, enabled)
draw_text(x + 24, y, width, line_height, item.name)
end
end
Voila ! Vous pouvez tester le script, il fonctionne ! Et l'implémentation est très courte car toute la logique d'interaction avec le maker est contenue dans le script des entités typées !
Conclusions
Nous avons fait le tour de ce script qui pourrait vraiment vous faciliter la tâche ! J'espère que vous en aurez bien comprit l'usage et que les scripteurs s'en serviront pour permettre d'étendre un peu plus la base de données.
Remapper toute sa base de données
Ce script permet l'ajout de données mais ne permet pas de restructurer totalement l'intégralité de la base de données. Pour permettre ça, vous pouvez soit utiliser
L'Event Extender de Grim qui propose son interface de manipulation de la base de données avancée (documentée) ou même
L'extension de base de données de Nuki (qui fonctionne avec l'Event Extender) et qui a été prévu pour modeler à sa guise une base de données. Car ce script sert avant tout à rajouter des petites features "rapide".
Bonne utilisation !
Posté le : 29/04/2014 à 12h58