Mundo Maker
¡Bienvenid@ a Mundo Maker!

¿Quieres aprender todo sobre el RPG Maker?



Regístrate y forma parte de Mundo Maker.

[XP] Skill Groups

Ver el tema anterior Ver el tema siguiente Ir abajo

RPG Maker XP [XP] Skill Groups

Mensaje por Wecoc el 2017-04-09, 18:48

Éste script permite agrupar skills parecidas de modo que sea más fácil encontrarlas en la ventana de selección de Skills.

Por ejemplo si usas skills del tipo Fuego, Fuego +, Fuego ++ ... o cosas así, puedes hacer una skill principal llamada Fuego, y poner esas tres dentro de ésta con el script.
Entonces en la ventana de skills saldrá solo la principal, y al clicarla saldrá una nueva ventana de selección para el tipo concreto. Otro ejemplo es hacer skills con múltiples opciones, como una skill "Invocar" y dentro las opciones Esqueleto, Zombie, Golem... (cada una será una skill secundaria).

Poned el script encima de main:
Hay que vigilar con las incompatibilidades porque modifica varios aspectos de la ventana de skills, la escena Scene_Skill y la selección de skills en Scene_Battle, y solo pude usar un alias.

Código:
#==============================================================================
# ** [XP] Skill Groups v1.0
#------------------------------------------------------------------------------
#  Autor: Wecoc (no requiere créditos)
#==============================================================================

#==============================================================================
# ** Skill_Groups
#==============================================================================

module Skill_Groups
  
  # ID skill principal => [[IDs secundarias], iconos, SP cost, align]
  DATA = {81 => [[82, 83, 84], true, true, 0]}
  
  # Opción: Mostrar skills pese a que el actor no pueda usarlas (desactivadas)
  SHOW_DISABLED_SKILLS = false
  
  # Opción: Si afecta a todos no se abre la ventana Window_Target
  TARGET_ALL_AUTO = true
  
  # Opción: Quitar ventana cuando se selecciona el target
  DISPOSE_WHEN_TARGET = true
  
end

class Game_Actor < Game_Battler
  alias subgroup_can_use? skill_can_use? unless $@
  def skill_can_use?(skill_id)
    result = subgroup_can_use?(skill_id)
    if result == true
      if Skill_Groups::DATA.keys.include?(skill_id)
        for i in 0...Skill_Groups::DATA[skill_id][0].size
          subskill = Skill_Groups::DATA[skill_id][0][i]
          return true if subgroup_can_use?(subskill)
        end
        return false
      end
    end
    return result
  end
end

#==============================================================================
# ** Window_Skill
#==============================================================================

class Window_Skill < Window_Selectable
  attr_reader :data
  #--------------------------------------------------------------------------
  # * Refresh
  #--------------------------------------------------------------------------
  def refresh
    if self.contents != nil
      self.contents.dispose
      self.contents = nil
    end
    @data = []
    @skill = nil
    for i in 0...@actor.skills.size
      skill = $data_skills[@actor.skills[i]]
      sub_skill = false
      if skill != nil
        for d in Skill_Groups::DATA.values
          if d[0].include?(skill.id)
            sub_skill = true
            break d
          end
        end
        if sub_skill == false
          @data.push(skill)
        end
      end
    end
    @item_max = @data.size
    if @item_max > 0
      self.contents = Bitmap.new(width - 32, row_max * 32)
      for i in 0...@item_max
        draw_item(i)
      end
    end
  end
  #--------------------------------------------------------------------------
  # * Get current Skill
  #--------------------------------------------------------------------------
  def skill
    return @skill
  end
  #--------------------------------------------------------------------------
  # * Set current Skill
  #--------------------------------------------------------------------------
  def skill=(skill)
    @skill = skill
  end
  #--------------------------------------------------------------------------
  # * Draw Item
  #     index : item number
  #--------------------------------------------------------------------------
  def draw_item(index)
    skill = @data[index]
    if @actor.skill_can_use?(skill.id)
      self.contents.font.color = normal_color
    else
      self.contents.font.color = disabled_color
    end
    x = 4 + index % 2 * (288 + 32)
    y = index / 2 * 32
    rect = Rect.new(x, y, self.width / @column_max - 32, 32)
    self.contents.fill_rect(rect, Color.new(0, 0, 0, 0))
    bitmap = RPG::Cache.icon(skill.icon_name)
    opacity = self.contents.font.color == normal_color ? 255 : 128
    self.contents.blt(x, y + 4, bitmap, Rect.new(0, 0, 24, 24), opacity)
    self.contents.draw_text(x + 28, y, 204, 32, skill.name, 0)
    if skill.sp_cost > 0
      self.contents.draw_text(x + 232, y, 48, 32, skill.sp_cost.to_s, 2)
    end
  end
