O TEMA DO FÓRUM ESTÁ EM MANUTENÇÃO. FEEDBACKS AQUI: ACESSAR

Aperfeiçoamento em um script de Seleção de Personagens

Iniciado por Darkrafa, 11/10/2021 às 20:43

11/10/2021 às 20:43 Última edição: 11/10/2021 às 20:45 por Darkrafa
Boa noite.

Faz um tempo que não entro, então ofereço meu olá a todos, quanto tempo rs. Espero que estejam bem.

Não sabia se criava o tópico na aba Suporte para RPG Maker MV, VX/VX Ace e XP, mas acredito que ela se encaixe em qualquer uma das duas abas, de qualquer forma peço desculpas desde já caso haja algum problema.

Sendo objetivo, eis um script de Seleção de Personagens que se aproxima de algo que procuro, (script autoria de Mewgles):
Spoiler
module Mewgles_Character_Select
#-------------------------------------------------------------------------------
# Version 1.2     Credits an Mewgles
#-------------------------------------------------------------------------------
# Upate July 2020:
# - Name auf meinen neuen Steam- und Forumnamen angepasst
# - Nutzungsbedingungen hinzugefügt
# - Supportinformationen hinzugefügt
#-------------------------------------------------------------------------------
# Nutzungsbedingungen:
# Dieses Script darf sowohl für nicht-kommerzielle als auch kommerzielle Zwecke
# verwendet werden unter der voraussetzung, dass entsprechende Credits
# vergeben werden und ich eine Benachrichtigung bei Spielrelease erhalte
# (Mewgles#5913)
#-------------------------------------------------------------------------------
# Support und Bug-reports:
# Sollte es irgendwelche Probleme geben, könnt ihr mich gerne über Discord
# kontaktieren (#Mewgles#5913) oder meinem Server beitreten für regelmäßige Updates
# und Support: https://discord.gg/b4MwdG3
#-------------------------------------------------------------------------------
# Dieses Script ermöglicht es zu Spielbeginn und an jeder beliebigen anderen
# Stelle im Spiel den Hauptcharacter (spielbar) zu wechseln. Hierbei sind
# verschiedene Optionen möglich. Um Fehler zu vermeiden sollte die Anleitung
# sehr genau gelesen werden.
#
# Aktuelle Funktionen:
# - Spieler vor dem Startpunkt auf der ersten Map einen Character auswählen
#   lassen
# - Jederzeit die Characterauswahl aufrufen per ScriptCall
# - Anpassen der Ansicht und der angezeigten Texte im Auswahlmenü
# - Anzeigen eines bestimmten Hintergrundbildes
# - Wahlweise den vorherigen Hauptcharakter aus der Party entfernen
# - Wahlweise dem Spieler die Möglichkeit geben den Charakter umzubenennen
#
# Die Charakterauswahl kann man per Event mit dem folgendem ScriptCall starten:
# SceneManager.call(Scene_CharacterSelect)
#-------------------------------------------------------------------------------
# Beginn des editierbaren Bereichs
#-------------------------------------------------------------------------------
# Mit "USED_CHARACTERS" werden die Charaktere definiert, die sich der Spieler
# aussuchen kann. Um sie einzustellen kann man beliebig viele Charaktere in die
# Klammern schreiben, solange sie mit einem Komma getrennt sind. Die Zahlen sind
# dabei die Indexnummern der Charaktere in der Datenbank (F9)
#-------------------------------------------------------------------------------
  USED_CHARACTERS = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
#-------------------------------------------------------------------------------
# "CHARACTER_VIEW_X" und -"_Y" legen die Koordinaten der Characteransicht fest.
#-------------------------------------------------------------------------------
  CHARACTER_VIEW_X = 200
  CHARACTER_VIEW_Y = 100
#-------------------------------------------------------------------------------
# "SHOW_FACE_GRAPHIC" legt fest ob das Gesicht des Characters angezeigt wird
# (wenn auf "true" gesetzt). Ist der Wert auf "false" gesetzt, so wird der
# Character selbst angezeigt.
#-------------------------------------------------------------------------------
  SHOW_FACE_GRAPHIC = true
