Galv’s Magic Shards V.1.8

Demo
Demo – Version 1.8 >
This script requires graphics from the demo.

Script

#------------------------------------------------------------------------------#
#  Galv's Magic Shards
#------------------------------------------------------------------------------#
#  For: RPGMAKER VX ACE
#  Version - 1.8
#  Thanks: Ocedic, DP3, Reactive Owl, LucidK for ideas, inspiration and/or help
#------------------------------------------------------------------------------#
#  2013-12-30 - Version 1.8 - added unequip_shards script call
#  2013-08-09 - Version 1.7 - fixed bug with optimizing equips
#  2013-06-30 - Version 1.6 - made armors and weapons parameters add to actor
#  2013-04-02 - Version 1.5 - linked shard skills no longer display learned
#                           - skill if they dont have that skill type.
#  2013-03-28 - Version 1.4 - skills learned no longer appear in 'view skills'
#                             if actor doesn't have that skill type.
#  2013-03-25 - Version 1.3 - added indication of what linked skills were
#                           - learned of forgotten when changing shards.
#  2013-03-25 - Version 1.2 - added swith to enable/disable Orb Shard menu item
#                           - added message when gaining slots via level up
#  2013-03-24 - Version 1.1 - added indicator line signifying adjacent shards
#  2013-03-24 - Version 1.0 - release
#------------------------------------------------------------------------------#
#  This script adds a system of equipping shards to actors via a new scene.
#  Each shard can give bonuses (just like equipping normal equips) and can also
#  allow actors to use different skills depending on which shards are placed
#  touching each other.
#------------------------------------------------------------------------------#

#------------------------------------------------------------------------------#
#  INFORMATION
#------------------------------------------------------------------------------#
#  TYPES OF SHARDS
#  You can make items, armors or weapons into shards.
#
#  Armors and Weapons as shards:
#  If you use armors and weapons for a shard, it will display in either the item
#  OR key item category of the item screen (you set this in the settings below).
#  All the features of the armor/weapon will work when the shard is equipped
#  and only actors with the correct weapon/armor type (and nothing is stopping
#  them from equipping the head/shield/accessory/etc.) can equip them.
#
#  Items as shards:
#  If you use an item as a shard, you can make it be consumable and work just
#  like a normal item as well as be equipped as a shard. Any actor can equip
#  an item shard without restriction but as it is an item, it's features do not
#  effect the actor. There is, however, a note tag below to allow item shards to
#  add skills to the actor and they can still be part of an adjacent shard.
#
#  Adjacent Shards:
#  If shards are equipped touching another shard, it is possible that the actor
#  is granted an additional skill. When you notetag a shard, you give it an id.
#  In the SHARD SETUP, you specify what skill is learned when any two id's are
#  touching each other.
#  An indicator light appears on shards that are adjacent. The first and last
#  shard are counted as adjacent to each other, so this light will be visible
#  on all the locked shards so the player knows.
#------------------------------------------------------------------------------#

#------------------------------------------------------------------------------#
#  SCRIPT CALLS
#------------------------------------------------------------------------------#
#
#  add_shard_level(id,x)  # Adds x amounts of shard slots to actor number id.
#                         # Make id 0 to add shard slots to party leader
#
#  unequip_shards(actor_id)   # Remove all shards from actor
#
#  SceneManager.call(Scene_Shards)   # Manually bring up shard equip screen
#
#------------------------------------------------------------------------------#
#  EXAMPLE SCRIPT CALLS
#
#  add_shard_level(1,4)   # Adds 4 shard slots to actor 1
#------------------------------------------------------------------------------#

#------------------------------------------------------------------------------#
#  Notetag ITEMS, ARMORS or WEAPONS
#------------------------------------------------------------------------------#
#
#  <shard: x>            # x is the shard id to use in SHARD SETUP below.
#
#  <sskills: x,x,x>      # x is the skill ids for the shard to teach the player.
#                        # NOTE, Armors and equips can still use the feature.
#                        # An item can teach skills via this tag.
#
#  <scolor: r,g,b>       # RGB color applied to the shard (RGB can be 0-255).
#                        # Default is 255,255,255 (white)
#
#  <simage: imagename>   # A different image for the shard from /Graphics/Shards
#
#------------------------------------------------------------------------------#

#------------------------------------------------------------------------------#
#  Notetag for CLASS skill acquired on level up list (Classes tab, Skills box)
#------------------------------------------------------------------------------#
#
#  <shard_gain: x,skill?>     # x is how many slots you want the actor to gain
#                             # when the class reaches the level to gain this
#                             # skill. skill? can be true or false. If true,
#                             # the skill is learned as normal. If false, the
#                             # skill isn't learned.
#
#------------------------------------------------------------------------------#
#  This notetag goes in the CLASSES tab in the database in the notes field of
#  skills that you set the actor to learn when he reaches certain levels. It is
#  used for the player to gain slots at that level. EXAMPLE:
#
#  <shard_gain: 2,false>  # Actor gains 2 shard slots and doesn't learn the
#                         # skill selected. (used for if you want to add just
#                         # slots at that level and no skill.
#
#  <shard_gain: 1,true>   # Actor gains 1 shard slot and also the skill.
#------------------------------------------------------------------------------#

