Mundo Maker
¡Bienvenid@ a Mundo Maker!

¿Quieres aprender todo sobre el RPG Maker?



Regístrate y forma parte de Mundo Maker.
Conectarse

Recuperar mi contraseña

Temas importantes
----------------------------------------
Páginas con recursos RPG Maker
----------------------------------------
----------------------------------------
----------------------------------------
----------------------------------------
----------------------------------------
----------------------------------------
----------------------------------------
----------------------------------------
----------------------------------------
Afiliados
Estadísticas
Tenemos 3768 miembros registrados.
El último usuario registrado es lMac.

Nuestros miembros han publicado un total de 85831 mensajes en 12224 argumentos.

[XP] Advanced Scope

Ver el tema anterior Ver el tema siguiente Ir abajo

RPG Maker XP [XP] Advanced Scope

Mensaje por Wecoc el 2017-01-10, 02:15

Éste script es un añadido de batalla que considero bastante útil.

Descripción

Define nuevos tipos de scope para Items y Skills.
Lo que hace es separar el scope en muchas propiedades distintas de modo que luego cada una se puede definir por separado.

Esas propiedades son:

- Si afecta a los aliados
- Si afecta a los enemigos
- Si afecta a todo el grupo o solo a uno
- Si selecciona a uno al azar (nuevo)
- Si se incluye al usuario
- Si solo afecta a vivos
- Si solo afecta a muertos

Además permite definir restricciones totalmente personalizadas.

Está centrado en batalla, al usar scope personalizados de items y skills desde menú funcionarán algunas cosas, pero otras no (eso sí, lo que hay por defecto sigue funcionando igual). En un futuro seguramente haga un script añadido para dar completo soporte a los nuevos parámetros desde menú, pero irá a parte para minimizar los posibles problemas de incompatibilidades.

Sé que no es el primer script con éste concepto (me suena haber visto otro en una comunidad inglesa) pero que yo sepa sí es el primero que usa ésta mecánica de restricciones con &block para los scope, y me pareció el modo más práctico y menos limitante (especialmente para scripters) para definir exactamente a quien puede seleccionar/afectar y a quien no cada item o skill. Con ésto es fácil definir que sean solo seleccionables targets con una clase, o de un tipo de enemigo, o con una PV mayor al 50%, o que tengan cierto estado, o que sepan hacer cierta habilidad... Las posibilidades son altísimas.

Es compatible con Number Flood.
Para la versión compatible con Data File Save ve aquí.
Antes sí era compatible directamente con Data File Save pero hubo cambios en éste así que ahora necesitaréis esa otra versión del script.

Autor: Wecoc (créditos opcionales)
Versión: 1.0

Demo

He hecho una demo con objetos de ejemplo con nuevas combinaciones y restricciones.
Hablad con el buenazo de Alexis para que os dé 10 de cada uno y luego con el fantasma para probarlos en batalla.

IMAGEN:

Descarga: Advanced Scope.zip
Actualizado: 07/05/2017

Código

Ponedlo encima de main.

Código:
#==============================================================================
# ** [XP] Advanced Scope v1.0
#------------------------------------------------------------------------------
# Autor: Wecoc (créditos opcionales)
#------------------------------------------------------------------------------
# Define nuevos tipos de Scope para Items y Skills
#------------------------------------------------------------------------------
# Se usa en $data_items[ID] y $data_skills[ID] exactamente de la misma forma
# Para definir el target usa:
# $data_items[ID].scope_ally   = true | false # Aliado
# $data_items[ID].scope_enemy  = true | false # Enemigo
# $data_items[ID].scope_all    = true | false # Todos los del grupo o uno solo
# $data_items[ID].scope_random = true | false # Uno al azar
# $data_items[ID].scope_user   = true | false # Incluir usuario
# $data_items[ID].scope_alive  = true | false # Solo miembros vivos
# $data_items[ID].scope_dead   = true | false # Solo miembros muertos
#------------------------------------------------------------------------------
# $data_items[ID].restriction(&block) # Definir restricción personalizada
# $data_items[ID].restrictions        # Obtener restricciones personalizadas
# $data_items[ID].clear_restrictions  # Borrar  restricciones personalizadas
#==============================================================================

#==============================================================================
# ** Scope Configuration
#==============================================================================

module Scope
  #----------------------------------------------------------------------------
  # Default Dead Select
  #----------------------------------------------------------------------------
  # Por defecto si un item solo afecta a vivos igualmente se puede seleccionar
  # a un aliado muerto, solo que el item no tendrá efecto.
  # Lo mismo con los items que afectan solo a muertos, se puede seleccionar
  # cualquiera.
  # Si pones false en cambio solo se pueden seleccionar los que cumplen
  # estrictamente la restricción
  #----------------------------------------------------------------------------
  
  DEFAULT_DEAD_SELECT = true
  
end

#==============================================================================
# ** Array
#==============================================================================