#-------------------------------------------------------------------------------
# "DESCRIPTION_Y" legt die vertikale Position der Charakterbeschreibung fest.
# In der Horizontalen wird die komplette Bildschirmbreite genutzt.
#-------------------------------------------------------------------------------
  DESCRIPTION_Y = 300
#-------------------------------------------------------------------------------
# "INPUT_X" und "INPUT_Y" legen die Koordinaten des Eingabefensters fest.
#-------------------------------------------------------------------------------
  INPUT_X = 250
  INPUT_Y = 100
#-------------------------------------------------------------------------------
# "CLASS_NAME" bezeichnet den Namen der Spielerklassen (Beispiele: Klasse, Job,
# Beruf, usw.).
#-------------------------------------------------------------------------------
  CLASS_NAME = "Classe"
#-------------------------------------------------------------------------------
# Im folgenden Bereich werden die Eingabemöglichkeiten benannt.
# "COMMAND_CHOOSE_CHARACTER" bezeichnet das Kommando für das Auswählen des
# Charakters.
# "COMMAND_CANCEL" benennt den Abbruchvorgang.
# "COMMAND_CONFIRM" ist für das Bestätigen zuständig.
#-------------------------------------------------------------------------------
  COMMAND_CHOOSE_CHARACTER = "Escolher"
  COMMAND_CANCEL = "Cancelar"
  COMMAND_CONFIRM = "Sim"
#-------------------------------------------------------------------------------
# Dieser Bereich ist für das Hilfe-Fenster zuständig.
# "HELP_WINDOW_SELECTION_TEXT" Ist die Aufforderung den Charakter auszuwählen.
# "HELP_WINDOW_CONFIRM_TEXT" beinhaltet die Abfrage ob sich der Spieler sicher
# ist, dass er den gewählten Charakter verwenden will.
# "HELP_WINDOW_X" und "HELP_WINDOW_Y" legen die Koordinaten des Fensters fest.
# Der Y-Wert sollte nur verändert werden, wenn die Breite ("HELP_WINDOW_WIDTH")
# geringer ist als die Breite des RGSS-Players.
# "HELP_WINDOW_WIDTH" Legt die Breite des Hilfe-Fensters fest. Je Breiter das
# Fenster, desto mehr Text kann angezeigt werden. "Graphics.width" ist hier der
# Standardwert und bezeichnet die komplette Breite des RGSS-Players. Hier kann
# auch ein Pixelwert eingegeben werden.
#-------------------------------------------------------------------------------
  HELP_WINDOW_SELECTION_TEXT = "Escolha seu personagem"
  HELP_WINDOW_CONFIRM_TEXT = "Você realmente quer escolher este personagem?"
  HELP_WINDOW_X = 0
  HELP_WINDOW_Y = 0
  HELP_WINDOW_WIDTH = Graphics.width
#-------------------------------------------------------------------------------
# "USE_BACKGROUND_IMAGE" bestimmt ob ein Hintergrundbild für die Charakter-
# auswahl verwendet werden soll. Ist der Wert auf "false" gesetzt, so bleibt der
# Hintergrund schwarz (wenn die Characterauswahl die erste Szene ist) bzw.
# zeigt die aktuelle Karte an (wenn die Auswahl mitten im Spiel verwendet wird).
#-------------------------------------------------------------------------------
  USE_BACKGROUND_IMAGE = false
#-------------------------------------------------------------------------------
# "BACKGROUND_IMAGE" legt das Hintergrundbild fest (sofern der vorherige Wert
# "true" ist). Das Bild muss sich im Ordner Pictures befinden.
#-------------------------------------------------------------------------------
  BACKGROUND_IMAGE = "CharacterSelect"
#-------------------------------------------------------------------------------
# Wenn die Charakterauswahl als erstes im Spiel geschehen soll (noch bevor
# irgendetwas anderes passiert), kann "FIRST_SCENE" auf "true" gesetzt werden.
# Andernfalls ist die Charakterauswahl trotzdem per ScriptCall erreichbar.
#-------------------------------------------------------------------------------
  FIRST_SCENE = false
