[PSDK] Modifier le menu de combat (attaque / sac / pokémon / fuite)

3 Réponses • 129 Vues

Bonjour à tous, et bienvenue dans ce tutoriel pour modifier le menu de combat sous PSDK

Ce tutoriel vous permettra donc de modifier certains scripts afin de modifier le célèbre menu de combat de PSDK. Certaines personnes ne l'aiment pas beaucoup ou veulent juste le changer car ils en ont trouvé un meilleur...

En effet, dans le dossier graphics > interface, vous pouvez trouver le fichier "choice_4" qui représente la localisation des différents boutons.

Voilà le fichier d'attaque basique de PSDK

Pour le reste du tutoriel, on prendra mon fichier choice_4 que j'ai modelé moi-même (donc privé) à partir des boutons des jeux officiels Noir / Blanc / Noir 2 / Blanc 2. Le bouton du milieu étant celui d'attaque, celui en bas à gauche du sac, celui en bas au milieu de la fuite et enfin, celui en bas à droite des pokémon.

Voici donc mon propre fichier d'attaque

I) Copier les scripts
Allez dans votre projet, au niveau des scripts, et collez ce script en l'appelant Scene_Battle::Action_Selector
Spoiler
# Scene that define a Pokemon Battle
class Scene_Battle
  # Action Selector interface
  #
  # This interface is used during battle and allows the user to choose an action on a specific Pokemon
  class Action_Selector < UI::SpriteStack
    # Constant that define the Action Selector background
    Bar="Choice_4"
    # Constant that define the Selector image
    Selector="Choice_Select"
    # Creates a new Action Selector interface
    def initialize
      super(nil)
      push(0, 0, "choice_4").z = 10005
      @select_sprite = push(0, 0, "choice_select")
      @select_sprite.z = z = 10006
      push(281, 115, nil, type: UI::PokemonIconSprite).z = z
      add_text(256, 28, 64, 135, _get(32,0), 1, 1, color: 9).z = z
      add_text(0, 49, 62, 18, _get(32,2), 1, 1, color: 9).z = z
      add_text(0, 117, 62, 18, _get(32,1), 1, 1, color: 9).z = z
      add_text(109, 158, 102, 34,_get(32,3), 1, 1, color: 9).z = z
      self.visible = false
      self.pos_selector(0)
    end
    # Sets the position of the selector
    # @param action_index [Integer] the index of the action (0 to 3)
    def pos_selector(action_index)
      sprite = @select_sprite
      sprite.angle = 0
      sprite.ox = sprite.oy = 0
      sprite.mirror = false
      case action_index
      when 0 #> Attaquer
        sprite.x = 233
        sprite.y = 81
        sprite.mirror = true
      when 1 #> Pokémon
        sprite.x = 54
        sprite.y = 42
      when 2 #> Sac
        sprite.x = 54
        sprite.y = 111
      else
        sprite.x = 159
        sprite.y = 148
        sprite.ox = sprite.oy = 16
        sprite.angle = 90
      end
    end
    # Sets the Pokemon used to show the Action Selector
    alias pokemon= data=
    # Ranges that describe the Attack button surface
    ATK = [257..319, 29..161]
    # Ranges that describe the Pokemon button surface
    POK = [0..61, 32..93]
    # Ranges that describe the Bag button surface
    BAG = [0..61, 100..161]
    # Ranges that describe the Flee button surface
    RUN = [98..221, 158..191]
    # Action to do when mouse clicks on the interface
    # @param index [Integer] the index of the current action
    # @return [Array(Symbol, Integer)] forced_action, new_index
    # @note forced_action return can be nil
    def mouse_action(index)
      mx, my = @stack[0].translate_mouse_coords
      return :A, 0 if ATK[0].include?(mx) and ATK[1].include?(my)
      return :A, 1 if POK[0].include?(mx) and POK[1].include?(my)
      return :A, 2 if BAG[0].include?(mx) and BAG[1].include?(my)
      return :A, 3 if RUN[0].include?(mx) and RUN[1].include?(my)
      return nil, index
    end
  end
end

