Rom Hack & Fan Game

Créer un système de Baies

Salut, je vais vous présenter un petit tutoriel qui vous permettra de programmer un système de baie vous-même. Le but de tuto ne sera donc pas de vous donner un script tout fait qui fonctionnera directement chez vous, il sera question de vous donner les clefs qui vous permettront de programmer votre système.

Sommaire :

Niveau du tutoriel : Moyen

Connaissances requises :

  • Savoir programmer en Ruby.
  • Connaitre le fonctionnement des scripts de base d’RPG Maker XP, notamment le système d’évènement et de gestion de l’affichage de la MAP.
  • Savoir ajouter des variables à une classe.
  • Connaître les bases de la classe Array et de la classe Hash.
  • Savoir utiliser les constantes.
  • Connaître le fonctionnement du Sac de Pokémon Script Project.
  • Savoir que commencer un nombre par un Zéro avec que des chiffres derrière c’est de l’octal donc ce n’est pas bien. (RPG Maker XP affiche tous les ids en commençant par des Zéro, ceci fait faire des erreurs aux débutants alors considérez que quand c’est écrit 005, RPG Maker XP pense à 5.)

Ce dont vous aurez besoin :

  • Un système de gestion du temps. C’est la raison pour laquelle le script ne sera pas fonctionnel, il a besoin d’un système de gestion du temps et ceci est propre à chaque projets, chez certains c’est l’horloge du PC, chez d’autres, c’est un temps dilaté et chez moi, c’est un temps géré par un comptage de frame.
  • Les Characters des baies. Sans ça, le système sert un peu à rien.
  • Que les objets des baies soient crées dans la base de données, il faudra aussi faire en sorte à ce que toute les baies soient l’une derrière l’autre afin de simplifier la gestion des données des baies.

Hypotheses à retenir tout au long du tutoriel :

  • $game_variables[VAR_HEU] représente l’heure du jeu au moment où vous utilisez cette variable.
  • $game_variables[VAR_JOU] représente le jour de la semaine.
  • $game_variables[VAR_SEM] représente le nombre de semaines écoulés depuis le début de la partie.
  • VAR_HEU représente l’id de la variable contenant l’heure.
  • VAR_JOU représente l’id de la variable contenant le jour de la semaine.
  • VAR_SEM représente l’id de la variable contenant le nombre de semaines écoulés.

Avant de commencer à coder quoi que ce soit, il faut prendre un papier et un crayon puis se poser des questions et écrire vos idées. C’est une étape importante qu’il ne faut pas négliger sous peine de mal concevoir votre programme ou script dans notre cas.
Nous allons donc nous poser les questions essentielles et je vais exposer mes choix (qui sont largement discutable, on a tous nos manières de faire.)

1) Un système de baie, comment ça pourrait fonctionner ?

La base est évidemment de se représenter un fonctionnement potentiel d’un quelconque système de baie.
Quand vous jouez aux versions RSE et DPP de Pokémon, la première fois que vous rencontrez une terre fertile, il y avait une baie planté et qui était au dernier stade de sa croissance.
Après avoir récupéré la baie, elle disparaissait puis vous pouviez planter une baie et là, la baie plantée passait par plusieurs états de croissances, pousse, naissance de l’arbuste, floraison et maturité (les fruits apparaissent et vous pouvez les cueillir).

2) Comment faire ceci sur un projet RPG Maker ?

Il faut pouvoir voir ces états, dans les faits, il existe deux états principaux, la baie initialement présente et la baie qui devra pousser. Pour simplifier les choses, je choisis d’utiliser le système d’évènement d’RPG Maker qui me permettra de gérer très facilement l’affichage à l’écran de la baie et aussi d’interagir avec le joueur sans trop scripter ce qui est parfois plus simple.

3) D’accord, je choisi l’évènement mais maintenant, comment gérer cet évènement ?

Là le choix se pose sur quelque chose de tout simple, nous allons considérer que l’évènement est un objet à ramasser, sauf que lorsque nous entrerons sur la MAP, il se ramassera tout seul et n’ajoutera rien dans notre sac.
C’est une vision un peu particulière, en fait au lieu d’afficher un message et ajouter des choses dans le sac, l’évènement va dire au système de baie, qu’il contient une baie, après l’avoir dit, il désactive sa page par défauts pour laisser place à la page qui gère la récolte de la baie. (Par conséquent la plantation car je vais faire l’interaction joueur->arbuste/terre dans une seule page).