#-------------------------------------------------------------------------------
# Wenn die Charakterauswahl die erste Szene im Spiel ist, kann hier die folgende
# Szene definiert werden.
#-------------------------------------------------------------------------------
  NEXT_SCENE = Scene_Map
#-------------------------------------------------------------------------------
# Für den Fall, dass der vorherige Hauptcharakter die Party verlassen soll kann
# "DELETE_OLD_MAIN_CHARACTER" auf "true" gesetzt werden. Ansonsten bleibt (wenn
# es die Partygröße zuläst) der alte Hauptcharakter als normales Partymitglied
# bestehen.
#-------------------------------------------------------------------------------
  DELETE_OLD_MAIN_CHARACTER = false
#-------------------------------------------------------------------------------
# Mit "USE_RENAME" legt man fest, ob der Spieler die möglichkeit haben soll den
# Charakter nach der Auswahl umzubenennen.
#-------------------------------------------------------------------------------
  USE_RENAME = false
#-------------------------------------------------------------------------------
# "NAME_MAX_CHAR" gibt die maximale Länge des Namens vor.
#-------------------------------------------------------------------------------
  NAME_MAX_CHAR = 8
#-------------------------------------------------------------------------------
# Hier werden die Hilfetexte für die Umbenennung eingestellt.
# "HELP_WINDOW_RENAME_Q_TEXT" steht für die Abfrage ob der Spieler seinen
# Charakter umbenennen möchte.
# "HELP_WINDOW_RENAME_SET_TEXT" ist die Aufforderung zur Eingabe des Namens.
# "HELP_WINDOW_RENAME_CONFIRM_TEXT" ist die Abfrage ob der Spieler den
# eingegebenen Namen wirklich verwenden möchte.
#-------------------------------------------------------------------------------
  HELP_WINDOW_RENAME_Q_TEXT = "Do you want to rename your character?"
  HELP_WINDOW_RENAME_SET_TEXT = "Enter your name"
  HELP_WINDOW_RENAME_CONFIRM_TEXT = "Do you want to use this name?"
