Mundo Maker
¡Bienvenid@ a Mundo Maker!

¿Quieres aprender todo sobre el RPG Maker?



Regístrate y forma parte de Mundo Maker.

Fixes para IGOS v0.2

Ver el tema anterior Ver el tema siguiente Ir abajo

Fixes para IGOS v0.2

Mensaje por silvanash el 2015-04-04, 13:20

Pues sí, ahora el tío silva edita scripts ajenos.

Este script es una serie de fixes para el HIGOS diseñado por Eron y Wecocio. Arregla varios de los features más irritantes del IGOS y, en teoría, es compatible con cualquier otro add-on que quieran hacerle al sistema.

¿Pero qué hacen tus fixes, tío silva? - tipo random.

Las imágenes son más útiles que las palabras en este caso.

Sin fix:
Con fix:
Sin fix:
Con fix:

El HIGOS por default te separa todos los objetos, aunque sean total y absolutamente idénticos. En las capturas sin los fixes se ve cómo ha dibujado todas las pociones por separado, aunque en realidad sólo hay dos tipos de pociones ("poción" y "poción b", que es una poción normal modificada mediante IGOS). Con los fixes, las pociones (y el escudo de bronce) están en stacks ordenados.

¿Y si no me importa tener todas las pociones separadas? - otro tipo random.

Pues te [inserte taco de su elección aquí]. No, es broma.

Hablando en serio: ¿alguna vez habéis llegado a tener 20 pociones en un RPG? ¿50? ¿90? Pues bien, sin usar los fixes, al entrar en el menú de objetos, el Maker se congela, y hasta que no pasan diez segundos no entra en el menú. Esos diez segundos los está usando para dibujarte las 90 pociones una a una, en lugar de agruparlas todas y decirte que tienes 90 stackeadas. Todo esto ocurre debido a un problema con el IGOS original, que obligaba a tener todos los items (y armas y armaduras) separados, aunque fuesen idénticos.

¿Cuál es ese problema, tío silva? - otro tipo random (no es el segundo).

Los objetos del IGOS son independientes, muy independientes (por algo el script se llama "Independent"). Ese sistema convierte los objetos en scripts, y un objeto de script, al inicializarse, recibe una ID. Dos objetos inicializados en llamadas diferentes tienen IDs diferentes. Por eso, el IGOS original muestra todos los objetos por separado.

Ejemplo: usa el comando de [Cambiar objeto] en el IGOS original para darte pociones. Pon tres comandos seguidos, y en el primero da una poción, en el segundo tres y en el tercero dos. ¿Resultado? Las tres pociones del segundo comando son idénticas entre sí (tienen la misma ID de script), y las dos pociones del tercer comando son idénticas entre sí. Las pociones de los tres comandos tienen tres IDs de script diferentes, y por eso el Maker las considera diferentes (pese a que todas tienen los mismos datos de item). A la hora de dibujarlas, es immposible agruparlas porque el Maker te tiraría un stack de una poción, un stack de tres pociones y un stack de dos pociones (y las seis pociones tienen los mismos datos). ¡Imposible hasta que llegaron estos fixes!

Stacks con fixes:

En esa última imagen hay tres stacks de "poción". Está la poción original, la poción b (que es una poción modificada), y una tercera poción b, que tiene modificada la descripción del objeto. Los fixes han reconocido que se trata de tres objetos distintos, y los ha agrupado correctamente.

¿Y qué más hacen tus maravillosos fixes? - otro tipo random (no, no le he pagado para que diga eso).

Al agrupar los objetos en stacks, surgieron otras complicaciones que era necesario corregir. En primer lugar, están corregidos los métodos de lose_item, lose_weapon y lose_armor para que pueda eliminar objetos que son idénticos. El IGOS original no me funcionaba correctamente cuando quería eliminar dos pociones de un stack debido al problema con las IDs de scripts. Si las dos pociones se habían añadido en momentos diferentes, tenían IDs diferentes y no podían eliminarse a la vez. El fix permite eliminar objetos que sean idénticos en stats, sin importar la ID de script (los fixes beben de los métodos originales de IGOS, así que no todo es malo).

El último fix no es un fix real. Copié el update_target del Scene_Item original, corregí una línea y lo pegué ahí mismo. En el IGOS original, todos los objetos están separados, así que tras usar una poción se cierra automáticamente window_target. Con los fixes, las pociones están en stacks, así que es posible mantener window_target activa para seguir usando pociones de ese stack.