4) Maintenant que la partie émergée de l’iceberg a été réglée, pensons à la partie immergée : Comment le système de baie va-t-il mémoriser tout ceci ?

Eh oui, il faut que le système de baie sache quel évent contient quelle baie et quelles informations annexes. Par conséquent, il faut  lui permettre d’enregistrer les informations que les évènements activant l’état initial des arbustes à baie fournissent.
De manière plus générale, le système de baie doit mémoriser les informations de toutes les baies plantées donc il faut une variable. Pour une gestion simple et optimisés, je choisi de créer une variable dans Pokémon Party qui contiendra un Hash.

Pourquoi Pokémon Party ? Tout simplement parce que l’objet contenu dans $pokemon_party est systématiquement sauvegardé donc il est plus simple de placer une variable dedans que de s’embêter à gérer la sauvegarde.
Pourquoi un Hash ? Tout simplement parce que je vais enregistrer quel évent contient quelle baie donc un évent a un id et est stocké sur une map, je vais me servir de l’id de la map comme index donc je préfèrerai le Hash au tableau (Array) pour ne pas avoir à initialiser tout un tas de case vide lorsque le joueur n’a pas encore visité les autres maps. (Surtout quand l’id des maps n’est pas correspondant à l’ordre de passage du héros.) Dans le fond, Hash ou Array, ça ne fera pas trop de différence tant que vous pouvez récupérer les objets avec l’id de la map courante.

5) Comment le système peut faire pour savoir si une baie est arrivée à maturité ou est passé par un certain état ?

Le système doit avoir certaines informations en mémoire afin de fonctionner correctement donc il faudra construire un data contenant les informations principales sur les baies. Comme mon système est assez simple, les données seront juste, le nombre de baies donnés et le temps qu’il faut pour qu’elle passe un état de croissance.

6) D’ailleurs, j’ai les ressources mais elles ne correspondent pas aux l’ids des baies dans la base de données…

Quand j’ai extrait les ressources des baies via un petit script, les images ne sont pas sorties dans l’ordre réel des baies (Baie Ceriz en première position par exemple). Comme je n’ai pas envie de m’amuser à remettre toute les baies dans l’ordre, j’ai préféré ajouter une données dans le datas des baies indiquant l’id du Character à prendre pour l’affichage de l’arbuste.

7) Finalement, quel modèle de fonctionnement choisir pour le système de baies ?

Maintenant qu’on a répondu à ces questions-là, faut choisir un modèle qui sera notre système de baies à savoir comment le système sera géré. J’ai choisi de faire un module qui se sépare en deux grands axes : La mise à jour du système (qui va en réalité influer sur la MAP) et la récupération des informations qui devra se faire dans la mise à jour mais aussi via les évènements.

Nous arrivons à la partie principale : la programmation du système de baie. Avant tout, nous allons créer le module qui gère le système de baies.
Ce module-là, je vais le stocker dans un autre module qui contient tous mes systèmes. Pourquoi je fais ça ? Juste pour que ce soit un peu moins le bordel, faut considérer que les constantes/modules/classes sont comme des fichiers, si vous mettez tout à la racine, ça devient un sacré bordel alors on peut utiliser des modules qui agissent comme des dossiers et qui contiennent les classes et modules qui doivent d’être séparés du reste pour éviter les problèmes et le bordel :d
Mes systèmes sont tous stockés dans le module Yuki, par conséquent pour y accéder je dois taper Yuki ::NomDuModule, et aussi pour créer les modules je dois mettre le corps du module entre « module Yuki » et « end ».

Bref, voici le corps du système de baie :

#===
#¤Yuki::Berries
#---
#%Script permettant de simuler les baies
#---
#© 27/07/2013 - Nuri Yuri (? ??)
#===
module Yuki
  #Je déclare le module Berries dans Yuki.
  module Berries
    #Ici seront définies toutes les constantes
    
    module_function
    #Ici seront défini toutes les méthodes
    
  end
end

Le mot clef module_function permet de dire à Ruby que toute les méthodes qui suivent ce mot clef seront des singleton de Yuki::Berries, pour accéder aux méthodes on pourra donc taper Yuki::Berries.nom_de_la_methode(arguments).