($imported ||= {})["Galv_Shards"] = true
module Galv_Shard

#------------------------------------------------------------------------------#
#  SHARD SETUP
#------------------------------------------------------------------------------#
#  This is where you setup the skills learned when placing shards adjacent to
#  each other. NOTE: Your shard id's must be lowest first, higest second
#------------------------------------------------------------------------------#
   SHARDS = { # Don't touch
#------------------------------------------------------------------------------#

#  [shard_id,shard_id] => skill_id,

    [1,2] => 46,     # fire and water = skill 46 (steam)
    [2,3] => 4,      # water and earth = skill 4 (mudslide)
    [2,5] => 13,     # water and healing = skill 13 (healing rain)


#------------------------------------------------------------------------------#
  } # Don't touch
#------------------------------------------------------------------------------#

#------------------------------------------------------------------------------#
#  MORE SETTINGS
#------------------------------------------------------------------------------#

  #-----------#
  #  General  #
  #-----------#
  
  

  HIDE_SHARDS = false   # Hide shards completely from normal inventory screen
                        # true or false
  KEY_ITEMS = false     # If HIDE_SHARDS is false, setting this to true will
                        # display all armor/weapons shards as key items in the
                        # item screen. false will display them as normal items
  
  SKIN = ""     # Use a different windowskin from /Graphics/Shards folder
  FONT_NAME = "Arial"   # Font used in the right orb window only.
  
  ORB_X_OFFSET = 0    # T0 move the orb container left and right
  ORB_Y_OFFSET = 0    # T0 move the orb container up and down
  
  LINKED_COLOR = [0,204,255]  # Colour of light indicating linked shards

  
  #---------#
  #  Vocab  #
  #---------#
  
  LEVEL_NAME = "Orb Level: "  # Text used for level
  EMPTY_SLOT = "Empty Slot"   # Text used in help box for empty slot
  
  ADD_TO_MENU = true          # Add equip shards to menu true or false
  DISABLE_SWITCH = 1          # Disable menu item when switch is ON
  MENU_TEXT = "Orb Shards"    # Text used for menu item
  
  LEVEL_UP_SLOTS = "Shard Slots Gained: "  # Message displayed when gaining 
                                           # shard slots with a level up followed
                                           # by how many were gained. Make this
                                           # = "" if don't want to use it.
  
  #---------#
  #  Sound  #    ["SE_NAME",volume,pitch]
  #---------#
  
  SE_EQUIP = ["Cursor2",90,50]      # SE When equipping a shard
  SE_REMOVE = ["Water1",80,150]     # SE When removing a shard
  SE_CLEAR = ["Darkness7",90,150]   # SE When clearning shards
  

#------------------------------------------------------------------------------#
#  END SETTINGS
#------------------------------------------------------------------------------#

end

module Cache
  def self.shards(filename)
    load_bitmap("Graphics/Shards/", filename)
  end
end # Cache


class Game_Interpreter
  def add_shard_level(actor,amount)
    if actor == 0
      $game_party.leader.add_shard_level(amount)
    elsif actor > 0
      return if $game_actors[actor].nil?
      $game_actors[actor].add_shard_level(amount)
    end
  end
  
  def unequip_shards(actor_id)
    $game_actors[actor_id].shards.each_with_index { |shard,i|
      next if shard == (:blank || nil)
      $game_party.gain_item(shard, 1)
      $game_actors[actor_id].shards[i] = :blank
    }
  end
end # Game_Interpreter

#------------------------------------------------------------------------
if Galv_Shard::ADD_TO_MENU

class Scene_Menu < Scene_MenuBase
  alias galv_shards_sm_create_command_window create_command_window
  def create_command_window
    galv_shards_sm_create_command_window
    @command_window.set_handler(:shards, method(:command_personal))
  end
  
  alias galv_shards_sm_on_personal_ok on_personal_ok
  def on_personal_ok
    if @command_window.current_symbol == :shards
      return SceneManager.call(Scene_Shards)
    end
    galv_shards_sm_on_personal_ok
  end
end # Scene_Menu < Scene_MenuBase


class Window_MenuCommand < Window_Command
  alias galv_shards_wmc_add_main_commands add_main_commands
  def add_main_commands
    galv_shards_wmc_add_main_commands
    add_command(Galv_Shard::MENU_TEXT, :shards,
      !$game_switches[Galv_Shard::DISABLE_SWITCH])
  end
end # Window_MenuCommand < Window_Command

end
#------------------------------------------------------------------------