Además de ello, los fixes permiten usar de nuevo Window_ShopNumber, que en IGOS está desactivada. Window_ShopNumber es la ventana de elegir cantidad en el menú de comprar/vender. Dado que en IGOS todo va uno por uno, la compra/venta es igual: se compra y vende un objeto cada vez. Los fixes permiten comprar y vender en masa de nuevo.

Nota1: los fixes permiten usar Window_ShopNumber, pero no han editado los scripts de tienda para poder usarla. Para ello, es necesario usar otro script que sí que modifique la tienda y sea compatible con IGOS, como el Improved Scene_Shop for IGOS.

Nota2: si alguien quiere hacer add-ons para IGOS y usar mis fixes, que tenga en cuenta cómo funcionan los fixes. Los fixes sólo cuentan como copias de un objeto los que sean idénticos (ignora la ID de script). Es decir, alguien con dos pociones normales y una poción normal al 50% (porque el IGOS permite hacer eso) no tiene 3 pociones normales; tiene 2 pociones normales y una poción normal al 50%. Este detalle es importante cuando sea necesario contar la cantidad de copias que tiene el jugador. Si hay que contar las copias de algo, que sea con item_number(item), no _by_id ni item_id, y lo mismo para armas y armaduras.

Nota3: (y esto debería decirlo Wecocio, no yo) IGOS modifica un montón de los scripts base del juego, y, por lo tanto, es probable que sea incompatible con muchas cosas. Si os salta bugazo, molestad a Wecocio para que os adapte el script a IGOS.

Y ahora el script (por fin, ¿eh?):

Código:
=begin
==============================================================================
#Fixes para IGOS v0.2
==============================================================================
Agrupa los objetos que son totalmente idénticos en Window_Item y Window_ShopSell
De esta forma no se bloquea el programa intentando dibujar 99 pociones iguales
==============================================================================
Corrige lose_item, _weapon y _armor para que pueda eliminar varios a la vez
cuando son idénticos
==============================================================================
Restablece el funcionamiento antiguo de Scene_Item, sin borrar window_target tras
usar un objeto. Maldita sea, me siento como si estuviese arreglando todos los
errores que metió Wecocio al separar todos los objetos que son idénticos
==============================================================================
Editados los métodos de gain_item, _weapon y _armor para que funcionen con los stacks
==============================================================================
Agrupa los objetos que son idénticos en Window_EquipItem
==============================================================================

Editado:
Window_Item
-> refresh
-> draw_item
Window_ShopSell
-> refresh
-> draw_item
Window_EquipItem
-> refresh
-> draw_item
Game_Party
-> lose_item
-> lose_weapon
-> lose_armor
-> gain_item
-> gain_weapon
-> gain_armor
Scene_Item
-> update_target
end
=end

#==============================================================================
# ** Window_Item
#------------------------------------------------------------------------------
#  This window displays items in possession on the item and battle screens.
#==============================================================================

class Window_Item < Window_Selectable
  def refresh
    if self.contents != nil
      self.contents.dispose
      self.contents = nil
    end
    @data = []
    for item in $game_party.items
      @data = @data.select{|e| item.compare_with(e).size != 0}
      @data.push(item)
    end
    unless $game_temp.in_battle
      for weapon in $game_party.weapons
        @data = @data.select{|e| weapon.compare_with(e).size != 0}
        @data.push(weapon)
      end
      for armor in $game_party.armors
        @data = @data.select{|e| armor.compare_with(e).size != 0}
        @data.push(armor)
      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

  def draw_item(index)
    item = @data[index]
    case item.type
    when 0
      number = $game_party.item_number(item)
    when 1
      number = $game_party.weapon_number(item)
    when 2
      number = $game_party.armor_number(item)
    end
    if item.is_item? and $game_party.item_can_use?(item)
      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(item.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, 212, 32, item.name, 0)
    self.contents.draw_text(x + 240, y, 16, 32, ":", 1)
    self.contents.draw_text(x + 256, y, 24, 32, number.to_s, 2)
  end
end


#==============================================================================
# ** Window_ShopSell
#------------------------------------------------------------------------------
#  This window displays items in possession for selling on the shop screen.
#==============================================================================