end

#==============================================================================
# ** Window_SubSkill
#==============================================================================

class Window_SubSkill < Window_Selectable
  attr_reader :data
  #--------------------------------------------------------------------------
  # * Initialize
  #--------------------------------------------------------------------------
  def initialize(actor, skill_id)
    width  = 280
    height = (Skill_Groups::DATA[skill_id][0].size + 1) * 32
    x = (640 / 2) - (width / 2)
    y = (480 / 2) - (height / 2)
    @actor = actor
    @skill_id = skill_id
    super(x, y, width, height)
    self.back_opacity = 160
    self.z = 1000
    refresh
    self.index = 0
  end
  #--------------------------------------------------------------------------
  # * Get current Skill
  #--------------------------------------------------------------------------
  def skill
    return @data[self.index]
  end
  #--------------------------------------------------------------------------
  # * Refresh
  #--------------------------------------------------------------------------
  def refresh
    if self.contents != nil
      self.contents.dispose
      self.contents = nil
    end
    @data = []
    skills = Skill_Groups::DATA[@skill_id][0]
    for i in 0...skills.size
      skill = $data_skills[skills[i]]
      if Skill_Groups::SHOW_DISABLED_SKILLS == false
        next if !@actor.skills.include?(skill.id)
      end
      if skill != nil
        @data.push(skill)
      end
    end
    @item_max = @data.size
    if Skill_Groups::SHOW_DISABLED_SKILLS == false
      self.height = (@item_max + 1) * 32
      self.y = (480 / 2) - (height / 2)
    end
    if @item_max > 0
      self.contents = Bitmap.new(width - 32, row_max * 32)
      for i in 0...@item_max
        draw_item(i)
      end
    end
  end
  #--------------------------------------------------------------------------
  # * Draw Item
  #--------------------------------------------------------------------------
  def draw_item(index)
    skill = @data[index]
    if @actor.skill_can_use?(skill.id)
      self.contents.font.color = normal_color
    else
      self.contents.font.color = disabled_color
    end
    x = 4
    y = index * 32
    rect = Rect.new(x, y, self.width / @column_max - 32, 32)
    self.contents.fill_rect(rect, Color.new(0, 0, 0, 0))
    bitmap = RPG::Cache.icon(skill.icon_name)
    opacity = self.contents.font.color == normal_color ? 255 : 128
    align = Skill_Groups::DATA[@skill_id][3]
    if Skill_Groups::DATA[@skill_id][1]
      self.contents.blt(x, y + 4, bitmap, Rect.new(0, 0, 24, 24), opacity)
      self.contents.draw_text(x + 28, y, 204, 32, skill.name, align)
    else
      self.contents.draw_text(x, y, self.width - 48, 32, skill.name, align)
    end
    if Skill_Groups::DATA[@skill_id][2]
      if skill.sp_cost > 0
        sx = x + self.width - 96 + 4
        self.contents.draw_text(sx, y, 48, 32, skill.sp_cost.to_s, 2)
      end
    end
  end
end

#==============================================================================
# ** Scene_Skill
#==============================================================================