class Game_Actor < Game_Battler
  attr_accessor :shards
  attr_accessor :shardlinks
  attr_accessor :known_links
  
  alias galv_shards_ga_setup setup
  def setup(actor_id)
    galv_shards_ga_setup(actor_id)
    @shards = []
    @shardlinks = []
    @known_links = []
    @slots_gained = 0
  end
  
  alias galv_shards_ga_feature_objects feature_objects
  def feature_objects
    galv_shards_ga_feature_objects + shard_array
  end
  
  def shard_array
    return [] if !shards
    array = Array.new(shards)
    array.delete(:blank)
    array
  end
  
  alias galv_shards_ga_param_plus param_plus
  def param_plus(param_id)
    galv_shards_ga_param_plus(param_id) + shard_params(param_id)
  end
  
  def shard_params(param_id)
    return 0 if !shards
    result = 0
    shard_array.each { |shard|
      next if shard.is_a?(RPG::Item) || shard.nil?
      result += shard.params[param_id]
    }
    return result
  end
  
  
  alias galv_shards_ga_added_skills added_skills
  def added_skills
    galv_shards_ga_added_skills + shard_item_skills + shard_linked_skills
  end
  
  def shard_item_skills
    return [] if !shards
    sarray = []
    shards.each { |shard|
      next if shard == :blank || shard.nil?
      shard.sskills.each { |skill| sarray << skill } if shard.sskills
    }
    sarray.compact
  end
  
  def shard_linked_skills
    lst = Galv_Shard::SHARDS
    return [] if !shards
    sarray = []
    shards.each_with_index { |s,i|
      nxt = shards[i + 1].nil? ? 0 : i + 1
      next if s == :blank || shards[nxt] == :blank
      check_for = [shards[i].shard,shards[nxt].shard].sort
      sarray << lst[check_for] if lst.keys.include?(check_for)
    }
    sarray.compact
  end
  
  def add_shard_level(amount)
    if (shards.count + amount) > 12
      amount = 12 - shards.count
    end
    amount.times { |i| shards << :blank }
  end
  
  alias galv_shards_ga_level_up level_up
  def level_up
    galv_shards_ga_level_up
    self.class.learnings.each do |learning|
      if learning.note =~ /<shard_gain:[ ](.*),(.*)>/i && learning.level == level
        plus_slots = $1.to_i
        @slots_gained += plus_slots
        add_shard_level(plus_slots)
        forget_skill(learning.skill_id) if $2 == "false"
      end
    end
  end
  
  alias galv_shards_ga_display_level_up display_level_up
  def display_level_up(new_skills)
    galv_shards_ga_display_level_up(new_skills)
    if @slots_gained > 0 && Galv_Shard::LEVEL_UP_SLOTS != ""
      $game_message.add(sprintf(Galv_Shard::LEVEL_UP_SLOTS + @slots_gained.to_s))
      @slots_gained = 0
    end
  end
  
end # Game_Actor < Game_Battler


class Game_BattlerBase
  
  alias galv_shards_gbb_equippable? equippable?
  def equippable?(item)
    return false if item && item.shard
    galv_shards_gbb_equippable?(item)
  end
  
  def shard_equippable?(item)
    return false unless item.is_a?(RPG::EquipItem)
    return false if equip_type_sealed?(item.etype_id)
    return equip_wtype_ok?(item.wtype_id) if item.is_a?(RPG::Weapon)
    return equip_atype_ok?(item.atype_id) if item.is_a?(RPG::Armor)
    return false
  end
  
  
end

class RPG::BaseItem
  def shard
    if @shard.nil?
      if @note =~ /<shard: (.*)>/i
        @shard = $1.to_i
      else
        @shard = nil
      end
    end
    @shard
  end
  
  def sskills
    if @sskills.nil?
      if @note =~ /<sskills: (.*)>/i
        @sskills = $1.to_s.split(",").map {|i| i.to_i}
      else
        @sskills = nil
      end
    end
    @sskills
  end
  
  def scolor
    if @scolor.nil?
      if @note =~ /<scolor: (.*)>/i
        @scolor = $1.to_s.split(",").map {|i| i.to_i}
      else
        @scolor = [255,255,255]
      end
    end
    @scolor
  end
  
  def simage
    if @simage.nil?
      if @note =~ /<simage: (.*)>/i
        @simage = $1.to_s
      else
        @simage = "shard-equipped"
      end
    end
    @simage
  end
end # RPG::BaseItem


class Window_ItemList < Window_Selectable
  alias galv_shards_wil_include? include?
  def include?(item)
    return false if item && item.shard && Galv_Shard::HIDE_SHARDS
    case @category
    when :item
      if !Galv_Shard::KEY_ITEMS
        return true if item.is_a?(RPG::Weapon) && item.shard
        return true if item.is_a?(RPG::Armor) && item.shard
      end
    when :weapon
      return false if item.is_a?(RPG::Weapon) && item.shard
    when :armor
      return false if item.is_a?(RPG::Armor) && item.shard
    when :key_item
      if Galv_Shard::KEY_ITEMS
        return true if item.is_a?(RPG::Weapon) && item.shard
        return true if item.is_a?(RPG::Armor) && item.shard
      end
    end
    galv_shards_wil_include?(item)
  end
end # Window_ItemList < Window_Selectable


class Window_EquipItem < Window_ItemList
  alias galv_shards_wei_include? include?
  def include?(item)
    return false if item && item.shard
    galv_shards_wei_include?(item)
  end
end # Window_EquipItem < Window_ItemList


#==============================================================================
# ** Scene_Shards
#==============================================================================

class Scene_Shards < Scene_MenuBase
  def start
    super
    create_help_window
    create_command_window
    create_skill_window
    create_orb_window
    create_info_window
    create_item_window
    create_character
  end

  def create_background
    @background_sprite = Sprite.new
    @background_sprite.bitmap = Cache.shards("Background")
    @background_sprite.z = -100
  end

  def create_character
    @character_sprite = OrbCharacter.new(@viewport1,@actor)
  end
  