class Array
  #--------------------------------------------------------------------------
  # * Select!
  #--------------------------------------------------------------------------
  unless self.respond_to?(:select)
    def select!(&block)
      result = self.select(&block)
      self.replace(result)
    end
  end
end

#==============================================================================
# ** RPG
#==============================================================================

for Klass in [RPG::Item, RPG::Skill]
  class Klass
    #--------------------------------------------------------------------------
    # * Public Instance Variables
    #--------------------------------------------------------------------------
    attr_writer :scope_ally, :scope_enemy, :scope_all, :scope_random
    attr_writer :scope_user, :scope_alive, :scope_dead
    #--------------------------------------------------------------------------
    # * For Allies
    #--------------------------------------------------------------------------
    def scope_ally
      @scope_ally = [3, 4, 5, 6].include?(@scope) if @scope_ally == nil
      return @scope_ally
    end
    #--------------------------------------------------------------------------
    # * For Enemies
    #--------------------------------------------------------------------------
    def scope_enemy
      @scope_enemy = [1, 2].include?(@scope) if @scope_enemy == nil
      return @scope_enemy
    end
    #--------------------------------------------------------------------------
    # * For All Party/Troop Members
    #--------------------------------------------------------------------------
    def scope_all
      @scope_all = [2, 4, 6].include?(@scope) if @scope_all == nil
      return @scope_all
    end
    #--------------------------------------------------------------------------
    # * Random Pick
    #--------------------------------------------------------------------------
    def scope_random
      @scope_random = false if @scope_random == nil
      return @scope_random
    end
    #--------------------------------------------------------------------------
    # * User included
    #--------------------------------------------------------------------------
    def scope_user
      if Scope::DEFAULT_DEAD_SELECT == true
        @scope_user = [3, 4, 5, 6, 7].include?(@scope) if @scope_user == nil
      else
        @scope_user = [3, 4, 7].include?(@scope) if @scope_user == nil
      end
      return @scope_user
    end
    #--------------------------------------------------------------------------
    # * Only Alive
    #--------------------------------------------------------------------------
    def scope_alive
      @scope_alive = [1, 2, 3, 4, 7].include?(@scope) if @scope_alive == nil
      return @scope_alive
    end
    #--------------------------------------------------------------------------
    # * Only Dead
    #--------------------------------------------------------------------------
    def scope_dead
      @scope_dead = [5, 6].include?(@scope) if @scope_dead == nil
      return @scope_dead
    end
    #--------------------------------------------------------------------------
    # * Define Scope
    #--------------------------------------------------------------------------
    def set_scope(ally,enemy,all,random=false,user=true,alive=true,dead=false)
      self.scope_ally   = ally
      self.scope_enemy  = enemy
      self.scope_all    = all
      self.scope_random = random
      self.scope_user   = user
      self.scope_alive  = alive
      self.scope_dead   = dead
    end
    #--------------------------------------------------------------------------
    # * Special Restrictions
    #--------------------------------------------------------------------------
    def scope_rest
      @scope_rest = [] if @scope_rest == nil
      return @scope_rest
    end
    def restriction(&block)  self.scope_rest.push(block)  end
    def restrictions()       self.scope_rest              end
    def clear_restrictions() self.scope_rest.clear        end
    #--------------------------------------------------------------------------
  end
end

#==============================================================================
# ** Arrow_Base
#==============================================================================