class Scene_Skill
  #--------------------------------------------------------------------------
  # * Frame Update
  #--------------------------------------------------------------------------
  def update
    @help_window.update
    @status_window.update
    @skill_window.update
    @target_window.update
    unless @subskill_window.nil?
      @subskill_window.update
      if @subskill_window.active
        update_subskill
        return
      end
    end
    if @skill_window.active
      update_skill
      return
    end
    if @target_window.active
      update_target
      return
    end
  end
  #--------------------------------------------------------------------------
  # * Frame Update (if skill window is active)
  #--------------------------------------------------------------------------
  def update_skill
    @skill_window.skill = @skill_window.data[@skill_window.index]
    if Input.trigger?(Input::B)
      $game_system.se_play($data_system.cancel_se)
      $scene = Scene_Menu.new(1)
      return
    end
    if Input.trigger?(Input::C)
      @skill = @skill_window.skill
      if @skill == nil or not @actor.skill_can_use?(@skill.id)
        $game_system.se_play($data_system.buzzer_se)
        return
      end
      if Skill_Groups::DATA.keys.include?(@skill.id)
        $game_system.se_play($data_system.decision_se)
        @subskill_window = Window_SubSkill.new(@actor, @skill.id)
        @skill_window.active = false
        return
      end
      if @skill.scope >= 3
        if @skill.scope == 4 || @skill.scope == 6
          if Skill_Groups::TARGET_ALL_AUTO == true
            used = false
            for i in $game_party.actors
              used |= i.skill_effect(@actor, @skill)
            end
            if used
              $game_system.se_play(@skill.menu_se)
              @actor.sp -= @skill.sp_cost
              @status_window.refresh
              @skill_window.refresh
              @target_window.refresh
              if $game_party.all_dead?
                $scene = Scene_Gameover.new
                return
              end
              if @skill.common_event_id > 0
                $game_temp.common_event_id = @skill.common_event_id
                $scene = Scene_Map.new
                return
              end
            end
            unless used
              $game_system.se_play($data_system.buzzer_se)
            end
            return
          end
        end
        $game_system.se_play($data_system.decision_se)
        @skill_window.active = false
        @target_window.x = (@skill_window.index + 1) % 2 * 304
        @target_window.z = 2000
        @target_window.visible = true
        @target_window.active = true
        if @skill.scope == 4 || @skill.scope == 6
          @target_window.index = -1
        elsif @skill.scope == 7
          @target_window.index = @actor_index - 10
        else
          @target_window.index = 0
        end
      else
        if @skill.common_event_id > 0
          $game_temp.common_event_id = @skill.common_event_id
          $game_system.se_play(@skill.menu_se)
          @actor.sp -= @skill.sp_cost
          @status_window.refresh
          @skill_window.refresh
          @target_window.refresh
          $scene = Scene_Map.new
          return
        end
      end
      return
    end
    if Input.trigger?(Input::R)
      if $game_party.actors.size == 1
        $game_system.se_play($data_system.buzzer_se)
        return
      end
      actor_index = @actor_index
      loop do
        @actor_index += 1
        @actor_index %= $game_party.actors.size
        break unless $game_party.actors[@actor_index].restriction >= 1
        break if @actor_index == actor_index
      end
      if @actor_index == actor_index
        $game_system.se_play($data_system.buzzer_se)
        return
      end
      $game_system.se_play($data_system.cursor_se)
      $scene = Scene_Skill.new(@actor_index)
      return
    end
    if Input.trigger?(Input::L)
      if $game_party.actors.size == 1
        $game_system.se_play($data_system.buzzer_se)
        return
      end
      actor_index = @actor_index
      loop do
        @actor_index -= 1
        @actor_index %= $game_party.actors.size
        break unless $game_party.actors[@actor_index].restriction >= 1
        break if @actor_index == actor_index
      end
      if @actor_index == actor_index
        $game_system.se_play($data_system.buzzer_se)
        return
      end
      $game_system.se_play($data_system.cursor_se)
      $scene = Scene_Skill.new(@actor_index)
      return
    end
  end
  #--------------------------------------------------------------------------
  # * Frame Update (if subskill window is active)
  #--------------------------------------------------------------------------
  def update_subskill
    @skill_window.skill = @subskill_window.skill
    @skill_window.update_help
    if Input.trigger?(Input::B)
      $game_system.se_play($data_system.cancel_se)
      @subskill_window.dispose
      @subskill_window = nil
      @skill_window.active = true
      return
    end
    if Input.trigger?(Input::C)
      @skill = @subskill_window.skill
      if @skill == nil or not @actor.skill_can_use?(@skill.id)
        $game_system.se_play($data_system.buzzer_se)
        return
      end
      if @skill.scope >= 3
        if @skill.scope == 4 || @skill.scope == 6
          if Skill_Groups::TARGET_ALL_AUTO == true
            used = false
            for i in $game_party.actors
              used |= i.skill_effect(@actor, @skill)
            end
            if used
              $game_system.se_play(@skill.menu_se)
              @actor.sp -= @skill.sp_cost
              @status_window.refresh
              @skill_window.refresh
              @target_window.refresh
              if $game_party.all_dead?
                @subskill_window.dispose
                @subskill_window = nil
                $scene = Scene_Gameover.new
                return
              end
              if @skill.common_event_id > 0
                @subskill_window.dispose
                @subskill_window = nil
                $game_temp.common_event_id = @skill.common_event_id
                $scene = Scene_Map.new
                return
              end
            end
            unless used
              $game_system.se_play($data_system.buzzer_se)
            end
            return
          end
        end
        $game_system.se_play($data_system.decision_se)
        @subskill_window.active = false
        @target_window.x = (@skill_window.index + 1) % 2 * 304
        @target_window.z = 2000
        @target_window.visible = true
        @target_window.active = true
        if Skill_Groups::DISPOSE_WHEN_TARGET
          @subskill_window.visible = false
        end
        if @skill.scope == 4 || @skill.scope == 6
          @target_window.index = -1
        elsif @skill.scope == 7
          @target_window.index = @actor_index - 10
        else
          @target_window.index = 0
        end
      else
        if @skill.common_event_id > 0
          $game_temp.common_event_id = @skill.common_event_id
          $game_system.se_play(@skill.menu_se)
          @actor.sp -= @skill.sp_cost
          @status_window.refresh
          @skill_window.refresh
          @target_window.refresh
          @subskill_window.dispose
          @subskill_window = nil
          $scene = Scene_Map.new
          return
        end
      end
      return
    end
  end
  #--------------------------------------------------------------------------
  # * Frame Update (when target window is active)
  #--------------------------------------------------------------------------
  def update_target
    if Input.trigger?(Input::B)
      $game_system.se_play($data_system.cancel_se)
      unless @subskill_window.nil?
        @subskill_window.dispose
        @subskill_window = nil
      end
      @skill_window.active = true
      @target_window.visible = false
      @target_window.active = false
      return
    end
    if Input.trigger?(Input::C)
      unless @actor.skill_can_use?(@skill.id)
        $game_system.se_play($data_system.buzzer_se)
        return
      end
      if @target_window.index == -1
        used = false
        for i in $game_party.actors
          used |= i.skill_effect(@actor, @skill)
        end
      end
      if @target_window.index <= -2
        target = $game_party.actors[@target_window.index + 10]
        used = target.skill_effect(@actor, @skill)
      end
      if @target_window.index >= 0
        target = $game_party.actors[@target_window.index]
        used = target.skill_effect(@actor, @skill)
      end
      if used
        $game_system.se_play(@skill.menu_se)
        @actor.sp -= @skill.sp_cost
        @status_window.refresh
        @skill_window.refresh
        @target_window.refresh
        if $game_party.all_dead?
          $scene = Scene_Gameover.new
          return
        end
        if @skill.common_event_id > 0
          $game_temp.common_event_id = @skill.common_event_id
          $scene = Scene_Map.new
          return
        end
      end
      unless used
        $game_system.se_play($data_system.buzzer_se)
      end
      return
    end
  end