#--------------------------------------------------------------------------
# * Create Windows
#--------------------------------------------------------------------------
  def create_help_window
    @help_window = Window_OrbHelp.new
    @help_window.viewport = @viewport
  end
  
  def create_command_window
    wy = @help_window.height
    ww = Graphics.width - 330
    @command_window = Window_OrbCommand.new(0, wy, ww)
    @command_window.viewport = @viewport
    @command_window.help_window = @help_window
    @command_window.set_handler(:equip,    method(:command_equip))
    @command_window.set_handler(:remove,    method(:command_remove))
    @command_window.set_handler(:cancel,   method(:return_scene))
    @command_window.set_handler(:pagedown, method(:next_actor))
    @command_window.set_handler(:pageup,   method(:prev_actor))
  end
  
  def create_skill_window
    wy = @help_window.height
    ww = @command_window.width
    wh = Graphics.height - @help_window.height
    @skill_window = Window_OrbSkillList.new(0, wy, ww, wh)
    @skill_window.actor = @actor
    @skill_window.viewport = @viewport
    @skill_window.help_window = @help_window
    @skill_window.set_handler(:ok,       method(:on_skill_ok))
    @skill_window.set_handler(:cancel,   method(:on_skill_cancel))
    @skill_window.z = 900
    @skill_window.visible = false
  end

  def create_orb_window
    wx = @command_window.width
    wy = @help_window.height
    ww = Graphics.width - @command_window.width
    wh = Graphics.height - @help_window.height
    @orb_window = Window_Orb.new(wx, wy, ww, wh)
    @orb_window.viewport = @viewport
    @orb_window.actor = @actor
    @orb_window.help_window = @help_window
    @orb_window.set_handler(:ok,       method(:on_orb_ok))
    @orb_window.set_handler(:cancel,   method(:on_orb_cancel))
  end

  def create_info_window
    @info_window = Window_Info.new(@command_window.width)
    @info_window.viewport = @viewport
  end

  def create_item_window
    wy = @command_window.height + @help_window.height
    ww = @command_window.width
    wh = Graphics.height - wy - @info_window.height
    @item_window = Window_OrbItems.new(0, wy, ww, wh)
    @item_window.viewport = @viewport
    @item_window.help_window = @help_window
    @item_window.actor = @actor
    @item_window.set_handler(:ok,     method(:on_item_ok))
    @item_window.set_handler(:cancel, method(:on_item_cancel))
    @item_window.refresh
  end

#--------------------------------------------------------------------------
# * Command Handlers
#--------------------------------------------------------------------------
  def command_equip
    @info_window.clear
    @item_window.activate
    @item_window.select(0)
  end

  def command_remove
    @info_window.clear
    @orb_window.activate
    @orb_window.select(@orb_window.last_index)
  end
  
  def on_skill_ok
    @skill_window.activate
  end
  def on_skill_cancel
    @skill_window.deactivate
    @skill_window.visible = false
    if @item_window.index >= 0
      @item_window.activate
    else
      @command_window.activate
    end
  end

  def on_orb_ok
    case @command_window.current_symbol
    when :equip
      # Do equip
      equip_shard
    when :remove
      # Do Remove
      remove_shard
      @orb_window.activate
    end
  end

  def on_orb_cancel
    case @command_window.current_symbol
    when :equip
      @orb_window.unselect
      @item_window.activate
    when :remove
      @info_window.clear
      @orb_window.unselect
      @command_window.activate
    end
  end

  def on_item_ok
    @info_window.clear
    if !@item_window.item.nil?
      @orb_window.activate
      @orb_window.select(@orb_window.last_index)
    else
      @item_window.activate
    end
  end

  def on_item_cancel
    @info_window.clear
    @item_window.unselect
    @command_window.activate
  end

  def on_actor_change
    @info_window.clear
    @orb_window.select_none
    @item_window.actor = @actor
    @orb_window.actor = @actor
    @character_sprite.character = @actor
    @skill_window.refresh
    @command_window.activate
  end

#--------------------------------------------------------------------------
# * Shard Stuff
#--------------------------------------------------------------------------
  def remove_shard
    return Sound.play_buzzer if @orb_window.item.nil? || @orb_window.item == :blank
    se = Galv_Shard::SE_REMOVE
    RPG::SE.new(se[0],se[1],se[2]).play
    $game_party.gain_item(@orb_window.item, 1)
    @actor.shards[@orb_window.index] = :blank
    @orb_window.refresh
    @item_window.refresh
    
    do_shard_change
  end
  
  def clear_all
    @info_window.clear
    @help_window.set_item(nil) if @skill_window.active
    @actor.shards.each_with_index { |shard,i|
      next if shard.nil? || shard == :blank
      $game_party.gain_item(shard,1)
      @actor.shards[i] = :blank
    }
    se = Galv_Shard::SE_CLEAR
    RPG::SE.new(se[0],se[1],se[2]).play
    @orb_window.refresh
    @item_window.refresh
  end
  
  def equip_shard
    se = Galv_Shard::SE_EQUIP
    RPG::SE.new(se[0],se[1],se[2]).play
    temp_item = @item_window.item
    if @orb_window.item != :blank
      $game_party.gain_item(@orb_window.item,1)
    end
    @actor.shards[@orb_window.index] = @item_window.item
    $game_party.lose_item(@item_window.item, 1)
    @orb_window.refresh
    @item_window.refresh
    @item_window.activate
    @orb_window.unselect
    do_shard_change
  end

  def do_shard_change
    learned = @actor.shard_linked_skills - @actor.known_links
    forgot = @actor.known_links - @actor.shard_linked_skills
    learn_usable = []
    forgot_usable = []
    learned.each { |sid|
      if @actor.added_skill_types.include?($data_skills[sid].stype_id)
        learn_usable << sid
      end
    }
    forgot.each { |sid|
      if @actor.added_skill_types.include?($data_skills[sid].stype_id)
        forgot_usable << sid
      end
    }
    
    @info_window.display(learn_usable,forgot_usable)
    @actor.known_links = @actor.shard_linked_skills
  end