Toujours dans votre projet, collez un autre script en l'appelant Scene_Battle Phase 2
Spoiler
#noyard
# Description: Définition de la phase de choix de l'action à réaliser
class Scene_Battle
  #===
  #>start_phase2 : Initialisation du choix pour le pokémon index
  #===
  def start_phase2(index=0)
    # Remise à 0 de l'avancement de la phase 4 (on passe forcément ici)
    @phase4_step = 0
    @phase = 2
    return if judge
    @action_selector.pos_selector(@action_index=0)
    #Vidage des actions si on retourne au premier actor :d
    @actor_actions.clear if index == 0
    #Si le Pokémon est KO on le saute
    if @actors[index].dead?
      @actor_actions.push([-1])
      return update_phase2_next_act
    #Si une attaque est forcée on la force :D
    elsif @actors[index].battle_effect.has_forced_attack?
      @actor_actions.push([0,@actors[index].battle_effect.get_forced_attack(@actors[index]),
      -@actors[index].battle_effect.get_forced_position-1,@actors[index]])
      return update_phase2_next_act
    #> Si le Pokémon doit se reposer
    elsif @actors[index].battle_effect.must_reload
      @actor_actions.push([0, @actors[index].find_last_skill_position, 0,@actors[index]])
      return update_phase2_next_act
    end
    display_message(_parse(18, 71, '[VAR 010C(0000)]' => @actors[index].given_name),false) if @Actions_To_DO.size==0
    @action_selector.pokemon = @actors[index]
    @action_selector.visible = true
    0 while get_action
    launch_phase_event(2,true)
  end
  #===
  #>update_phase2
  #Méthode qui va mettre à jour le choix Attaquer, Sac, PKMN, Fuite
  #===
  def update_phase2
    #> Actions forcés par le tutoriel
    forced_action = get_action
   
    if !forced_action and Mouse.trigger?(:left) #>Souris
      forced_action, @action_index = @action_selector.mouse_action(@action_index)
      @action_selector.pos_selector(@action_index)
    end
   
    if Input.trigger?(:UP) and !forced_action or forced_action==:UP
      @action_index = ((@action_index == 3) ? 2 : 1)
    elsif Input.trigger?(:DOWN) and !forced_action or forced_action==:DOWN
      @action_index = ((@action_index == 1) ? 2 : 3)
    elsif Input.trigger?(:LEFT) and !forced_action or forced_action==:LEFT
      @action_index = 1
    elsif Input.trigger?(:RIGHT) and !forced_action or forced_action==:RIGHT
      @action_index = 0
    elsif Input.trigger?(:A) and !forced_action or forced_action==:A
      return on_phase2_validation
    elsif Input.trigger?(:B) and !forced_action or forced_action==:B
      if @actor_actions.size>0 and @actor_actions[-1][0] != 1 #> Empêchement du retour pour les objets
        $game_system.se_play($data_system.decision_se)
        start_phase2(@actor_actions.size-1)
      end
    end
   
    #Reposition du sprite de selection
    @action_selector.pos_selector(@action_index)
  end
  #===
  #>update_phase2_next_act
  #Méthode permettant de sauter l'actor en cours pour le suivant ou la phase 4
  #===
  def update_phase2_next_act
    if $game_temp.vs_type==2 and @actors[1] and
      !@actors[1].dead? and @actor_actions.size==1
      unless(@actor_actions[0][0] == 1 and @actor_actions[0][1][1][:ball_data])
        start_phase2(1)
        return
      end
    end
    launch_phase_event(4,false)
    @to_start=:start_phase4
  end
  #===
  #>update_phase2_escape
  #Méthode de fuite (menu fuite)
  #===
  def update_phase2_escape(auto_return=false)
    success = rand(256) < phase2_flee_factor
    $game_temp.vs_type.times do |i|
      next unless @actors[i]
      #>Boule fumée / Carapace Mue / Fuite
      if !$game_temp.trainer_battle and
        (BattleEngine::_has_items(@actors[i],228,295) or
        BattleEngine::Abilities.has_ability_usable(@actors[i],9))
        return true if auto_return
        $game_system.se_play($data_system.escape_se)
        display_message(_get(18,75))
        battle_end(1)
        return
      end
      success&&=BattleEngine::_can_switch(@actors[i])
    end
    return success if auto_return
    #Si c'est un succès on lance la fin du combat avec l'argument fuite
    if success
      $game_system.se_play($data_system.escape_se)
      display_message(_get(18,75))
      battle_end(1)
    else
      display_message(_get(18,76))
      launch_phase_event(4,false)
      @to_start=:start_phase4
    end
  end
 
end

Cela  doit donc donner :
Spoiler