Maintenant commençons à initialiser le data des baies, je vais créer une constante contenant les données dans un tableau. Ce tableau s’organisera de la manière suivante :
tableau[id]=[chara_id, nb_hour, nb_berries]

  • id sera l’id de la baie à partir de l’index 1.
  • chara_id c’est le numéro du character qui correspond à l’affichage de l’arbuste sur la map.
  • nb_hour est le nombre d’heure qu’il faut pour observer un changement d’état dans la croissance de la baie.
  • nb_berries est le nombre de baies que le système donnera au joueur quand il récoltera.
  • tableau devra être remplacé par le nom de la constante, ici, je choisi Data_Berries.

Il faut aussi stocker des informations essentielles, le modèle de nom des baies, dans mes ressources elle commence par Z_B et finissent par l’id, j’ai choisi un tel nom pour que les characters soient automatiquement affiché à la fin dans l’éditeur comme ça je trouve plus rapidement les charas des personnages.
On crée une constante contenant le modèle de nom des baies : BERRY_NAME="Z_B%02d"

Après avoir initialisé nos constantes notre script devrait ressembler à ceci :

#===
#¤Yuki::Berries
#---
#%Script permettant de simuler les baies
#---
#© 27/07/2013 - Nuri Yuri (? ??)
#===
module Yuki
  #Je déclare le module Berries dans Yuki.
  module Berries
    #Données des baies
    Data_Berries=[[],
    [6,20,2], [5,20,2], [4,20,2], [3,20,2], [2,20,2],
    [1,20,2], [64,20,2], [63,20,2], [62,20,2], [61,20,2],
    [56,20,2], [55,20,2], [34,20,2], [33,12,5], [12,20,2],
    [11,20,2], [24,20,2], [23,20,2], [22,22,3], [21,20,2],
    [20,22,4], [19,20,2], [18,22,3], [17,22,3], [16,22,3],
    [15,20,2], [14,20,2], [13,20,2], [10,20,2], [9,20,2],
    [8,12,5], [7,20,2], [42,20,2], [41,20,2], [40,22,3],
    [54,22,3], [53,22,3], [52,12,5], [51,20,2], [50,22,3],
    [49,20,2], [48,20,2], [47,20,2]]
    #Modèle du nom d'un chara de baie.
    BERRY_NAME="Z_B%02d"
    
    module_function
    #Ici seront défini toutes les méthodes
    
  end
end

Le système de baies a besoins d’une variable de stockage automatiquement sauvegardée, j’ai dit plus haut que j’utiliserais une variable dans Pokemon_Party, ce que je vais faire de suite en ajoutant quelques lignes dans le script définissant la classe Pokemon_Party.

1) Juste après « attr_accessor :bag_index », on ajoute « attr_accessor :berries ». Ca nous  permettra d’accéder à ma variable depuis l’extérieur de l’objet du type Pokemon_Party.
2) Dans la méthode initialize, juste après « @repel_count = 0 », on ajoute « @berries = {} ». Ca initialisera la variable @berries à la création d’une nouvelle partie et uniquement à la création d’une nouvelle partie donc il faudra mettre une ligne de code quelque part pour initialiser la variable sur les parties chargés qui n’avaient pas le système de baie.

Maintenant que nous avons mis en place les choses dont le système a besoin, nous pouvons commencer à coder les méthodes importantes du système. J’ai dit qu’il y avait deux parties, la mise à jour et la récupération des données. Nous allons commencer par la récupération des données car c’est ces méthodes qui permettent à la mise à jour de fonctionner.

Le système a besoins de récupérer plusieurs informations : L’état de la croissance de la baie, l’id de cette baie, le nom de la baie, la quantité donnée au joueur, les données de l’évent qui contient la baie.

Pourquoi faire des méthodes pour le nom, la quantité et les données ? Pour faire des vérifications afin d’éviter les erreurs. Enfin, vous mettrez en place ces vérifications si besoin, de mon côté, je ne fais pas n’importe quoi avec mes systèmes donc je n’ai pas besoins de vérifier si je fais trop de conneries ^^

1) Récupérer les données enregistrées par l’évènement. C’est la méthode la plus importante, d’abord, nous allons définir comment les données sont enregistrés dans notre  variable $pokemon_party.berries :
$pokemon_party.berries[map_id]= [ [event_id, jour, heure, semaine, baie_id], ...]
map_id contient l’id de la map, event_id est l’id de l’évent qui fait référence aux données suivantes, jour, heure et semaine sont les informations qui font référence à quand la baie a été plantée. baie_id c’est juste l’id de la baie qui est planté ici.