#--------------------------------------------------------------------------
# * Other Stuff
#--------------------------------------------------------------------------
  def update
    super
    update_animations
    update_key_press
    update_info
  end

  def update_animations
    @character_sprite.character = @actor
    @character_sprite.update
  end
  
  def update_info
    if @orb_window.active
      @orb_window.orb_keys.opacity = 100
    else
      @orb_window.orb_keys.opacity = 255
    end
  end
  
  def update_key_press
    if Input.trigger?(:X) && !@orb_window.active
      clear_all
      @skill_window.refresh
    elsif Input.trigger?(:Y) && !@orb_window.active
      if @skill_window.active
        Sound.play_cancel
        @skill_window.deactivate
        @skill_window.visible = false
        if @item_window.index >= 0
          @item_window.activate
        else
          @command_window.activate
        end
      else
        Sound.play_ok
        @command_window.deactivate
        @item_window.deactivate
        @skill_window.activate
        @skill_window.select(0)
        @skill_window.actor = @actor
        @skill_window.visible = true
        @skill_window.refresh
        @help_window.set_item(@skill_window.item)
      end
    end
  end

  def terminate
    super
    dispose_orb_graphics
  end
  
  def dispose_orb_graphics
    @character_sprite.dispose
  end
end


#==============================================================================
# ** Windows and whatsis
#==============================================================================

class Window_OrbCommand < Window_HorzCommand
  def initialize(x, y, width)
    @window_width = width
    super(x, y)
    self.windowskin = Cache.shards(Galv_Shard::SKIN) if Galv_Shard::SKIN != ""
  end
  
  def window_width
    @window_width
  end
  
  def col_max
    return 2
  end

  def make_command_list
    add_command("Equip",   :equip)
    add_command("Remove", :remove)
  end
end # Window_OrbCommand < Window_HorzCommand


class Window_OrbHelp < Window_Help
  def initialize
    super
  end
  
  def set_item(item)
    return set_text("") if item.nil?
    if item == :blank
      set_text("Empty Slot")
    else
      set_text(item ? item.description : "")
    end
  end
end # Window_OrbHelp < Window_Help


class Window_Info < Window_Base
  def initialize(width)
    super(0, Graphics.height - fitting_height(2), width, fitting_height(2))
    self.windowskin = Cache.shards(Galv_Shard::SKIN) if Galv_Shard::SKIN != ""
    @learned ||= []
    @forgot ||= []
  end
  
  def refresh
    contents.clear
    draw_skills
  end
  
  def clear
    contents.clear
  end
  
  def display(learned,forgot)
    @learned = learned
    @forgot = forgot
    refresh
  end
  
  def draw_skills
    ind = 0
    w = contents.width
    x = 0
    h = line_height
    
    change_color(Color.new(197,255,202,255))
    @learned.uniq.each { |skill|
      sk = $data_skills[skill]
      draw_text(0,h * ind,w,h,"+" + sk.name,1)
      ind += 1
    }
    
    change_color(Color.new(255,197,197,255))
    @forgot.uniq.each { |skill|
      sk = $data_skills[skill]
      draw_text(0,h * ind,w,h,"-" + sk.name,1)
      ind += 1
    }
    change_color(normal_color)
  end
end # Window_Info < Window_Base