class Arrow_Base < Sprite
  attr_reader :user
  attr_reader :item
  attr_reader :target
  attr_reader :targets
  #--------------------------------------------------------------------------
  # * Initialize
  #--------------------------------------------------------------------------
  def initialize(viewport, user, item)
    super(viewport)
    self.bitmap = RPG::Cache.windowskin($game_system.windowskin_name)
    self.ox = 16
    self.oy = 64
    self.z = 2500
    @blink_count = 0
    @index = 0
    @help_window = nil
    @user = user
    @item = item
    @targets = target_battlers
    @target = @targets[0]
    update_sprite
  end
  #--------------------------------------------------------------------------
  # * Obtener índice
  #--------------------------------------------------------------------------
  def index
    return @targets.index(@target) rescue -1
  end
  #--------------------------------------------------------------------------
  # * Definir índice
  #--------------------------------------------------------------------------
  def index=(index)
    @target = @targets[index]
  end
  #--------------------------------------------------------------------------
  # * Obtener targets seleccionables
  #--------------------------------------------------------------------------
  def target_battlers
    if @user.is_a?(Game_Actor)
      allies = $game_party.actors.clone
      enemies = $game_troop.enemies.clone
    else
      allies = $game_troop.enemies.clone
      enemies = $game_party.actors.clone
    end
    allies.delete_if {|target| target.hidden}
    enemies.delete_if{|target| target.hidden}
    if @item == nil
      enemies.delete_if {|target| !target.exist? }
      return enemies
    end
    result = []
    if @item.scope_ally == true
      for target in allies
        result.push(target)
      end
    end
    if @item.scope_enemy == true
      for target in enemies
        result.push(target)
      end
    end
    if @item.scope_user == true
      if !result.include?(@user)
        result.push(@user)
      end
    end
    if @item.scope_user == false
      result.delete(@user)
    end
    if @item.scope_alive == true && Scope::DEFAULT_DEAD_SELECT == false
      result.select!{|target| !target.dead?}
    end
    if @item.scope_dead == true && Scope::DEFAULT_DEAD_SELECT == false
      result.select!{|target| target.dead?}
    end
    for r in @item.restrictions
      if r.arity == 1
        result.select!{|target| r.call(target) == true} rescue nil
      else
        result.select!{|target| r.call == true} rescue nil
      end
    end
    return result
  end
  #--------------------------------------------------------------------------
  # * Update
  #--------------------------------------------------------------------------
  def update
    update_sprite
    if @help_window != nil
      update_help
    end
    if @target == nil
      self.visible = false
      return
    end
    self.visible = true
    # Siguiente target
    if Input.repeat?(Input::RIGHT)
      $game_system.se_play($data_system.cursor_se)
      self.index = (self.index + 1) % @targets.size
    end
    # Anterior target
    if Input.repeat?(Input::LEFT)
      $game_system.se_play($data_system.cursor_se)
      self.index = (self.index - 1) % @targets.size
    end
    # Colocar flecha encima del target
    if @target != nil
      self.x = @target.screen_x
      self.y = @target.screen_y
    end
  end
  #--------------------------------------------------------------------------
  # * Update Sprite
  #--------------------------------------------------------------------------
  def update_sprite
    @blink_count = (@blink_count + 1) % 8
    if @blink_count < 4
      self.src_rect.set(128, 96, 32, 32)
    else
      self.src_rect.set(160, 96, 32, 32)
    end
  end
  #--------------------------------------------------------------------------
  # * Update Help
  #--------------------------------------------------------------------------
  def update_help
    if @target == nil
      @help_window.set_text("")
      return
    end
    if @target.is_a?(Game_Actor)
      @help_window.set_actor(@target)
    else
      @help_window.set_enemy(@target)
    end
  end
end

#==============================================================================
# ** Game_Battler
#==============================================================================

class Game_Battler
  #--------------------------------------------------------------------------
  # * Obtener si puede usar la Skill
  #--------------------------------------------------------------------------
  alias wecoc_scope_skill_use? skill_can_use? unless $@
  def skill_can_use?(skill_id)
    skill = $data_skills[skill_id]
    return false if skill.nil?   # La skill no existe
    return false if !self.exist? # El usuario está oculto o muerto
    if self.is_a?(Game_Actor)
      members = $game_party.actors.clone
    else
      members = $game_troop.enemies.clone
    end
    if members.size == 1 # Está solo en el grupo y se requiere un aliado
      if skill.user == false && skill.ally == false && skill.enemy == false
        return false
      end
    end
    for r in skill.restrictions
      if r.arity == 1
        members.select!{|target| r.call(target) == true} rescue nil
      else
        members.select!{|target| r.call == true} rescue nil
      end
    end
    return false if members.size == 0
    return wecoc_scope_skill_use?(skill_id)
  end
  #--------------------------------------------------------------------------
  # * Obtener si puede usar el Item
  #--------------------------------------------------------------------------
  def item_can_use?(item_id)
    item = $data_items[item_id]
    return false if item.nil?    # El item no existe
    return false if !self.exist? # El usuario está oculto o muerto
    if self.is_a?(Game_Actor)
      # El grupo no tiene ese objeto
      return false if $game_party.item_number(item_id) == 0
      # Restricciones del item (Solo menú / Solo batalla)
      return false if $game_temp.in_battle  && item.occasion == 2
      return false if !$game_temp.in_battle && item.occasion == 1
      members = $game_party.actors.clone
    else
      members = $game_troop.enemies.clone
    end
    if members.size == 1 # Está solo en el grupo y se requiere un aliado
      if item.user == false && item.ally == false && item.enemy == false
        return false
      end
    end
    for r in item.restrictions
      if r.arity == 1
        members.select!{|target| r.call(target) == true} rescue nil
      else
        members.select!{|target| r.call == true} rescue nil
      end
    end
    return false if members.size == 0
    return true
  end
end

#==============================================================================
# ** Game_Party
#==============================================================================

class Game_Party
  #--------------------------------------------------------------------------
  # * Obtener si el grupo puede usar el Item
  #--------------------------------------------------------------------------
  def item_can_use?(item_id)
    for member in $game_party.actors
      if member.item_can_use?(item_id)
        return true
      end
    end
    return false
  end
end

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