Comme j’ai décidé de ne pas indexer par rapport à l’id de l’évent dans le tableau, je vais devoir scanner toutes les cases pour trouver quel case correspond au data voulu et ainsi le retourner. Pour tout scanner, je vais utiliser la méthode each de la classe Array pour trouver le data voulu et le retourner. Voici la méthode :

    def get_berry_event_data(event_id)
      $pokemon_party.berries[$game_map.map_id].each do |i|
        return i if i[0]==event_id #Si l'id correspond, alors je retourne le data.
      end
      raise "Yuki::Berries.get_berry_event_data(#{event_id})" #Sinon, je lance une erreur indiquant que le data n'a pas été trouvé
    end

Maintenant que la méthode get_berry_event_data a été programmée, je peux programmer les autres méthodes mentionnés qui ont forcément besoin de cette méthode pour fonctionner.

2) La récupération de l’id est toute bêbête, il suffit de retourner la 5ème case du data de l’évent :

    def get_berry_id(event_id)
      return get_berry_event_data(event_id)[4]
    end

3) La récupération du nom par contre est un peu plus complexe, il faut déjà trouver l’id réel de la baie en tant qu’objet dans le jeu et après récupérer le nom en utilisant les variables de PSP, $data_item, le nom se trouve dans la première case. Chez moi, toutes les baies sont dans l’ordre et elles commencent à partir de 205 donc je vais ajouter 204 à l’id de la baie pour récupérer le nom de cette baie :

    def get_berry_name(event_id)
      return $data_item[get_berry_event_data(event_id)[4]+204][0]
    end

4) La récupération de la quantité est assez simpliste car je ne fais aucune variations de quantité, le système codé actuellement ne gère pas les engrais, l’arrosage etc… C’est à vous de faire ça, on verra si vous avez compris le tutoriel si vous arrivez à coder ces petits détails :3
Je vais récupérer la quantité donnée directement en regardant dans le data de quantité.

    def get_berry_quantity(event_id)
      return Data_Berries[get_berry_event_data(event_id)[4]][2]
    end

La récupération des informations de base est faite, il faut désormais  programmer la récupération de l’état de la croissance de la baie et là, c’est un tout petit peu plus compliqué. Plus haut, j’ai dit que je stockais l’heure, le jour et la semaine où la baie a été plantée, je vais donc simplement vérifier le temps qui s’est écoulé entre le moment où la baie a été plantée et le moment où je vérifie son état pour le retourner. D’ailleurs, je dois aussi vérifier un état particulier, l’état indiquant que rien n’a été planté !

La vérification de rien est planté est simple, on vérifie si le data de la baie contient l’id 0 ou pas d’id, dans ce cas, j’ai décidé de retourner  -1 pour dire qu’il n’y a pas de baie planté.
Les vérifications de l’état comme j’ai dit se font par un delta t, je vais utiliser le data qui indique le temps qu’il faut pour passer d’un état de croissance à un autre.

    def get_berry_state(event_id,event_data=nil)
      event_data=get_berry_event_data(event_id) unless event_data
      return -1 if event_data[4]==0 or !event_data[4]
      st=$game_variables[VAR_HEU]-event_data[2]
      st+=($game_variables[VAR_JOU]-event_data[1])*24
      st+=($game_variables[VAR_SEM]-event_data[3])*168
      data_state=Data_Berries[event_data[4]][1]
      return 0 if st < data_state
      return 1 if st <(data_state*2)
      return 2 if st <(data_state*3)
      return 3
    end

Vous pouvez vérifier vous-même que je ne me suis pas trompé dans la détermination du temps écoulé depuis la plantation :d
Sinon, un petit détail, j’ai deux arguments dans cette fonction, c’est parce qu’elle a deux utilisations, l’une pour les évents et l’autre pour la méthode update, update va envoyer le data car elle l’aura en main quand elle demandera l’état, l’évent lui va envoyer son id car il n’a pas accès de manière évident au data de la baie planté.