Voilà donc pour le moment, copier des scripts, c'est assez facile mais vous allez voir que pour les modifier, il faut faire preuve de logique et de bon sens...

II) Modifier les scripts !

A) Commençons avec le plus difficile, le script Scene_Battle::Action_Selector !

Nous allons donc commencer par la plus longue et difficile partie : modifier la place des textes, la place de la petite flèche rouge et la zone de sélection pour ceux qui jouent avec la souris (évitons d'ouvrir le menu des pokémon si vous avez cliqué sur le sac !)

a) Modifier la place des textes

Dans cette première partie, nous prendrons les lignes 12 à 28 :
    def initialize
      super(nil)
      push(0, 0, "choice_4").z = 10005
      @select_sprite = push(0, 0, "choice_select")
      @select_sprite.z = z = 10006
      push(190, 97, nil, type: UI::PokemonIconSprite).z = z
      #Attaquer
      add_text(120, 32, 64, 135, _get(32,0), 1, 1, color: 9).z = z
      # Pokemon
      add_text(251, 158, 62, 18, _get(32,2), 1, 1, color: 9).z = z
      # Sac
      add_text(9, 158, 62, 18, _get(32,1), 1, 1, color: 9).z = z
      # Fuite
      add_text(110, 162, 102, 34,_get(32,3), 1, 1, color: 9).z = z
      self.visible = false
      self.pos_selector(0)
    end

On peut observer qu'après chaque "#partie à modifier" on a une ligne suivante :
add_text(x1, x2, x3, x4,_get(32,3), 1, 1, color: 9).z = z

Et après, j'peux rien faire pour vous : à vous de trouver les x pour modifier la localisation du texte sur l'image !
/!\ NE TOUCHEZ A RIEN D'AUTRE QU'AUX X !!

b) Modifier la place de la flèche rouge

Pour cette partie, comme indiqué, nous allons modifier la place de la flèche rouge selon l'option que l'on sélectionne.
Nous allons nous concentrer sur la partie qui suit, des lignes 29 à 57 :
    # Sets the position of the selector
    # @param action_index [Integer] the index of the action (0 to 3)
    def pos_selector(action_index)
      sprite = @select_sprite
      sprite.angle = 0
      sprite.ox = sprite.oy = 0
      sprite.mirror = false
      case action_index
      when 0 #> Attaquer
        sprite.x = 89
        sprite.y = 85
        sprite.mirror = true
      when 1 #> Pokémon
        sprite.x = 280
        sprite.y = 136
        sprite.ox = sprite.oy = 16
        sprite.angle = 90
      when 2 #> Sac
        sprite.x = 40
        sprite.y = 136
        sprite.ox = sprite.oy = 16
        sprite.angle = 90
      else
        sprite.x = 161
        sprite.y = 152
        sprite.ox = sprite.oy = 16
        sprite.angle = 90
      end
    end

Pour chaque condition, vous avez :
- "when x #>endroit que vous sélectionnez"
Qui défini ce que vous allez modifier ensuite, si l'endroit est Sac, vous allez modifier l'emplacement de la flèche si vous selectionnez le Sac.
- "sprite.x = 40"
La première coordonnée de la flèche, qui correspond à son emplacement horizontal.
- "sprite.y = 136"
La deuxième coordonnée de la flèche, qui correspond à son emplacement vertical.
- "sprite.ox = sprite.oy = 16"
/!\ Ne pas toucher
- "sprite.angle = 90"
Correspond à la rotation de la flèche : aucune pour que la flèche pointe la gauche, 90 pour qu'elle pointe le bas, 270 pour qu'elle pointe le haut et enfin, remplacez cette info par :
sprite.mirror = true
pour qu'elle pointe la droite.

A propos des coordonnées verticales et horizontales, c'est à vous de les chercher et de les modifier pour qu'elles soient en accord avec là où vous voulez que la flèche soit. Les coordonnées dans le code plus haut correspondent à ma propre image modifiée.

c) Modifier la zone de sélection

Pour cette partie, nous allons nous interresser à un bout de code des lignes 60 à 67 :
    # Ranges that describe the Attack button surface
    ATK = [100..220, 86..115]
    # Ranges that describe the Pokemon button surface
    POK = [241..317, 144..189]
    # Ranges that describe the Bag button surface
    BAG = [3..77, 144..189]
    # Ranges that describe the Flee button surface
    RUN = [123..198, 158..189]