end

#==============================================================================
# ** Scene_Battle
#==============================================================================

class Scene_Battle
  #--------------------------------------------------------------------------
  # * Frame Update (actor command phase : skill selection)
  #--------------------------------------------------------------------------
  def update_phase3_skill_select
    @skill_window.visible = true
    @skill_window.update
    @skill_window.skill = @skill_window.data[@skill_window.index]
    unless @subskill_window.nil?
      @subskill_window.update
      update_phase3_subskill_select
      return
    end
    if Input.trigger?(Input::B)
      $game_system.se_play($data_system.cancel_se)
      end_skill_select
      return
    end
    if Input.trigger?(Input::C)
      @skill = @skill_window.skill
      if @skill == nil or not @active_battler.skill_can_use?(@skill.id)
        $game_system.se_play($data_system.buzzer_se)
        return
      end
      $game_system.se_play($data_system.decision_se)
      if Skill_Groups::DATA.keys.include?(@skill.id)
        @subskill_window = Window_SubSkill.new(@active_battler, @skill.id)
        @skill_window.active = false
        return
      end
      @active_battler.current_action.skill_id = @skill.id
      @skill_window.visible = false
      if @skill.scope == 1
        start_enemy_select
      elsif @skill.scope == 3 or @skill.scope == 5
        start_actor_select
      else
        end_skill_select
        phase3_next_actor
      end
      return
    end
  end
  #--------------------------------------------------------------------------
  # * Frame Update (actor command phase : skill selection)
  #--------------------------------------------------------------------------
  def update_phase3_subskill_select
    @skill_window.skill = @subskill_window.skill
    @skill_window.update_help
    if Input.trigger?(Input::B)
      $game_system.se_play($data_system.cancel_se)
      @subskill_window.dispose
      @subskill_window = nil
      @skill_window.active = true
      return
    end
    if Input.trigger?(Input::C)
      @skill = @subskill_window.skill
      if @skill == nil or not @active_battler.skill_can_use?(@skill.id)
        $game_system.se_play($data_system.buzzer_se)
        return
      end
      $game_system.se_play($data_system.decision_se)
      @active_battler.current_action.skill_id = @skill.id
      @subskill_window.dispose
      @subskill_window = nil
      @skill_window.visible = false
      if @skill.scope == 1
        start_enemy_select
      elsif @skill.scope == 3 or @skill.scope == 5
        start_actor_select
      else
        end_skill_select
        phase3_next_actor
      end
      return
    end
  end