#-------------------------------------------------------------------------------
# Ab hier nichts mehr bearbeiten!
#-------------------------------------------------------------------------------
end
class Scene_CharacterSelect < Scene_Base
 
  def start
    super
    @storage = []
    @actornumber = nil
    @on_rename = false
    create_background
    create_all_windows
  end
 
 
  def create_background
    @background_sprite = Sprite.new
    if Mewgles_Character_Select::USE_BACKGROUND_IMAGE
      @background_sprite.bitmap = Cache.picture(Mewgles_Character_Select::BACKGROUND_IMAGE)
    else
      @background_sprite.bitmap = SceneManager.background_bitmap
    end
  end
 
  def create_all_windows
    create_help_window
    create_character_window
    create_description_window
    create_confirm_window
    create_name_window
  end
 
  def create_help_window
    @help_window = Window_Select_Help.new(1)
    @help_window.set_text(Mewgles_Character_Select::HELP_WINDOW_SELECTION_TEXT)
  end
 
  def create_character_window
    wx = Mewgles_Character_Select::CHARACTER_VIEW_X
    wy = Mewgles_Character_Select::CHARACTER_VIEW_Y
    if Mewgles_Character_Select::SHOW_FACE_GRAPHIC
      @character_view_window = Window_Character_View.new(wx, wy, 130, 150)
    else
      @character_view_window = Window_Character_View.new(wx, wy, 130, 130)
    end
  end
 
  def create_description_window
    wy = Mewgles_Character_Select::DESCRIPTION_Y
    @character_description_window = Window_Character_Description.new(0, wy)
  end
 
  def create_input_window
    wx = Mewgles_Character_Select::INPUT_X
    wy = Mewgles_Character_Select::INPUT_Y
    @input_window = Window_Character_Select_Input.new(wx, wy)
    @input_window.set_handler(:choose, method(:choose))
    @input_window.set_handler(:cancel, method(:cancel))
  end
 
  def create_confirm_window
    wx = Mewgles_Character_Select::INPUT_X
    wy = Mewgles_Character_Select::INPUT_Y
    @confirm_window = Window_Character_Select_Confirm.new(wx, wy)
    @confirm_window.set_handler(:confirm, method(:confirm))
    @confirm_window.set_handler(:abort, method(:abort))
    @confirm_window.deactivate
    @confirm_window.openness = 0
  end
 
  def create_name_window
    wx = Mewgles_Character_Select::INPUT_X
    wy = Mewgles_Character_Select::INPUT_Y
    @name_input_window = Window_Character_Select_Name.new(wx, wy)
    @name_input_window.set_handler(:ninput, method(:ninput))
    @name_input_window.set_handler(:nnoput, method(:nnoput))
    @name_input_window.deactivate
    @name_input_window.openness = 0
  end
 
  def choose
    store_members
    remove_members
    set_actor
    @input_window.deactivate
    @input_window.openness = 0
    confirm_selection
  end
 
  def store_members
    $game_party.members.each do |actor|
      @storage.push actor.id
    end
  end
 
  def remove_members
    for i in @storage
      $game_party.remove_actor(i)
    end
  end
 
  def set_actor
    $game_party.add_actor(@actornumber)
  end
 
  def confirm_selection
    @help_window.set_text(Mewgles_Character_Select::HELP_WINDOW_CONFIRM_TEXT)
    @confirm_window.activate
    @confirm_window.openness = 255
  end
 
  def cancel
    Sound.play_cancel
    @input_window.deactivate
    @input_window.openness = 0
  end
 
  def confirm
    if Mewgles_Character_Select::DELETE_OLD_MAIN_CHARACTER
      @storage.delete_at 0
    end
    if @storage.include?(@actornumber)
      @storage.delete(@actornumber)
    end
    if @storage.size > 3
      @storage.delete(1)
    end
    for i in @storage
      $game_party.add_actor(i)
    end
    @confirm_window.deactivate
    @confirm_window.openness = 0
    if Mewgles_Character_Select::USE_RENAME
      @rename_state = 1
      @help_window.set_text(Mewgles_Character_Select::HELP_WINDOW_RENAME_Q_TEXT)
      @name_input_window.activate
      @name_input_window.openness = 255
    else
      if Mewgles_Character_Select::FIRST_SCENE
        SceneManager.goto(Mewgles_Character_Select::NEXT_SCENE)
      else
        return_scene
      end
    end
  end
 
  def ninput
    @name_input_window.deactivate
    @name_input_window.openness = 0
    case @rename_state
    when 1
      hide_all_windows
      init_rename
    when 2
      if Mewgles_Character_Select::FIRST_SCENE
        SceneManager.goto(Mewgles_Character_Select::NEXT_SCENE)
      else
        return_scene
      end
    end
  end
 
  def nnoput
    @name_input_window.deactivate
    @name_input_window.openness = 0
    case @rename_state
    when 1
      if Mewgles_Character_Select::FIRST_SCENE
        SceneManager.goto(Mewgles_Character_Select::NEXT_SCENE)
      else
        return_scene
      end
    when 2
      @rename_state = 1
      hide_all_windows
      init_rename
    end
  end
 
  def init_rename
    @on_rename = true
    @actor = $game_actors[@actornumber]
    @max_char = Mewgles_Character_Select::NAME_MAX_CHAR
    @edit_window = Window_NameEdit.new(@actor, @max_char)
    @edit_window.y = @help_window.height + 2
    @ninput_window = Window_NameInput.new(@edit_window)
    @ninput_window.set_handler(:ok, method(:on_input_ok))
    @help_window.set_text(Mewgles_Character_Select::HELP_WINDOW_RENAME_SET_TEXT)
  end
 
  def on_input_ok
    @actor.name = @edit_window.name
    @on_rename = false
    @edit_window.deactivate
    @edit_window.openness = 0
    @ninput_window.deactivate
    @ninput_window.openness = 0
    @rename_state = 2
    show_all_windows
    check_name_ok
  end
 
  def hide_all_windows
    @character_view_window.openness = 0
    @character_description_window.openness = 0
  end
 
  def show_all_windows
    @character_view_window.openness = 255
    @character_view_window.refresh
    @character_description_window.openness = 255
  end
 
  def check_name_ok
    @help_window.set_text(Mewgles_Character_Select::HELP_WINDOW_RENAME_CONFIRM_TEXT)
    @name_input_window.activate
    @name_input_window.openness = 255
  end
 
  def abort
    Sound.play_cancel
    @confirm_window.deactivate
    @confirm_window.openness = 0
    @help_window.set_text(Mewgles_Character_Select::HELP_WINDOW_SELECTION_TEXT)
  end
  def update
    super
    update_actornumber
    if @on_rename == false
      if Input.trigger?(:LEFT)
        @character_view_window.charindex -= 1
        @character_view_window.refresh
        @character_description_window.charindex -=1
        @character_description_window.refresh
        Sound.play_cursor
      end
      if Input.trigger?(:RIGHT)
        @character_view_window.charindex += 1
        @character_view_window.refresh
        @character_description_window.charindex += 1
        @character_description_window.refresh
        Sound.play_cursor
      end
      if Input.trigger?(:C)
        if @rename_state != 2 && @rename_state != 3
          if @input_window == nil
            create_input_window
          else
            @input_window.activate
            @input_window.openness = 255
          end
          Sound.play_ok
        end
      end
      if Input.trigger?(:B)
        if Mewgles_Character_Select::FIRST_SCENE == false
          Sound.play_cancel
          return_scene
        else
          Sound.play_buzzer
        end
      end     
    end
  end
 
  def update_actornumber
    @actornumber = Mewgles_Character_Select::USED_CHARACTERS[@character_description_window.charindex - 1]
  end
 