class Window_Orb < Window_Selectable
  attr_accessor :last_index
  attr_reader :item
  attr_accessor :orb_keys
  
  def initialize(x, y, width, height)
    create_graphics
    @last_index = 0
    super(x, y, width, height)
    self.opacity = 0
    @actor = nil
  end
  
  def create_graphics
    @shard_images = []
    @shards_active = []
    create_orb_back
    create_orb_front
    create_orb_numbers
    create_key_info
    create_cursor
  end
  
  def select_none
    index = -1
    @cursor.index = index
    @last_index = 0
    @cursor.angle = 285
  end
  
  def create_orb_back
    @orb_back = Sprite.new
    @orb_back.bitmap = Cache.shards("OrbBack")
    @orb_back.z = -50
    @orb_back.x = Graphics.width - @orb_back.bitmap.width + Galv_Shard::ORB_X_OFFSET
    @orb_back.y = 95 + Galv_Shard::ORB_Y_OFFSET
  end
  
  def create_orb_front
    @orb_front = Sprite.new
    @orb_front.bitmap = Cache.shards("OrbFront")
    @orb_front.z = 500
    @orb_front.x = @orb_back.x
    @orb_front.y = @orb_back.y
  end
  
  def create_orb_numbers
    @orb_nums = Sprite.new
    @orb_nums.bitmap = Cache.shards("OrbNumbers")
    @orb_nums.z = @orb_front.z + 50
    @orb_nums.x = @orb_back.x
    @orb_nums.y = @orb_back.y
  end
  
  def create_key_info
    @orb_keys = Sprite.new
    @orb_keys.bitmap = Cache.shards("keys")
    @orb_keys.z = @orb_front.z + 50
    @orb_keys.x = Graphics.width - @orb_keys.bitmap.width - 10 
    @orb_keys.y = 375 + Galv_Shard::ORB_Y_OFFSET
  end
  
  def create_cursor
    @cursor = Sprite_Cursor.new
    @cursor.x = @orb_back.x + @orb_back.bitmap.width / 2
    @cursor.y = @orb_back.y + @orb_back.bitmap.height / 2
    @cursor.opacity = 0
    @cursor.angle = 285
    @cursor.z = 450
  end
 
  def update
    super
    @cursor.index = index
    @last_index = index if index >= 0
    @cursor.update
  end

  def actor=(actor)
    return if @actor == actor
    @actor = actor
    refresh
  end
  
  def refresh
    contents.clear
    dispose_shards
    create_shards
    create_text
  end
  
  def create_text
    return if @actor.nil?
    contents.font.size = 22
    change_color(text_color(15))
    contents.font.out_color = text_color(0)
    contents.font.bold = true
    contents.font.name = Galv_Shard::FONT_NAME
    draw_text(0, 0, contents.width, line_height, @actor.name)
    draw_text(0, 0, contents.width - 30, line_height, Galv_Shard::LEVEL_NAME,2)
    change_color(text_color(9))
    draw_text(0, 0, contents.width, line_height, @actor.shards.count,2)
  end
  
  def create_shards
    12.times { |i| draw_item(i) }
  end
  
  def draw_item(ind)
    shard = @actor.shards[ind] if @actor.shards[ind]
    sx = @cursor.x
    sy = @cursor.y
    return if shard == :blank
    @shard_images[ind] = Sprite_Shard.new(@viewport,ind,shard,sx,sy)
    if item_linked(ind) && !@actor.shards.empty?
      @shards_active[ind] = Sprite_Shard.new(@viewport,ind,:active,sx,sy)
    end
    draw_shard_icon(shard,ind)
  end
  
  def draw_shard_icon(shard,ind)
    center_x = contents.width - @orb_back.bitmap.width / 2 + Galv_Shard::ORB_X_OFFSET
    center_y = 160 + Galv_Shard::ORB_Y_OFFSET
    round_x = center_x + Math::cos((@shard_images[ind].angle - 90) / -57) * 100
    round_y = center_y + Math::sin((@shard_images[ind].angle - 90) / -57) * 100
    return if shard.nil?
    draw_icon(shard.icon_index,round_x,round_y,true)
  end
  
  def dispose_shards
    @shard_images.each { |s| s.dispose if s }
    @shard_images = []
    @shards_active.each { |s| s.dispose if s }
    @shards_active = []
  end
  
  def item_linked(ind)
    sh = @actor.shards
    return false if sh[ind] == :blank
    if sh[ind].nil?
      if sh.first != :blank && sh.last != :blank
        return true
      else
        return false
      end
    end

    case ind
    when 0
      return true if sh.last != :blank || sh[ind+1] != :blank
    when (sh.count-1)
      return true if sh.first != :blank || sh[ind-1] != :blank
    else
      return true if sh[ind+1] != :blank || sh[ind-1] != :blank
    end
    false
  end

  def item
    @actor ? @actor.shards[index] : nil
  end
  
  def item_max
    return 0 if @actor.nil?
    @actor.shards.count
  end

  def activate
    super
    @cursor.opacity = 100
  end
  
  def deactivate
    super
    @cursor.opacity = 0
  end
  
  def update_help
    super
    @help_window.set_item(item) if @help_window
  end
  
  def dispose
    @orb_back.bitmap.dispose
    @orb_front.bitmap.dispose
    @orb_nums.bitmap.dispose
    @orb_keys.bitmap.dispose
    @cursor.bitmap.dispose
    dispose_shards
    super
  end

  def update_cursor
    if @cursor_all
      cursor_rect.empty
      self.top_row = 0
    elsif @index < 0
      cursor_rect.empty
    else
      ensure_cursor_visible
      cursor_rect.empty
    end
  end
  
  def process_ok
    if current_item_enabled?
      Input.update
      deactivate
      call_ok_handler
    else
      Sound.play_buzzer
    end
  end
  
  def cursor_right(wrap = false)
    cursor_up
  end

  def cursor_left(wrap = false)
    cursor_down
  end
    
  def cursor_down(wrap = false)
    if index >= col_max || index == @actor.shards.count - 1 || index == 0
      select((index - col_max + item_max) % item_max)
    end
  end
  def cursor_up(wrap = false)
    if index < item_max - col_max || index == @actor.shards.count - 1 || index == 0
      select((index + col_max) % item_max)
    end
  end