class Scene_Battle
  #--------------------------------------------------------------------------
  # * Seleccionar enemigo
  #--------------------------------------------------------------------------
  def start_enemy_select
    item = nil
    if @active_battler.current_action.kind == 1
      item = @skill if @skill != nil
    end
    if @active_battler.current_action.kind == 2
      item = @item  if @item != nil
    end
    @enemy_arrow = Arrow_Base.new(@spriteset.viewport2, @active_battler, item)
    @enemy_arrow.help_window = @help_window
    @actor_command_window.active = false
    @actor_command_window.visible = false
  end
  #--------------------------------------------------------------------------
  # * Seleccionar actor
  #--------------------------------------------------------------------------
  def start_actor_select
    item = nil
    if @active_battler.current_action.kind == 1
      item = @skill if @skill != nil
    end
    if @active_battler.current_action.kind == 2
      item = @item  if @item != nil
    end
    @actor_arrow = Arrow_Base.new(@spriteset.viewport2, @active_battler, item)
    @actor_arrow.index = @actor_index
    @actor_arrow.help_window = @help_window
    @actor_command_window.active = false
    @actor_command_window.visible = false
  end
  #--------------------------------------------------------------------------
  # * Aplicar skill
  #--------------------------------------------------------------------------
  def make_skill_action_result
    @skill = $data_skills[@active_battler.current_action.skill_id]
    unless @active_battler.current_action.forcing
      unless @active_battler.skill_can_use?(@skill.id)
        $game_temp.forcing_battler = nil
        @phase4_step = 1
        return
      end
    end
    @active_battler.sp -= @skill.sp_cost
    @status_window.refresh
    @help_window.set_text(@skill.name, 1)
    @animation1_id = @skill.animation1_id
    @animation2_id = @skill.animation2_id
    @common_event_id = @skill.common_event_id
    @target_battlers.clear
    @target_battlers = set_target_battlers(@skill)
    for target in @target_battlers
      target.skill_effect(@active_battler, @skill)
    end
  end
  #--------------------------------------------------------------------------
  # * Aplicar item
  #--------------------------------------------------------------------------
  def make_item_action_result
    @item = $data_items[@active_battler.current_action.item_id]
    unless @active_battler.item_can_use?(@item.id)
      @phase4_step = 1
      return
    end
    if @item.consumable
      $game_party.lose_item(@item.id, 1)
    end
    @help_window.set_text(@item.name, 1)
    @animation1_id = @item.animation1_id
    @animation2_id = @item.animation2_id
    @common_event_id = @item.common_event_id
    index = @active_battler.current_action.target_index
    target = $game_party.smooth_target_actor(index)
    @target_battlers.clear
    @target_battlers = set_target_battlers(@item)
    for target in @target_battlers
      target.item_effect(@item)
    end
  end
  #--------------------------------------------------------------------------
  # * Obtener targets disponibles de item o skill
  #--------------------------------------------------------------------------
  def set_target_battlers(item)
    if @active_battler.is_a?(Game_Actor)
      allies = $game_party.actors.clone
      enemies = $game_troop.enemies.clone
    else
      allies = $game_troop.enemies.clone
      enemies = $game_party.actors.clone
    end
    index = @active_battler.current_action.target_index
    result = []
    if item.scope_ally == true
      for target in allies
        result.push(target)
      end
    end
    if item.scope_enemy == true
      for target in enemies
        result.push(target)
      end
    end
    if item.scope_user == true
      if !result.include?(@active_battler)
        result.push(@active_battler)
      end
    end
    if item.scope_user == false
      result.delete(@active_battler)
    end
    if item.scope_all == false
      if item.scope_random == true
        result.select!{|target| !target.dead?} if item.scope_alive == true
        result.select!{|target| target.dead?} if item.scope_alive == false
        result = [result[rand(result.size)]]
      else
        if Scope::DEFAULT_DEAD_SELECT == false
          result.select!{|target| !target.dead?} if item.scope_alive == true
          result.select!{|target| target.dead?} if item.scope_alive == false
        end
        result = [result[index]]
      end
    end
    result.select!{|target| !target.dead?} if item.scope_alive == true
    result.select!{|target| target.dead?} if item.scope_alive == false
    for r in item.restrictions
      if r.arity == 1
        result.select!{|target| r.call(target) == true} rescue nil
      else
        result.select!{|target| r.call == true} rescue nil
      end
    end
    return result
  end
end


Última edición por Wecoc el 2017-05-07, 10:06, editado 6 veces
avatar
Wecoc
Administrador
Administrador



Créditos 12083

Gracias : 519

Volver arriba Ir abajo

RPG Maker XP Re: [XP] Advanced Scope

Mensaje por Producciones The Golden el 2017-01-10, 17:20

¿Cuál es la diferencia entre los que tienen only y los que no? el resto lo deduje todo pero a ese no le hallo posibilidad de diferencia ya que para mi ya usaste todas las posibilidades XD.
avatar
Producciones The Golden
Veterano
Veterano

0/3

Créditos 637

Gracias : 60

Volver arriba Ir abajo

RPG Maker XP Re: [XP] Advanced Scope

Mensaje por Wecoc el 2017-01-10, 17:47

@Producciones The Golden escribió:¿Cuál es la diferencia entre los que tienen only y los que no?