Toutes les méthodes de récupération des informations ont été faites, maintenant il faut passer à la méthode mise à jour du système. La mise à jour consistera uniquement à rafraichir le graphisme des évènements de plantation de baie présents sur la map.
Pour rafraichir les graphismes j’ai juste besoin de connaitre l’id du chara et le statu de croissance de la baie.
Si pour un évent l’id de baie est nul ou inexistant, je saute l’étape de mise à jour car par défaut, le graphisme n’est pas défini et lorsque je cueille une baie, le graphisme est rendu indéfini par l’évent.

    def update()
      berries=$pokemon_party.berries
      berries=$pokemon_party.berries={} unless berries
      map_id=$game_map.map_id
      berries[map_id]=[] unless berries[map_id]
      berries[map_id].each do |i|
        event=$game_map.events[i[0]]
        next if i[4]==0 or !i[4]
        state=get_berry_state(nil,i)
        event.character_name=sprintf(BERRY_NAME,Data_Berries[i[4]][0])
        case state
        when 0
          event.direction=2
        when 1
          event.direction=4
        when 2
          event.direction=6
        else
          event.direction=8
        end
      end
    end

Ici, j’utilise deux méthodes pour changer le chara de l’évent et sa direction, elles ne sont pas défini par défauts donc il faut aller les définir, pour se faire, rendons nous dans le script Game_Character 1 et remplaçons « attr_reader   :character_name » par « attr_accessor   :character_name » et « attr_reader   :direction » par « attr_accessor   :direction ». On peut aussi définir des méthodes à la main mais c’est plus rapide d’utiliser ce que Ruby nous met à disposition.
Dernière chose, j’ai utilisé mon modèle de nom de character avec la donnée correspondante, pour générer ce nom à partir du modèle, j’ai utilisé la méthode sprintf qui correspond à l’équivalent de printf du C avec la particularité de retourner un string formaté et ne rien afficher dans la console.

Voilà, on a fait le gros du système, sauf que… On n’a pas fini, loin de là :D

Il reste quatre méthodes à définir, celle qui définir la baie poussé par défaut lors de la première entrée sur la MAP, celle qui permet de choisir une baie à planter, une qui plante la baie et une qui permet de récupérer les baies.

1) Enregistrement d’une baie par défaut. Cette méthode va initialiser la variable de stockage des statu de croissance des baies pour la map en cours si cette variable n’existe pas puis, insérer le data  le data de croissance de la baie par défaut dans la variable. Je mets le numéro de semaine -0x1ffff pour m’assurer que la baie sera considéré comme ayant fini de pousser.

    def register_berry(event_id,id)
      $pokemon_party.berries[$game_map.map_id]=Array.new unless $pokemon_party.berries[$game_map.map_id]
      $pokemon_party.berries[$game_map.map_id]<<[event_id,0,0,-0x1ffff,id]
      update()
    end

event_id est l’id de l’évènement qui va agir comme l’arbuste et id est l’id de la baie. (1=Baie Ceriz, c’est par rapport au data du script et non les objets du sac.)

2) La plantation d’une baie est similaire à l’enregistrement au détail que ça enregistre la date actuelle et que ça n’initialise pas la variable qui est considéré comme déjà initialisé. (Donc pas de plant_berry sans avoir déjà fait register_berry !)

    def plant_berry(event_id,id)
      berry=get_berry_event_data(event_id)
      berry[1]=$game_variables[VAR_JOU]
      berry[2]=$game_variables[VAR_HEU]
      berry[3]=$game_variables[VAR_SEM]
      berry[4]=id
      $pokemon_party.drop_item(berry[4]+204)
      update()
    end

3) La méthode permettant de cueillir une baie va simplement ajouter l’objet correspondant à la baie dans le sac et modifier la variable de stockage des informations de la baie de sorte à ce que le chara de l’évent ne soit plus rafraichis.

    def pick_berry(event_id)
      berry=get_berry_event_data(event_id)
      $pokemon_party.add_item(berry[4]+204,get_berry_quantity(event_id))
      berry[4]=0
    end

4) La selection de la baie à planter est un peu plus compliqué, il faudra modifier le script de gestion du sac, globalement, je vais demander de sélectionner un objet dans la poche à baie du sac.

    def select_berry()
      scene = POKEMON_S::Pokemon_Item_Bag.new($pokemon_party.bag_index, 9998 + 100, "Yuki")
      scene.main
      Graphics.transition
      return scene.return_data[0]
    end

Modification de l’interface de sélection d’un objet (version simple)