end # Window_Orb < Window_Selectable


class Window_OrbItems < Window_ItemList
  def initialize(x, y, width, height)
    super
    self.windowskin = Cache.shards(Galv_Shard::SKIN) if Galv_Shard::SKIN != ""
  end

  def col_max
    return 1
  end
  
  def include?(item)
    return false if item.nil?
    return true if item == :blank
    return true if @actor.shard_equippable?(item) && item.shard
    return true if item.is_a?(RPG::Item) && item.shard
  end

  def refresh
    super
  end
  
  def enable?(item)
    return false if item.nil?
    return false if @actor.shards.empty?
    true
  end
  
  def actor=(actor)
    return if @actor == actor
    @actor = actor
    refresh
    self.oy = 0
  end
end # Window_OrbItems < Window_ItemList


class Window_OrbSkillList < Window_SkillList
  def initialize(x, y, width, height)
    super
    @actor = nil
    @data = []
    self.back_opacity = 255
  end

  def col_max
    return 1
  end
  
  def update; super; end
  def refresh; super; end

  def current_item_enabled?
    false
  end
  
  def include?(item)
    return false if item.nil?
    return false if !@actor.added_skill_types.include?(item.stype_id)
    item
  end

  def enable?(item)
    true
  end
end # Window_OrbSkillList < Window_SkillList


#==============================================================================
# ** Sprites and Things
#==============================================================================

class OrbCharacter < Sprite_Base
  attr_accessor :character
  def initialize(viewport, character = nil)
    @pattern = 1
    @step_speed = 20
    @step = true
    @character = character
    super(viewport)
    update
  end
  
  def set_character_bitmap
    self.bitmap = Cache.character(@character_name)
    sign = @character_name[/^[\!\$]./]
    if sign && sign.include?('$')
      @cw = bitmap.width / 3
      @ch = bitmap.height / 4
    else
      @cw = bitmap.width / 12
      @ch = bitmap.height / 8
    end
    self.ox = @cw / 2
    self.oy = @ch
    self.x = Graphics.width - 300
    self.y = 150
    self.z = 500
  end
  
  def update_src_rect
    index = @character.character_index
    sx = (index % 4 * 3 + @pattern) * @cw
    sy = (index / 4 * 4 + (2 - 2) / 2) * @ch
    self.src_rect.set(sx, sy, @cw, @ch)
  end

  def update_bitmap
    if graphic_changed?
      @character_name = @character.character_name
      @character_index = @character.character_index
      set_character_bitmap
    end
  end

  def graphic_changed?
    @character_name != @character.character_name ||
    @character_index != @character.character_index
  end  
  def update
    super
    update_bitmap
    update_src_rect
    update_animation
  end
  
  def update_animation
    @step_speed -= 1
    if @step_speed <= 0
      if @step
        if @pattern < 2 
          @pattern += 1 
        else 
          @pattern = 1
          @step ^= true
        end
      else
        if @pattern > 0 
          @pattern -= 1 
        else 
          @pattern = 1
          @step ^= true
        end
      end
      @step_speed = 20
    end
  end
  
  def dispose
    super
    self.bitmap.dispose
  end
end # OrbCharacter < Sprite_Base


class Sprite_Cursor < Sprite_Base
  attr_accessor :index
  
  def initialize
    super
    @index = 0
    create_graphic
    @fade = 0  # 0 in, 1 out
  end
  
  def create_graphic
    self.bitmap = Cache.shards("shard-cursor")
    self.ox = self.bitmap.width / 2
  end
  
  def update
    super
    update_position
    update_blink if @index >= 0
  end
  
  def update_position
    return if index < 0
    self.angle = 285 - index * 30
  end
  
  def update_blink
    if @fade == 0
      self.opacity += 3
      @fade = 1 if self.opacity >= 150
    else
      self.opacity -= 3
      @fade = 0 if self.opacity <= 80
    end
  end
  
  def dispose; super; end
end # Sprite_Cursor < Sprite_Base
  
  
class Sprite_Shard < Sprite_Base
  def initialize(viewport,index,item,sx,sy)
    @index = index
    @item = item
    super(viewport)
    create_graphic
    self.x = sx
    self.y = sy
  end
  
  def create_graphic
    if @item == :active
      self.bitmap = Cache.shards("linked-light")
      c = Galv_Shard::LINKED_COLOR
      self.color = Color.new(c[0],c[1],c[2],160)
    elsif @item.nil?
      self.bitmap = Cache.shards("shard-locked")
    else
      self.bitmap = Cache.shards(@item.simage)
      c = @item.scolor
      self.color = Color.new(c[0],c[1],c[2],160)
    end
    self.ox = self.bitmap.width / 2
    self.angle = 285 - @index * 30      
    self.z = -20
  end
  
  def update
    super
  end
  
  def dispose; super; end
end # Sprite_Shard < Sprite_Base
Advertisements

