Caveman's sets(VXACE)
Автор: caveman
Версия: 1.0
Тип: дополнительная фича




Описание:
Кто играл в последнюю версию ДДД, вероятно, заметили в нем комплекты предметов:

Собрал растекшийся по древу ровным слоем код и вынес все в отдельный скрипт.

Этот скрипт добавляет в игру сеты - комплекты предметов, которые, будучи надеты на персонажа сразу, дают дополнительные бонусы.
Кроме внутренней логики и задания сетов, в скрипте также есть окно для просмотра наборов, встроенное в стандарт экипировки. Вариант не очень, и я использую отображение по-другому, но хотя бы показать, что скрипт работает, можно.

Использование

Скрипт не шибко прост в использовании и требует некоторых знаний скриптинга. Все нужное описано в скрипте, и в деме.

Сеты набиваются в классе Item_Sets. Формат таков:
# код, название, количество частей, номер оружия в БД, номер брони в БД
# последние 2 параметра содержат ссылки на итемы в БД, в
# которые прописываем плюсы и минусы комплекта
# разные, так как в оружии есть то, чего нет в броне и наоборот

Пример:
self.sets.push(ItemSet.new(1, "Костюм Мастера Огня", 3, 4, 8))

В данном примере мы добавили сет из трех предметов, и его бонусы (и описание) будут в оружии под номером 4 и броне под номером 8. Так как доп фичи у оружия и брони различаются (например, у оружия элемент рейт - на атаку, а у брони - на защиту), то иногда нужно заполнять оба слота.

Теперь выбираем экип, который является частью сета и ставим ему в нотсы <iset>1</iset>
Всего их, помним, три!

Итак, комплект готов, прописываем в фейковом оружии и броне параметры и в нотсах:
<set_name>Костюм Мастера Огня</set_name>
<set_desc>+ 10 магии, + 5 маг защиты,
+ 15 маны, +20% урона огнем, - 10% урона от земли.</set_desc>


Теги говорят сами за себя. Добавлю, что для варианта отображения, что я написал, больше 2х строк не влезет. В вашем варианте можно сделать по-другому, вплоть до отдельного окна со списком экипированных комплектов и их описаниями.

Выглядит это вот так (напомню, что в ДДД оно в статус окне для One Actor menu)


Подробнее все это можно увидеть в прилагаемой демо.


Код:
Спойлер скрипт:

Код:
#----------------------------------------------------------------------------
# * [ACE] Caveman Item Sets
#----------------------------------------------------------------------------
# * Автор - caveman
# * Версия: 1.0 RU
# * Релиз: 31/07/2015
#
# * Описание:
# * Добавляет в игру комплекты предметов, с достаточно простой настройкой
# *  полностью надетый комплект добавляет что-то еще, от себя и отмечается
# *  в окне экипировки.
# *
# *  Можно использовать и модифицировать как угодно с упоминанием или без.
#----------------------------------------------------------------------------


#----------------------------------------------------------------------------
# Класс комплекта
#----------------------------------------------------------------------------
class ItemSet
  attr_accessor :id # уникальный код
  attr_accessor :name # наименование
  attr_accessor :part_count # число частей
  
  attr_accessor :fake_id_1 # фейковое оружие для параметров
  attr_accessor :fake_id_2 # фейковая броня для параметров
  
  def initialize (id, name, part_count, fake_id_1, fake_id_2)
    self.id = id
    self.name = name
    self.part_count = part_count
    self.fake_id_1 = fake_id_1
    self.fake_id_2 = fake_id_2
  end
  
  def text
    # описание комплекта, лучше всего завести в обоих заметках
    return $data_weapons[fake_id_1].note if fake_id_1 != nil
    return $data_armors[fake_id_2].note if fake_id_2 != nil
    return ""
  end
end

#----------------------------------------------------------------------------
# Справочник всех доступных комплектов
#----------------------------------------------------------------------------
class Item_Sets
  attr_accessor :sets
  
  def initialize
    load_all_sets
  end
  
  ##############################################################
  # !!! Загрузка справочника, все комплекты заводятся тут !!!  #
  ##############################################################
  def load_all_sets
    self.sets = []
    # код, название, количество частей, номер оружия в БД, номер брони в БД
    # последние 2 параметра содержат ссылки на итемы в БД, в 
    # которые прописываем плюсы и минусы комплекта
    # разные, так как в оружии есть то, чего нет в броне и наоборот
    self.sets.push(ItemSet.new(1, "Костюм Мастера Огня", 3, 4, 8))
    self.sets.push(ItemSet.new(2, "Броня Рыцаря", 2, nil, 9))
    self.sets.push(ItemSet.new(3, "Детали Аагарота", 4, 5, 10))
  end
  
  def get_set(id)
    for i in 0..self.sets.length-1
      next if self.sets[i].id != id
      return self.sets[i]
    end
    return nil
  end
end