class Window_ShopSell
  #--------------------------------------------------------------------------
  # * Refresh
  #--------------------------------------------------------------------------
  def refresh
    if self.contents != nil
      self.contents.dispose
      self.contents = nil
    end
    @data = []
    items = $game_party.items
    for item in $game_party.items
      @data = @data.select{|e| item.compare_with(e).size != 0}
      @data.push(item)
    end
    for weapon in $game_party.weapons
      @data = @data.select{|e| weapon.compare_with(e).size != 0}
      @data.push(weapon)
    end
    for armor in $game_party.armors
      @data = @data.select{|e| armor.compare_with(e).size != 0}
      @data.push(armor)
    end
    # If item count is not 0, make a bitmap and draw all items
    @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
  
  #--------------------------------------------------------------------------
  # * Draw Item
  #     index : item number
  #--------------------------------------------------------------------------
  def draw_item(index)
    item = @data[index]
    case item.type
    when 0
      number = $game_party.item_number(item)
    when 1
      number = $game_party.weapon_number(item)
    when 2
      number = $game_party.armor_number(item)
    end
    if item.is_item? and $game_party.item_can_use?(item)
      self.contents.font.color = normal_color
    else
      self.contents.font.color = disabled_color
    end
    # If items are sellable, set to valid text color. If not, set to invalid
    # text color.
    if item.price > 0
      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(item.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, 212, 32, item.name, 0)
    self.contents.draw_text(x + 240, y, 16, 32, ":", 1)
    self.contents.draw_text(x + 256, y, 24, 32, number.to_s, 2)
  end
end

#==============================================================================
# ** Game_Party
#------------------------------------------------------------------------------
#  This class handles the party. It includes information on amount of gold
#  and items. Refer to "$game_party" for the instance of this class.
#==============================================================================

class Game_Party

  def lose_item(item_id, n)
    return gain_item(item_id, -n) if n < 0
    return if @items.size == 0
    if item_id.is_a?(Game_Item)
      item = item_id
      item_id = item.id
    else
      item = Game_Item.new(item_id)
    end
    while n > 0
      n -= 1
      for i in 0...@items.size
        if @items[i].compare_with(item).size == 0
          @items.delete_at(i)
          break
        end
      end
    end
    @items.sort_by!(:id)
  end
  
  def lose_weapon(weapon_id, n)
    return gain_weapon(weapon_id, -n) if n < 0
    return if @weapons.size == 0
    if weapon_id.is_a?(Game_Weapon)
      weapon = weapon_id
      weapon_id = weapon.id
    else
      weapon = Game_Weapon.new(weapon_id)
    end
    while n > 0
      n -= 1
      for i in 0...@weapons.size
        if @weapons[i].compare_with(weapon).size == 0
          @weapons.delete_at(i)
          break
        end
      end
    end
    @weapons.sort_by!(:id)
  end
  
  def lose_armor(armor_id, n)
    return gain_armor(armor_id, -n) if n < 0
    return if @armors.size == 0
    if armor_id.is_a?(Game_Armor)
      armor = armor_id
      armor_id = armor.id
    else
      armor = Game_Armor.new(armor_id)
    end
    while n > 0
      n -= 1
      for i in 0...@armors.size
        if @armors[i].compare_with(armor).size == 0
          @armors.delete_at(i)
          break
        end
      end
    end
    @armors.sort_by!(:id)
  end
  
  def gain_item(item_id, n)
    return lose_item(item_id, -n) if n < 0
    if item_id.is_a?(Game_Item)
      item = item_id
      item_id = item.id
    else
      item = Game_Item.new(item_id)
    end
    itd = @items.select{|x| x.compare_with(item).size == 0}
    n = [n, 99 - itd.size].min
    n.times{@items.push(item)}
    @items.sort_by!(:id)
  end

  def gain_weapon(weapon_id, n)
    return lose_weapon(weapon_id, -n) if n < 0
    if weapon_id.is_a?(Game_Weapon)
      weapon = weapon_id
      weapon_id = weapon.id
    else
      weapon = Game_Weapon.new(weapon_id)
    end
    itd = @weapons.select{|x| x.compare_with(weapon).size == 0}
    n = [n, 99 - itd.size].min
    n.times{@weapons.push(weapon)}
    @weapons.sort_by!(:id)
  end
  
  def gain_armor(armor_id, n)
    return lose_armor(armor_id, -n) if n < 0
    if armor_id.is_a?(Game_Armor)
      armor = armor_id
      armor_id = armor.id
    else
      armor = Game_Armor.new(armor_id)
    end
    itd = @armors.select{|x| x.compare_with(armor).size == 0}
    n = [n, 99 - itd.size].min
    n.times{@armors.push(armor)}
    @armors.sort_by!(:id)
  end

end

#==============================================================================
# ** Scene_Item
#------------------------------------------------------------------------------
#  This class performs item screen processing.
#==============================================================================