40 thoughts on “Galv’s Magic Shards V.1.8

  1. Legault says:

    Awesome script! Thank you very much :D

  2. ZippeyKeys says:

    It doesn’t work for me it says:
    Script ‘Galv’s Magic Shards’ line 899: NoMethodError occurred.
    undefined method `[]’ for nil:NilClass
    Which is
    shard = @actor.shards[ind] if @actor.shards[ind]

  3. Nio kasgami says:

    Hello Galv’s I really Love your work! and I use you shard System for my game..is really what i wanted!

    But for the link colors….you think you can add a new feature?

    Like the possibility to have more color for specific thing…like if the character where a ”Stone” permit to only have Fire Shard the color link has read….but if you change for (in your equipement ) for a stone permit to only have Water shard the color link become Blue ….
    Is was a idea i thinked is great because is had..somme dynamic in game!

    I thank you if you can add this :3!

    • Galv says:

      Sounds like a good idea but I’m sorry I am making no changes to this script currently. Too many people have offered suggestions to make it different and I cannot do them all.

  4. niokasgami says:

    Okai is correct don’t apogalise :3….

    BUt i have question because i want to do my own graphic for the shard system …but i think i need to do some adjustement in the script for make my graphic compatible?

    (because the ”shard ” is not triangular is a simple stone you enchance in a hole and the link light whas more high)

    (don’t worry i have some knowledge for programming and i also do my own script poste on rpgmaker :3 (but i am still a begginer so the script are not really sensationnal and is in construction)

    So is all i ask :3….have a good days :3!

    • Galv says:

      I don’t understand what you would like to do. Changing the shape of the shard would be a fairly big job getting the angles in the circle right

  5. Galv, in the Demo the Water Shard doesn’t show up, why?

  6. Legault says:

    Galv I think I found a bug ! My game was running very well until I made my character have 3 weapon, when I tried to change wapons, the game crashed and took me to this script line 436, I don’t think it’s a compatibility issue as your script works really well. I already have versiĆ³n 1.7 so I don’t know what could be wrong. Hope you check this out.

  7. Legault says:

    Two weapons or 1 weapon equipped and one weapon in your inventory. Then I press Change my equiped weapon and the game crashes x.x

    • Galv says:

      I cannot duplicate this crash or see why it would crash on that line. Can you please try to do exactly what you did using this script’s demo?
      If you cannot duplicate the crash in the demo I suspect it is a script conflict and you might have to do some tests to find which one is conflicting

  8. Legault says:

    Well I couldn’t replicate the error in the demo, here’s an image of the error :

    Thank you for your answers and quick help.

  9. Ke says:

    Is there a way to add something like tiers? for example: I have hero who can only have 1 tier III shard, 3 tier II shards and 4 tier I shards.

  10. ben says:

    is there a way to make this compatible with moghunters cursor?

  11. Jikaran says:

    Is there a possibility to link more than just two shards?
    So that you can link three shards to get a skill and if the shards have a link between just two
    this skill also will be learned?

  12. SlaveOfThaMind says:

    Curious if there is a way to add this system into Mog’s Monogatari Menu? I’ve tried everything to my knowledge and still await any help via the forums.

    • Galv says:

      I have not used Mog’s script so I’m sorry I cannot help you there

      • SlaveOfThaMind says:

        Oh alright, that’s fine I’ll keep at it until it works, I need this system for my game! Thank you anyway Galv and for your timely reply to my inquiry!

  13. minegabriel12 says:

    Where can i find the demo folder?

    • Galv says:

      What do you mean the demo folder? You can download the demo using the link at the top of this page under the heading “Demo”. I can’t help you find where you download it to on your computer

  14. Adam says:

    Hello.
    I have small “problem” with this script:
    Knight class can use type A shards.
    Mage class can use type B shards.

    Hero is Knight so he can equip type A shards. But when he change class to Mage he still have type A shards equipped.
    It there a way to automatic unequip shards after class change?

    • Galv says:

      You will need to modify the class change script you are using to do that. This script has a script call to remove all shards : unequip_shards(actor_id)

  15. Discovery says:

    So, I think I got a bug, I dont know if its Compatibility or a script bug…I’m using your menu script and the shards script, I had to do a “Scene_Shards” add to the menu script, not a problem worked fine, it opens the window of the shards and work really well… But when I close the window the image of the shard place are still there, is there a way to make it work?

  16. Eduardp says:

    Hey there Galv, I would like to know if there is a way to acess the shard equiping without entering the menu for this? My game have no menus but I would like to use shards.

  17. Galv says:

    Hey, I just had a look to remind myself and unfortunately how it was written there is no easy way to do it out of the menu. I’d have to write in a way for you. I don’t know when I can get to do this, though

  18. Amyrakunejo says:

    I must say that this is a very interesting gameplay concept. I actually wonder if it is possible to increase the amount of slots (or decrease them), depending on actor class, equipment, etcetera?

    Like, my Knight is next to useless with magic and has a six shard capacity, how could that be implemented to where he only has six available slots (I mean visibly not just have six of twelve perma-locked slots).

    Or if my Great Mage is thoroughly proficient with magic, and has a maximum of twenty-four slots…if she has her best weapon and specific armor equipped?

    • Galv says:

      Unfortunately the Ace version doesn’t do anything like that. I have moved on to MV which can have as many slots as required and not just lock certain slots

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s