#----------------------------------------------------------------------------
# Для инициализации в БД
# (для мержа с другими скриптами просто допишите (1) в нужное место)
#----------------------------------------------------------------------------
module DataManager
  class << self
    alias css10_load_normal_database load_normal_database
    def load_normal_database
      css10_load_normal_database
      $data_sets = Item_Sets.new # 1
    end
    
    alias css10_load_battle_test_database load_battle_test_database
    def load_battle_test_database
      css10_load_battle_test_database
      $data_sets = Item_Sets.new # 1
    end
  end
end


#----------------------------------------------------------------------------
# Дополнения для актора
#----------------------------------------------------------------------------
class Game_Actor
  # здесь в список оружия/доспехов героя добавляем фейковые оружие/броню от сета
  def weapons
    @equips.select {|item| item.is_weapon? }.collect {|item| item.object } +
      sets(1).collect {|item| item.object } 
  end

  def armors
    @equips.select {|item| item.is_armor? }.collect {|item| item.object } +
      sets(2).collect {|item| item.object } 
  end

  def equips
    @equips.collect {|item| item.object } + 
      sets(1).collect {|item| item.object } +
      sets(2).collect {|item| item.object } 
  end
  
  def g_equips
    @equips
  end
  
  def sets(type)
    res = Array.new(0)
    for i in 0..$data_sets.sets.length-1
      set = $data_sets.sets[i]
      i = 0

      @equips.each do |item|
        if !item.is_nil? && item.object != nil
          if item.is_weapon? || item.is_armor?
            results = item.object.note.scan(/<iset>(.*?)<\/iset>/im)
            results.each do |res|
              i+=1 if res[0].to_i == set.id
            end
          end
        end
      end
      
      if i == set.part_count
        if type == 1 && set.fake_id_1 != nil
          item = Game_BaseItem.new
          item.set_equip(true, set.fake_id_1)
          item.object = $data_weapons[set.fake_id_1]
          res.push(item)
        end
        if type == 2 && set.fake_id_2 != nil
          item = Game_BaseItem.new
          item.set_equip(false, set.fake_id_2)
          item.object = $data_armors[set.fake_id_2]
          res.push(item)
        end
      end
    end
    return res
  end
end


#----------------------------------------------------------------------------
# Дополнительно: вариант GUI
#----------------------------------------------------------------------------
class Window_Set < Window_Base
  def initialize(x, y, height)
    super(x, y, Graphics.width, height)
  end

  def set_text(text)
    if text != @text
      @text = text
      refresh
    end
  end

  def clear
    set_text("")
  end

  def refresh
    contents.clear
    draw_objective(0, 0)
  end
  
  def draw_objective(x, y) 
    nnote = sets_text
    return if nnote == ""
    
    change_color(text_color(14))
    contents.font.size = 20
    draw_text(x+4, y, contents.width, 22, "Экипированные комплекты:") 

    contents.font.size = 18
    change_color(text_color(2)) 
    name = nnote.scan(/<set_name>(.*?)<\/set_name>/im)
    draw_text(x+200, y+2, contents.width, 20, name[0][0]) 
    
    change_color(text_color(11)) 
    desc = nnote.scan(/<set_desc>(.*?)<\/set_desc>/im)
    draw_text_desc(x+8, y+18, desc[0][0]) 
  end
    
  def draw_text_desc(x, y, text)
    text = convert_escape_characters(text)
    pos = {:x => x, :y => y, :new_x => x, :height => 16}
    process_character(text.slice!(0, 1), text, pos) until text.empty?
  end
  
  def sets_text
    res = ""
    for i in 0..$data_sets.sets.length-1
      set = $data_sets.sets[i]
      i = 0

      $game_actors[1].g_equips.each do |item|
        if !item.is_nil? && item.object != nil
          if item.is_weapon? || item.is_armor?
            results = item.object.note.scan(/<iset>(.*?)<\/iset>/im)
            results.each do |res|
              i+=1 if res[0].to_i == set.id
            end
          end
        end
      end
      
      if i == set.part_count
        res += set.text
        res += "\n"
      end
    end
    return res
  end
end

class Scene_Equip
  alias cs10_start start
  def start
    cs10_start
    @item_window.height /= 2
    create_sets_window
  end

  def create_sets_window
    @sets_window = Window_Set.new(0, Graphics.height-@item_window.height, 
      @item_window.height)
    @sets_window.viewport = @viewport
  end
  
  def on_item_ok
    Sound.play_equip
    @actor.change_equip(@slot_window.index, @item_window.item)
    @slot_window.activate
    @slot_window.refresh
    @item_window.unselect
    @item_window.refresh
    @sets_window.refresh if @sets_window
  end
end


Либо тут: https://drive.google.com/file/d/0B_UUr9ncWPb1UExsX3hnc3ZiaUE/view?usp=sharing
Демо прилагается тут: https://yadi.sk/d/pxRaCL3hiCsb3


PS: так как собиралось на коленке на работе, то вполне могут быть какие-то косяки. Пишите, если что-то найдете.