Dans la méthode select_berry, j’ai appelé l’interface du sac avec comme argument du mode « Yuki », ce mode nous servira à sélectionner uniquement les baies en ajoutant quelques lignes :
Dans la méthode update de Pokemon_Item_Bag, avant la condition if @mode == "hold" suivit de # Fermer le sac et précédé de # Mode sélection objet à donner ajoutez ces lignes :

        if @mode == "Yuki"
          # Fermer le sac
          if @item_list.index == @item_list.size
            $game_system.se_play($data_system.decision_se)
            @done = true
            @return_data = [0, false]
          # Fermer le sac
          elsif item_id>=205 and item_id<=247 #Verification de l'objet selectionné : si c'est une baie.
            $game_system.se_play($data_system.decision_se)
            @done = true
            @return_data = [item_id, true]
          else
            $game_system.se_play($data_system.buzzer_se)
          end
          return
        end

Un peu plus loin, vous avez une autre condition if @mode == "hold" cette fois ci suivit de @done = true et précédé de $game_system.se_play($data_system.cancel_se) modifiez cette condition en if @mode == "hold" or @mode=="Yuki"
Ceci permettra de sélectionner uniquement une baie dans le sac.

Pour la gestion des arbustes on va se référer un modèle type d’évent qui utilise deux page. La première page contient l’enregistrement de la baie, la deuxième l’appel d’un évènement commun permettant d’agir sur l’arbuste. Dans cet évent, j’utilise une variable temporaire afin de rendre les appels plus dynamiques, cette variable doit contenir l’id de l’évent qui fait ces appels.

Page 1

Page 2

Comme vous pouvez le voir, je mets la variable 125 TMP1 à la valeur de l’id de l’évènement (écrit dans le titre de la fenêtre d’édition de l’évent). Après, j’appelle soit l’évenement commun qui utilisera cette variable temporaire, soit alors la méthode d’enregistrement de la baie avec id remplacé par la baie que je veux, ici baie Ceriz.

Maintenant, voici, l’évènement commun qui utilise toute les fonctions définies plus haut :

Je récupère les informations sur la baie de l’évènement en cours grâce à la variable TMP1 (125) pour ensuite faire un traitement dynamique. Enregistrer les informations des baies dans les variables de jeu permet de rendre les messages plus dynamiques et propres.
D’ailleurs, à la fin de l’évènement, je pense à vider les variables temporaires car leur contenu ne doit pas être permanant. (Sinon, ne prenez pas en compte les interrupteurs que je commute, ils servent à mon système d’affichage des messages à la Pokémon ^^)
J’ai pas trop détaillé cette partie la car normalement avec toutes les informations données dans la partie Script et votre savoir-faire en Event Making vous ne devriez pas avoir le moindre problème à comprendre ces évènements.

Il reste une toute petite chose à faire avant de voir si notre système de baie fonctionne, déjà vérifier que le script ressemble bien à ça :