Puse en cada item de la demo la descripción de a quien afectan, porque sé que con el nombre no es muy intuitivo.

Ally Only (no Allioli, eso es una salsa xD) -> Solo aliados, sin incluir el usuario. Algunas skills de protección puede ser interesante inhabilitar que uno mismo pueda aplicársela. Además si éste está solo en la party no podrá usar esa skill, claro. Los demás con Only son el mismo concepto, solo que añadiendo propiedad Random, incluyendo enemigos o esas cosas.

Nótese que algunas combinaciones no están porque no tienen sentido, por ejemplo solo afectar al usuario y a la vez solo afectar a muertos.

Wecocio, digo... Wecoc escribió:Con ésto es fácil definir que sean solo seleccionables targets con una clase, o de un tipo de enemigo, o con una PV mayor al 50%, o que tengan cierto estado, o que sepan hacer cierta habilidad... Las posibilidades son altísimas.

Aprovecho para poner cómo hacer cada una de esas, para que tengáis esos ejemplos hechos. Lo pongo en $data_items, con $data_skills va igual.
Son solo los primeros que me vinieron a la mente, hay muchas más.

Targets con una clase (Class ID 3 en el ejemplo)
$data_items[1].restriction {|target| target.is_a?(Game_Actor) && target.class_id == 3}

Targets solo de ciertos tipos de enemigo (21, 23, 30 y 31 en el ejemplo)
$data_items[1].restriction {|target| target.is_a?(Game_Enemy) && [20, 23, 30, 31].include?(target.id) }

Targets con HP mayor a la mitad
$data_items[1].restriction {|target| target.hp >= (target.maxhp * 50 / 100) }

Targets con cierto estado alterado (el 2 en el ejemplo)
$data_items[1].restriction {|target| target.state?(2) }

Targets que sepan alguna habilidad (solo actores) (Skill ID 50 en el ejemplo)
$data_items[1].restriction {|target| target.skill_learn?(50)}

Targets que sepan alguna habilidad (solo enemies) (Skill ID 50 en el ejemplo)
$data_items[1].restriction {|target| target.actions.any?{|action| action.skill_id == 50 }}

Todo eso se definiría en un método se se llamaría al crear y al cargar partida, pero si usáis Data File Save solo definiéndolo una vez donde sea no habría que volver a definirlo al cargar partida, así que es mucho más cómodo.

Consejo:
Por si lo llamáis desde evento y no os cabe en una línea.

Ésto:
Código:
$data_items[ID].restriction {|target| (ACCIÓN) }
Es lo mismo que ésto:
Código:
$data_items[ID].restriction do |target|
  (ACCIÓN)
end
avatar
Wecoc
Administrador
Administrador



Créditos 12083

Gracias : 519

Volver arriba Ir abajo

RPG Maker XP Re: [XP] Advanced Scope

Mensaje por Producciones The Golden el 2017-01-10, 18:02

Pero entre "random ally" y "random ally only", ¿cuál es la diferencia? XD, no quiero descargar la demo de momento ya que 1) no tengo ganas ajajaajaj 2) tengo MUY poco espacio en disco, necesito uno nuevo de un tera.
avatar
Producciones The Golden
Veterano
Veterano

0/3

Créditos 637

Gracias : 60

Volver arriba Ir abajo

RPG Maker XP Re: [XP] Advanced Scope

Mensaje por Wecoc el 2017-01-10, 18:19

Considera que hay 4 actores.

Random Ally:Selecciona al azar:[Usuario][Aliado 1][Aliado 2][Aliado 3]
Random Ally Only:Selecciona al azar:
-
[Aliado 1][Aliado 2][Aliado 3]
Además nuevamente si solo hay un actor puede usar Random Ally pero no Random Ally Only.

Consejo 2:
Si con Random Ally consideras que habiendo solo un actor (vivo) tampoco debería estar activada esa skill o item porque en realidad el resultado ya no es random (no te falta razón), solo hay que definirle una restricción a parte otra vez, aunque es algo especial:

Código:
$data_items[1].restriction do
  n = 0 ; for target in $game_party.actors
    n += 1 if target.exist?
  end
  (n > 1)
end
avatar
Wecoc
Administrador
Administrador



Créditos 12083

Gracias : 519

Volver arriba Ir abajo

RPG Maker XP Re: [XP] Advanced Scope

Mensaje por Producciones The Golden el 2017-01-10, 18:30

Ah! con razón no pusiste "enemy only" por ejemplo... gracias por explicármelo! saludos!
avatar
Producciones The Golden
Veterano
Veterano

0/3

Créditos 637

Gracias : 60

Volver arriba Ir abajo

RPG Maker XP Re: [XP] Advanced Scope

Mensaje por Wecoc el 2017-05-07, 09:48

Actualización: Se ha arreglado un bug relacionado con el scope del Ataque normal.
Ha sido actualizado tanto el código del post principal como la demo.