end

Instrucciones

Justo al principio del script se definen las skills secundarias de cada Skill en el hash DATA, con el formato:
ID skill principal => [[IDs secundarias], iconos, SP cost, align]

Por ejemplo:

81 => [[82, 83, 84], true, true, 0]

Y definís en la base de datos la skill principal y las secundarias en las ID definidas, con los nombres que queráis.
Nota: El gasto de PM de la principal ya no se gasta pero sigue usándose para mirar si se puede hacer la elección o no. Normalmente será 0.



Y aquí el resultado:



Al principio del script podéis definir otras propiedades del sistema más concretas como qué pasa cuando seleccionas un target desde menú con una skill dentro de un grupo.
Y sabiendo algo de script podréis cambiar vosotros mismos otros aspectos estéticos, no es un script complicado.

Configuración

Como dije antes la configuración de cada uno de los grupos tiene éste formato:

ID skill principal => [[IDs secundarias], iconos, SP cost, align]
iconos -> Indica si se visualizan los iconos de las skills dentro de la nueva ventana o no, normalmente vale true.
SP cost -> Indica si se visualiza el coste de SP de las skills dentro de la nueva ventana, normalmente vale true. Si todas las del grupo valen lo mismo recomiendo poner false y a la principal ponerle el mismo valor.
align -> Alineación del texto. 0 - Izquierda, 1 - Centrado, 2 - Derecha; normalmente vale 0.

Jugando un poco con eso podéis lograr un aspecto más tipo elección:


Ojalá os guste tanto como yo me gusto a mí mismo ;D
Saludos.
avatar
Wecoc
Administrador
Administrador



Créditos 12286

Gracias : 646

Volver arriba Ir abajo

RPG Maker XP Re: [XP] Skill Groups

Mensaje por BlazeCrimson el 2017-04-09, 18:57

Muy buen aporte, no crea que pueda usarlo, pero es muy interesante la verdad.

¡Un saludo! gcool

_________________
Image and video hosting by TinyPic
avatar
BlazeCrimson
Analista
Analista

0/3

Créditos 1128

Gracias : 111

Volver arriba Ir abajo

RPG Maker XP Re: [XP] Skill Groups

Mensaje por Producciones The Golden el 2017-04-09, 19:27

Que bestial, sin duda el mejor agregado para batallas que he visto (junto con el de barras de hp y sp para los enemigos), si empiezo un proyecto de rpg maker utilizando la batalla por defecto sin duda haré uso de este script.

Por cierto, te envié un MP sobre un problema con la batalla del rpg maker xp, ¿puedes echarle un vistazo? gracias de antemano.
avatar
Producciones The Golden
Veterano
Veterano

0/3

Créditos 653

Gracias : 71

Volver arriba Ir abajo

RPG Maker XP Re: [XP] Skill Groups

Mensaje por Contenido patrocinado


Contenido patrocinado


Volver arriba Ir abajo

Ver el tema anterior Ver el tema siguiente Volver arriba


Permisos de este foro:
No puedes responder a temas en este foro.