end
class Window_Character_Select_Name < Window_Command
 
  def make_command_list
    add_command(Mewgles_Character_Select::COMMAND_CONFIRM, :ninput)
    add_command(Mewgles_Character_Select::COMMAND_CANCEL, :nnoput)
  end
 
end
class Window_Character_Select_Confirm < Window_Command
 
  def make_command_list
    add_command(Mewgles_Character_Select::COMMAND_CONFIRM, :confirm)
    add_command(Mewgles_Character_Select::COMMAND_CANCEL, :abort)
  end
 
end
class Window_Character_Select_Input < Window_Command
 
  def make_command_list
    add_command(Mewgles_Character_Select::COMMAND_CHOOSE_CHARACTER, :choose)
    add_command(Mewgles_Character_Select::COMMAND_CANCEL, :cancel)
  end
 
end
class Window_Character_Description < Window_Base
 
  attr_accessor :charindex
 
  def initialize(x, y)
    super(x, y, window_width, fitting_height(4))
    @charindex = 1
    @actornumber = 1
    refresh
  end
 
  def window_width
    return Graphics.width
  end
 
  def refresh
    check_index
    contents.clear
    actor = $game_actors[get_actor_number]
    draw_actor_info(actor)
  end
 
  def draw_actor_info(actor)
      draw_text_ex(4, 0, actor.actor.description)
      draw_text(4, 45, contents.width - 8, line_height, Mewgles_Character_Select::CLASS_NAME + ": " + actor.class.name)
  end
 
  def get_actor_number
    @actornumber = Mewgles_Character_Select::USED_CHARACTERS[@charindex - 1]
    return @actornumber
  end
 
  def check_index
    if @charindex > Mewgles_Character_Select::USED_CHARACTERS.size
      @charindex = 1
    end
    if @charindex < 1
      @charindex = Mewgles_Character_Select::USED_CHARACTERS.size
    end
  end
 