Vous pouvez remarquer que pour chaque bouton, le code est du type :
Bouton = [x1.. x2, y1.. y2]
avec x1 la coordonnée x en haut à gauche du bouton
avec x2 la coordonnée x en bas à droite du bouton
avec y1 la coordonnée y en haut à gauche du bonton
et avec y2 la coordonnée y en bas à droite du bouton

Pour obtenir de telles coordonnées, rien de plus simple : prenez un éditeur d'image convenable et trouvez les !

B) Enfin le plus facile avec le script Scene_Battle Phase 2 !

Avec ce script, nous allons juste modifier l'action à faire pour sélectionner une case à l'autre avec les flèches. En effet, sur les cases par défaut, il suffisait de faire la flèche de gauche pour passer de l'attaque aux pokémon, alors que cela ne va pas être le cas sur mes cases à moi ! Comment faire ? C'est tout simple !
Chaque case comporte un numéro (qu'on ne peut pas changer) :
- 0 pour l'attaque
- 3 pour la fuite
- 2 pour le sac
- 1 pour le choix d'un pokémon

Nous allons donc considérer la partie suivante, qui se trouve des lignes 48 à 67 :
if Input.trigger?(:UP) and !forced_action or forced_action==:UP
      @action_index = 0 if (@action_index==1)
      @action_index = 0 if (@action_index==2)
      @action_index = 0 if (@action_index==3)
    elsif Input.trigger?(:DOWN) and !forced_action or forced_action==:DOWN
      @action_index = 3 if (@action_index==0)
    elsif Input.trigger?(:LEFT) and !forced_action or forced_action==:LEFT
      @action_index = 2 if (@action_index==3)
      @action_index = 3 if (@action_index==1)
    elsif Input.trigger?(:RIGHT) and !forced_action or forced_action==:RIGHT
      @action_index = 1 if (@action_index==3)
      @action_index = 3 if (@action_index==2)
    elsif Input.trigger?(:A) and !forced_action or forced_action==:A
      return on_phase2_validation
    elsif Input.trigger?(:B) and !forced_action or forced_action==:B
      if @actor_actions.size>0 and @actor_actions[-1][0] != 1 #> Empêchement du retour pour les objets
        $game_system.se_play($data_system.decision_se)
        start_phase2(@actor_actions.size-1)
      end
    end

Si vous savez lire l'anglais, vous saurez reconnaitre les mots "UP", "DOWN", ... Ils correspondent à une condition :
if Input.trigger?(:UP) and !forced_action or forced_action==:UP
Signifie "si la touche UP (haut) est pressée ..." et ainsi de suite avec toute les autres touches. Ce qu'il faut modifier est entre ces conditions, elles sont inversées. Il suffit de changer les chiffres ou d'ajouter les effets avec :
@action_index = x2 if (@action_index==x1)
Ici, si appuie une certaine touche et que l'on est à la position x1, on va basculer à la position x2 et la curseur rouge (que l'on a positionné à la partie précédente) va changer de place !
Ainsi, ici :
elsif Input.trigger?(:DOWN) and !forced_action or forced_action==:DOWN
      @action_index = 3 if (@action_index==0)
Si j'appuie sur la flèche du bas ET que je suis au niveau de l'attaque (le chiffre à droite est 0), cela va sélectionner la fuite (le chiffre à gauche est le 3) et on n'aura plus qu'a accepter avec "A" !

Voilà pour ce tutoriel très complet, n'hésitez pas à remercier ce post, à revenir vers moi si vous avez des problèmes ou si vous avez mal compris une notion ! Au revoir !

« Modifié: 25 octobre 2018, 18:47:31 par Max094_Reikeb »

Pokemon Reality project developper (Site officiel de Pokemon Reality)

Outil Tuto Script PSDK Tuto Making

Nuri Yuri

HostMaster

En effet ça a l'air assez complet.
ln(yo) = <3
Merci :) !
Pokemon Reality project developper (Site officiel de Pokemon Reality)

Amras Anárion

Scénariste

Merci pour ce tutoriel. Je fais parti des personnes qui n'aiment (pas du tout) les nouveaux menus de Combat du PSDK, en sachant que de bas, il était concu pour un écran dual screen. (Je préfère ceux du PSP, bien plus classiques et adapté à un mono-screen.)

Le jour où je coderai, je tenterai de faire mon propre menu en suivant ce tuto.

There was an error while thanking
Thanking...