class Scene_Item
  
  def update_target
    if Input.trigger?(Input::B)
      $game_system.se_play($data_system.cancel_se)
      unless $game_party.item_can_use?(@item)
        @item_window.refresh
      end
      @item_window.active = true
      @target_window.visible = false
      @target_window.active = false
      return
    end
    if Input.trigger?(Input::C)
      if $game_party.item_number(@item) == 0
        $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.item_effect(@item)
        end
      end
      if @target_window.index >= 0
        target = $game_party.actors[@target_window.index]
        used = target.item_effect(@item)
      end
      if used
        $game_system.se_play(@item.menu_se)
        if @item.consumable
          $game_party.lose_item(@item, 1)
          @item_window.draw_item(@item_window.index)
        end
        @target_window.refresh
        if $game_party.all_dead?
          $scene = Scene_Gameover.new
          return
        end
        if @item.common_event_id > 0
          $game_temp.common_event_id = @item.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

#==============================================================================
# ** Window_EquipItem
#------------------------------------------------------------------------------
#  This window displays choices when opting to change equipment on the
#  equipment screen.
#==============================================================================

class Window_EquipItem < Window_Selectable
  def refresh
    if self.contents != nil
      self.contents.dispose
      self.contents = nil
    end
    @data = []
    if @equip_type == 0
      weapon_set = $data_classes[@actor.class_id].weapon_set
      for weapon in $game_party.weapons
        if weapon_set.include?(weapon.id)
          @data = @data.select{|e| weapon.compare_with(e).size != 0}
          @data.push(weapon)
        end
      end
    end
    if @equip_type != 0
      armor_set = $data_classes[@actor.class_id].armor_set
      for armor in $game_party.armors
        if armor.kind == @equip_type-1
          if armor_set.include?(armor.id)
            @data = @data.select{|e| armor.compare_with(e).size != 0}
            @data.push(armor)
          end
        end
      end
    end
    @data.push(nil)
    @item_max = @data.size
    self.contents = Bitmap.new(width - 32, row_max * 32)
    for i in 0...@item_max-1
      draw_item(i)
    end
  end
  
  def draw_item(index)
    item = @data[index]
    x = 4 + index % 2 * (288 + 32)
    y = index / 2 * 32
    case item.type
    when 1
      number = $game_party.weapon_number(item)
    when 2
      number = $game_party.armor_number(item)
    end
    bitmap = RPG::Cache.icon(item.icon_name)
    self.contents.blt(x, y + 4, bitmap, Rect.new(0, 0, 24, 24))
    self.contents.font.color = normal_color
    self.contents.draw_text(x + 28, y, 212, 32, item.name, 0)
    self.contents.draw_text(x + 240, y, 16, 32, ":", 1)
    self.contents.draw_text(x + 256, y, 24, 32, number.to_s, 2)
  end

end

Instrucciones:
Pegar encima de Main, pero DEBAJO de todos los scripts base del HIGOS.

Y ya que está de moda esto de los derechos de autor, spammeo los míos:
No pido créditos (ni siquiera me he tomado la molestia de firmar el script). Podéis usar los fixes para cualquier proyecto, sea comercial o no. Sin embargo, no puedo decir nada acerca del IGOS original, puesto que no es mío (y los fixes no sirven para nada sin el IGOS original). Tampoco os permito publicar este script en ningún otro sitio. Si alguien quiere los fixes, que venga a este post. Y, por encima de todo, conservar la cabecera del script, en especial la parte donde me quejo de cómo está hecho.

Edito:
Cambios en la versión v0.2:
- Editado también gain_item, _weapon y _armor para que funcione con los stacks de items que son idénticos entre sí.
- Editado Window_EquipItem para mostrar los objetos idénticos en stacks. Queda pendiente arreglar un bug del IGOS que no he conseguido solucionar por mi cuenta.
- Corregido un bug gráfico menor en una de las windows que edité en la versión 0.1.
avatar
silvanash
Aventurero
Aventurero

0/3

Créditos 1631

Gracias : 231

Volver arriba Ir abajo

Re: Fixes para IGOS v0.2

Mensaje por Wecoc el 2015-09-30, 23:03

Atención: Éste script ya no es necesario para IGOS a partir de la versión 1.1 puesto que sus fixes fueron integrados como parte del sistema.

El script de Improved Shop que usaba éste fix, ya no lo requiere.
Doy las gracias a silvanash por el esfuerzo que puso en mejorar el sistema.
avatar
Wecoc
Administrador
Administrador



Créditos 12387

Gracias : 595

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.