end
class Window_Character_View < Window_Base
 
  attr_accessor :charindex
 
  def initialize(x, y, width, height)
    super
    @charindex = 1
    @actornumber = 1
    refresh
  end
 
  def refresh
    check_index
    contents.clear
    actor = $game_actors[get_actor_number]
    if Mewgles_Character_Select::SHOW_FACE_GRAPHIC
      draw_actor_face(actor, 5, 0)
    else
      draw_actor_graphic(actor, 52, 60)
    end
    draw_actors_name(actor)
  end
 
  def draw_actor_graphic(actor, x, y)
    draw_character(actor.character_name, actor.character_index, x, y)
  end
 
  def draw_actor_face(actor, x, y, enabled = true)
    draw_face(actor.face_name, actor.face_index, x, y, enabled)
  end
 
  def draw_actors_name(actor)
    name = actor.name
    if Mewgles_Character_Select::SHOW_FACE_GRAPHIC
      draw_text(4, 50, contents.width - 8, contents.height - 4, name, 1)
    else
      draw_text(4, 30, contents.width - 8, contents.height - 4, name, 1)
    end
  end
 
  def get_actor_number
    @actornumber = Mewgles_Character_Select::USED_CHARACTERS[@charindex - 1]
    return @actornumber
  end
 
  def check_index
    if @charindex > Mewgles_Character_Select::USED_CHARACTERS.size
      @charindex = 1
    end
    if @charindex < 1
      @charindex = Mewgles_Character_Select::USED_CHARACTERS.size
    end
  end
 
end
class Window_Select_Help < Window_Base
 
  def initialize(line_number = 3)
    super(Mewgles_Character_Select::HELP_WINDOW_X, Mewgles_Character_Select::HELP_WINDOW_Y, Mewgles_Character_Select::HELP_WINDOW_WIDTH, fitting_height(line_number))
  end
 
  def set_text(text)
    if text != @text
      @text = text
      refresh
    end
  end
 
  def clear
    set_text("")
  end
 
  def refresh
    contents.clear
    contents.draw_text(4, -2, contents.width - 8, contents.height - 4 , @text, 1)
  end
 
end
class Scene_Title < Scene_Base
 
  def command_new_game
    DataManager.setup_new_game
    close_command_window
    fadeout_all
    $game_map.autoplay
    if Mewgles_Character_Select::FIRST_SCENE
      SceneManager.goto(Scene_CharacterSelect)
    else
      SceneManager.goto(Scene_Map)
    end
  end
 
end
[close]

Bem, ele é um script bastante simplificado, e diferentemente dos do MOG que possuem graandes customizações, cheio de cores e etc, este é bem mais assertivo.
O problema é que há alguns entraves que eu gostaria de saber se algum dos magos em programação do fórum podem me ajudar, apenas para aperfeiçoá-lo ao meu "desenho".

-Não notei nenhuma opção de "cancelar a opção de cancelar" nas poucas opções de customização.
Basicamente neste script eu posso apertar o botão B, de cancelar, no meio de sua execução, saindo da tela de seleção e isso tira o propósito de escolha obrigatória do personagem.
É possível deixá-lo obrigatório a escolha, sem poder cancelá-lo??
-Haveria alguma forma de, assim que escolher um dos personagens a disposição, na próxima cena impedi-lo de reaparecer entre as opções???
Por exemplo, se eu utilizo o comando de script call e chamo a cena, eu escolho um personagem, ok. A cena acaba e eu fico somente com um personagem, a ideia é ficar com 3. Então chamando a cena 3 vezes ela resolve essa questão, mas em ambas aparecem os personagens que foram selecionados anteriormente.
Imagino que com algum comando de variável isso seria possível por evento, deixando cada personagem com 1 variável e removendo-a quando a variável X fosse selecionada, mas e quanto aqui no script - haveria algum facilitador?

Seriam somente esses dois pontos mesmo.
Será que tudo bem aperfeiçoar o script para esse cenário??? O primeiro item imagino que seja fácil de aplicar, o segundo é que pode dar alguma dor de cabeça.
O que vocês acham??

Fico agradecido a quem puder ajudar.
Ótima noite.