También informo que éste script es parcialmente incompatible con el Data File Save pero he hecho una versión compatible. La pongo a continuación:

Código:
#==============================================================================
# ** [XP] Advanced Scope v1.0
# Versión compatible con el script Data File Save
# Atención: Éste script debe quedar DEBAJO del Data File Save
#------------------------------------------------------------------------------
# Autor: Wecoc (créditos opcionales)
#------------------------------------------------------------------------------
# Define nuevos tipos de Scope para Items y Skills
#------------------------------------------------------------------------------
# Se usa en $data_items[ID] y $data_skills[ID] exactamente de la misma forma
# Para definir el target usa:
# $data_items[ID].scope_ally   = true | false # Aliado
# $data_items[ID].scope_enemy  = true | false # Enemigo
# $data_items[ID].scope_all    = true | false # Todos los del grupo o uno solo
# $data_items[ID].scope_random = true | false # Uno al azar
# $data_items[ID].scope_user   = true | false # Incluir usuario
# $data_items[ID].scope_alive  = true | false # Solo miembros vivos
# $data_items[ID].scope_dead   = true | false # Solo miembros muertos
#------------------------------------------------------------------------------
# $data_items[ID].restriction(&block) # Definir restricción personalizada
# $data_items[ID].restrictions        # Obtener restricciones personalizadas
# $data_items[ID].clear_restrictions  # Borrar  restricciones personalizadas
#==============================================================================

#==============================================================================
# ** Scope Configuration
#==============================================================================

module Scope
  #----------------------------------------------------------------------------
  # Default Dead Select
  #----------------------------------------------------------------------------
  # Por defecto si un item solo afecta a vivos igualmente se puede seleccionar
  # a un aliado muerto, solo que el item no tendrá efecto.
  # Lo mismo con los items que afectan solo a muertos, se puede seleccionar
  # cualquiera.
  # Si pones false en cambio solo se pueden seleccionar los que cumplen
  # estrictamente la restricción
  #----------------------------------------------------------------------------
  
  DEFAULT_DEAD_SELECT = true
  
end

#==============================================================================
# ** Array
#==============================================================================

class Array
  #--------------------------------------------------------------------------
  # * Select!
  #--------------------------------------------------------------------------
  unless self.respond_to?(:select)
    def select!(&block)
      result = self.select(&block)
      self.replace(result)
    end
  end
end

#==============================================================================
# ** RPG
#==============================================================================

for Klass in [RPG::Item, RPG::Skill]
  class Klass
    
    ALLY  = [3, 4, 5, 6]
    ENEMY = [1, 2]
    ALL   = [2, 4, 6]
    ALIVE = [1, 2, 3, 4, 7]
    DEAD  = [5, 6]
    USER  = [3, 4, 5, 6, 7]
    
    define_method(:scope_ally)   { @scope_ally |= ALLY.include?(@scope) }
    define_method(:scope_enemy)  { @scope_enemy |= ENEMY.include?(@scope) }
    define_method(:scope_all)    { @scope_all |= ALL.include?(@scope) }
    define_method(:scope_random) { @scope_random |= false }
    define_method(:scope_alive)  { @scope_alive |= ALIVE.include?(@scope) }
    define_method(:scope_dead)   { @scope_dead |= DEAD.include?(@scope) }
    define_method(:scope_user)   { @scope_user |= USER.include?(@scope) }
    define_method(:scope_rest)   { @scope_rest = [] }
    define_method(:restrictions) { @scope_rest = [] }
    
    def restriction(&block)
      @scope_rest.push(block)
    end
    
    def clear_restrictions
      @scope_rest.clear
    end
    
    def set_scope(ally,enemy,all,random=false,user=true,alive=true,dead=false)
      @scope_ally   = ally
      @scope_enemy  = enemy
      @scope_all    = all
      @scope_random = random
      @scope_user   = user
      @scope_alive  = alive
      @scope_dead   = dead
    end
  end
end

#==============================================================================
# ** Arrow_Base
#==============================================================================