#===
#¤Yuki::Berries
#---
#%Script permettant de simuler les baies
#---
#© 27/07/2013 - Nuri Yuri (? ??)
#===
module Yuki
  #Je déclare le module Berries dans Yuki.
  module Berries
    #Données des baies
    Data_Berries=[[],
    [6,20,2], [5,20,2], [4,20,2], [3,20,2], [2,20,2],
    [1,20,2], [64,20,2], [63,20,2], [62,20,2], [61,20,2],
    [56,20,2], [55,20,2], [34,20,2], [33,12,5], [12,20,2],
    [11,20,2], [24,20,2], [23,20,2], [22,22,3], [21,20,2],
    [20,22,4], [19,20,2], [18,22,3], [17,22,3], [16,22,3],
    [15,20,2], [14,20,2], [13,20,2], [10,20,2], [9,20,2],
    [8,12,5], [7,20,2], [42,20,2], [41,20,2], [40,22,3],
    [54,22,3], [53,22,3], [52,12,5], [51,20,2], [50,22,3],
    [49,20,2], [48,20,2], [47,20,2]]
    #Modèle du nom d'un chara de baie.
    BERRY_NAME="Z_B%02d"
    
    module_function
    #Ici seront défini toutes les méthodes
    def update()
      berries=$pokemon_party.berries
      berries=$pokemon_party.berries={} unless berries
      map_id=$game_map.map_id
      berries[map_id]=[] unless berries[map_id]
      berries[map_id].each do |i|
        event=$game_map.events[i[0]]
        next if i[4]==0 or !i[4]
        state=get_berry_state(nil,i)
        event.character_name=sprintf(BERRY_NAME,Data_Berries[i[4]][0])
        case state
        when 0
          event.direction=2
        when 1
          event.direction=4
        when 2
          event.direction=6
        else
          event.direction=8
        end
      end
    end
    
    def get_berry_state(event_id,event_data=nil)
      event_data=get_berry_event_data(event_id) unless event_data
      return -1 if event_data[4]==0 or !event_data[4]
      st=$game_variables[VAR_HEU]-event_data[2]
      st+=($game_variables[VAR_JOU]-event_data[1])*24
      st+=($game_variables[VAR_SEM]-event_data[3])*168
      data_state=Data_Berries[event_data[4]][1]
      return 0 if st < data_state
      return 1 if st <(data_state*2)
      return 2 if st <(data_state*3)
      return 3
    end
    
    def get_berry_id(event_id)
      return get_berry_event_data(event_id)[4]
    end
    
    def get_berry_name(event_id)
      return $data_item[get_berry_event_data(event_id)[4]+204][0]
    end
    
    def get_berry_quantity(event_id)
      return Data_Berries[get_berry_event_data(event_id)[4]][2]
    end
    
    def get_berry_event_data(event_id)
      $pokemon_party.berries[$game_map.map_id].each do |i|
        return i if i[0]==event_id
      end
      raise "Yuki::Berries.get_berry_event_data(#{event_id})"
    end
    
    def register_berry(event_id,id)
      $pokemon_party.berries[$game_map.map_id]=Array.new unless $pokemon_party.berries[$game_map.map_id]
      $pokemon_party.berries[$game_map.map_id]<<[event_id,0,0,-0x1ffff,id]
      update()
    end
    
    def plant_berry(event_id,id)
      berry=get_berry_event_data(event_id)
      berry[1]=$game_variables[VAR_JOU]
      berry[2]=$game_variables[VAR_HEU]
      berry[3]=$game_variables[VAR_SEM]
      berry[4]=id
      $pokemon_party.drop_item(berry[4]+204)
      update()
    end
    
    def pick_berry(event_id)
      berry=get_berry_event_data(event_id)
      $pokemon_party.add_item(berry[4]+204,get_berry_quantity(event_id))
      berry[4]=0
    end
    
    def select_berry()
      scene = POKEMON_S::Pokemon_Item_Bag.new($pokemon_party.bag_index, 9998 + 100, "Yuki")
      scene.main
      Graphics.transition
      return scene.return_data[0]
    end
  end
end

Puis maintenant ajouter l’appel de mis à jour aux points important du rafraichissement du jeu :

  • Dans la méthode command_new_game de Scene_Title (le dernier) juste avant alias_command_new_game placez $pokemon_party = POKEMON_S::Pokemon_Party.new et mettez l'autre ligne qui contient ce que vous venez de placer en commentaire. (Ceci évitera au système de buguer si des arbustes se trouvent sur la première MAP).
  • Dans le dernier Scene_Map après @message_window.update, ajoutez ces lignes :     @counter=20 unless @counter
        if(@counter>19)
          Yuki::Berries.update
          @counter=0
        else
          @counter+=1
        end

Avec ces petites pistes, vous avez de quoi faire la base d’un système de baie, il restera plus qu’à ajouter votre touche personnelle et corriger le petit glich graphique lorsque vous entrez sur une MAP (j’ai choisi de ne pas mettre de baies à proximité des téléportations mais ça peut se corriger en exécutant la mise à jour du système de baie au bon moment.)

L’ajout de la fertilisation des terres peut se faire sur le même modèle que l’ajout des baies, à la différence que seule une partie de données stockées pour l’évènement seront modifiés. (Ça sera à vous de choisir la manière de gérer ces données.)
Voici les fichiers de characters que j’utilise sur mon projet : ressources-baies.7z

Vous devrez les redimensionner car sur mon projet tous les charas sont en 1x1, je j'utiliser la propriété zoom_x et zoom_y des sprites de mon coté ^^

Vous n’êtes pas autorisés à copier ce tutoriel à votre guise, ce tutoriel résulte d’un réel travail.

Par Nuri Yuri

Par Loris