class Arrow_Base < Sprite
  attr_reader :user
  attr_reader :item
  attr_reader :target
  attr_reader :targets
  #--------------------------------------------------------------------------
  # * Initialize
  #--------------------------------------------------------------------------
  def initialize(viewport, user, item)
    super(viewport)
    self.bitmap = RPG::Cache.windowskin($game_system.windowskin_name)
    self.ox = 16
    self.oy = 64
    self.z = 2500
    @blink_count = 0
    @index = 0
    @help_window = nil
    @user = user
    @item = item
    @targets = target_battlers
    @target = @targets[0]
    update_sprite
  end
  #--------------------------------------------------------------------------
  # * Obtener índice
  #--------------------------------------------------------------------------
  def index
    return @targets.index(@target) rescue -1
  end
  #--------------------------------------------------------------------------
  # * Definir índice
  #--------------------------------------------------------------------------
  def index=(index)
    @target = @targets[index]
  end
  #--------------------------------------------------------------------------
  # * Obtener targets seleccionables
  #--------------------------------------------------------------------------
  def target_battlers
    if @user.is_a?(Game_Actor)
      allies = $game_party.actors.clone
      enemies = $game_troop.enemies.clone
    else
      allies = $game_troop.enemies.clone
      enemies = $game_party.actors.clone
    end
    allies.delete_if {|target| target.hidden}
    enemies.delete_if{|target| target.hidden}
    if @item == nil
      enemies.delete_if {|target| !target.exist?}
      return enemies
    end
    result = []
    if @item.scope_ally == true
      for target in allies
        result.push(target)
      end
    end
    if @item.scope_enemy == true
      for target in enemies
        result.push(target)
      end
    end
    if @item.scope_user == true
      if !result.include?(@user)
        result.push(@user)
      end
    end
    if @item.scope_user == false
      result.delete(@user)
    end
    if @item.scope_alive == true && Scope::DEFAULT_DEAD_SELECT == false
      result.select!{|target| !target.dead?}
    end
    if @item.scope_dead == true && Scope::DEFAULT_DEAD_SELECT == false
      result.select!{|target| target.dead?}
    end
    for r in @item.restrictions
      if r.arity == 1
        result.select!{|target| r.call(target) == true} rescue nil
      else
        result.select!{|target| r.call == true} rescue nil
      end
    end
    return result
  end
  #--------------------------------------------------------------------------
  # * Update
  #--------------------------------------------------------------------------
  def update
    update_sprite
    if @help_window != nil
      update_help
    end
    if @target == nil
      self.visible = false
      return
    end
    self.visible = true
    # Siguiente target
    if Input.repeat?(Input::RIGHT)
      $game_system.se_play($data_system.cursor_se)
      self.index = (self.index + 1) % @targets.size
    end
    # Anterior target
    if Input.repeat?(Input::LEFT)
      $game_system.se_play($data_system.cursor_se)
      self.index = (self.index - 1) % @targets.size
    end
    # Colocar flecha encima del target
    if @target != nil
      self.x = @target.screen_x
      self.y = @target.screen_y
    end
  end
  #--------------------------------------------------------------------------
  # * Update Sprite
  #--------------------------------------------------------------------------
  def update_sprite
    @blink_count = (@blink_count + 1) % 8
    if @blink_count < 4
      self.src_rect.set(128, 96, 32, 32)
    else
      self.src_rect.set(160, 96, 32, 32)
    end
  end
  #--------------------------------------------------------------------------
  # * Update Help
  #--------------------------------------------------------------------------
  def update_help
    if @target == nil
      @help_window.set_text("")
      return
    end
    if @target.is_a?(Game_Actor)
      @help_window.set_actor(@target)
    else
      @help_window.set_enemy(@target)
    end
  end
end

#==============================================================================
# ** Game_Battler
#==============================================================================

class Game_Battler
  #--------------------------------------------------------------------------
  # * Obtener si puede usar la Skill
  #--------------------------------------------------------------------------
  alias wecoc_scope_skill_use? skill_can_use? unless $@
  def skill_can_use?(skill_id)
    skill = $data_skills[skill_id]
    return false if skill.nil?   # La skill no existe
    return false if !self.exist? # El usuario está oculto o muerto
    if self.is_a?(Game_Actor)
      members = $game_party.actors.clone
    else
      members = $game_troop.enemies.clone
    end
    if members.size == 1 # Está solo en el grupo y se requiere un aliado
      if skill.user == false && skill.ally == false && skill.enemy == false
        return false
      end
    end
    for r in skill.restrictions
      if r.arity == 1
        members.select!{|target| r.call(target) == true} rescue nil
      else
        members.select!{|target| r.call == true} rescue nil
      end
    end
    return false if members.size == 0
    return wecoc_scope_skill_use?(skill_id)
  end
  #--------------------------------------------------------------------------
  # * Obtener si puede usar el Item
  #--------------------------------------------------------------------------
  def item_can_use?(item_id)
    item = $data_items[item_id]
    return false if item.nil?    # El item no existe
    return false if !self.exist? # El usuario está oculto o muerto
    if self.is_a?(Game_Actor)
      # El grupo no tiene ese objeto
      return false if $game_party.item_number(item_id) == 0
      # Restricciones del item (Solo menú / Solo batalla)
      return false if $game_temp.in_battle  && item.occasion == 2
      return false if !$game_temp.in_battle && item.occasion == 1
      members = $game_party.actors.clone
    else
      members = $game_troop.enemies.clone
    end
    if members.size == 1 # Está solo en el grupo y se requiere un aliado
      if item.user == false && item.ally == false && item.enemy == false
        return false
      end
    end
    for r in item.restrictions
      if r.arity == 1
        members.select!{|target| r.call(target) == true} rescue nil
      else
        members.select!{|target| r.call == true} rescue nil
      end
    end
    return false if members.size == 0
    return true
  end
end

#==============================================================================
# ** Game_Party
#==============================================================================

class Game_Party
  #--------------------------------------------------------------------------
  # * Obtener si el grupo puede usar el Item
  #--------------------------------------------------------------------------
  def item_can_use?(item_id)
    for member in $game_party.actors
      if member.item_can_use?(item_id)
        return true
      end
    end
    return false
  end
end

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

class Scene_Battle
  #--------------------------------------------------------------------------
  # * Seleccionar enemigo
  #--------------------------------------------------------------------------
  def start_enemy_select
    item = nil
    if @active_battler.current_action.kind == 1
      item = @skill if @skill != nil
    end
    if @active_battler.current_action.kind == 2
      item = @item  if @item != nil
    end
    @enemy_arrow = Arrow_Base.new(@spriteset.viewport2, @active_battler, item)
    @enemy_arrow.help_window = @help_window
    @actor_command_window.active = false
    @actor_command_window.visible = false
  end
  #--------------------------------------------------------------------------
  # * Seleccionar actor
  #--------------------------------------------------------------------------
  def start_actor_select
    item = nil
    if @active_battler.current_action.kind == 1
      item = @skill if @skill != nil
    end
    if @active_battler.current_action.kind == 2
      item = @item  if @item != nil
    end
    @actor_arrow = Arrow_Base.new(@spriteset.viewport2, @active_battler, item)
    @actor_arrow.index = @actor_index
    @actor_arrow.help_window = @help_window
    @actor_command_window.active = false
    @actor_command_window.visible = false
  end
  #--------------------------------------------------------------------------
  # * Aplicar skill
  #--------------------------------------------------------------------------
  def make_skill_action_result
    @skill = $data_skills[@active_battler.current_action.skill_id]
    unless @active_battler.current_action.forcing
      unless @active_battler.skill_can_use?(@skill.id)
        $game_temp.forcing_battler = nil
        @phase4_step = 1
        return
      end
    end
    @active_battler.sp -= @skill.sp_cost
    @status_window.refresh
    @help_window.set_text(@skill.name, 1)
    @animation1_id = @skill.animation1_id
    @animation2_id = @skill.animation2_id
    @common_event_id = @skill.common_event_id
    @target_battlers.clear
    @target_battlers = set_target_battlers(@skill)
    for target in @target_battlers
      target.skill_effect(@active_battler, @skill)
    end
  end
  #--------------------------------------------------------------------------
  # * Aplicar item
  #--------------------------------------------------------------------------
  def make_item_action_result
    @item = $data_items[@active_battler.current_action.item_id]
    unless @active_battler.item_can_use?(@item.id)
      @phase4_step = 1
      return
    end
    if @item.consumable
      $game_party.lose_item(@item.id, 1)
    end
    @help_window.set_text(@item.name, 1)
    @animation1_id = @item.animation1_id
    @animation2_id = @item.animation2_id
    @common_event_id = @item.common_event_id
    index = @active_battler.current_action.target_index
    target = $game_party.smooth_target_actor(index)
    @target_battlers.clear
    @target_battlers = set_target_battlers(@item)
    for target in @target_battlers
      target.item_effect(@item)
    end
  end
  #--------------------------------------------------------------------------
  # * Obtener targets disponibles de item o skill
  #--------------------------------------------------------------------------
  def set_target_battlers(item)
    if @active_battler.is_a?(Game_Actor)
      allies = $game_party.actors.clone
      enemies = $game_troop.enemies.clone
    else
      allies = $game_troop.enemies.clone
      enemies = $game_party.actors.clone
    end
    index = @active_battler.current_action.target_index
    result = []
    if item.scope_ally == true
      for target in allies
        result.push(target)
      end
    end
    if item.scope_enemy == true
      for target in enemies
        result.push(target)
      end
    end
    if item.scope_user == true
      if !result.include?(@active_battler)
        result.push(@active_battler)
      end
    end
    if item.scope_user == false
      result.delete(@active_battler)
    end
    if item.scope_all == false
      if item.scope_random == true
        result.select!{|target| !target.dead?} if item.scope_alive == true
        result.select!{|target| target.dead?} if item.scope_alive == false
        result = [result[rand(result.size)]]
      else
        if Scope::DEFAULT_DEAD_SELECT == false
          result.select!{|target| !target.dead?} if item.scope_alive == true
          result.select!{|target| target.dead?} if item.scope_alive == false
        end
        result = [result[index]]
      end
    end
    result.select!{|target| !target.dead?} if item.scope_alive == true
    result.select!{|target| target.dead?} if item.scope_alive == false
    for r in item.restrictions
      if r.arity == 1
        result.select!{|target| r.call(target) == true} rescue nil
      else
        result.select!{|target| r.call == true} rescue nil
      end
    end
    return result
  end
end

Disculpen las molestias. Ojalá ahora todo funcione bien...
avatar
Wecoc
Administrador
Administrador



Créditos 12083

Gracias : 519

Volver arriba Ir abajo

RPG Maker XP Re: [XP] Advanced Scope

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.