KSkillTypes XP

kyonides

Veteran
Veteran
Joined
Nov 17, 2019
Messages
127
Reaction score
27
First Language
English
Primarily Uses
RMXP
KSkillTypes XP

by Kyonides Arkanthes


Introduction

The following script is an overhaul of the skill menu. It is intended to show the same information the original provided plus a couple of details like skill power and a battler to test the skill on it! That battler even changes if the skill is cast to help allies or hurt your foes!

I do NOT expect it to be compatible with other skill menus!


Yeah! The resources are highly customizable! Just check out the KSkillTypes module section to find out how you can change it!

The Script
Code:
# * KSkillTypes XP Hit Version
#   Scripter : Kyonides Arkanthes
#   v1.0.2 - 2019-11-27

# This scriptlet allows the player to see the skill menu in a different way.
# He or she will retrieve the usual information AND watch a skill animation
# hitting a hero or monster after they have picked a category and chosen any
# skill available there.

# You are in need of creating extra elements in the System tab.

module KSkillTypes
  BACKDROP = 'magical place' # Placed in Graphics/Titles
  TITLE_STRIPE_BACKDROP = 'strip'
  TEST_BATTLER_ID = 1 # Enemy ID to use as the skill target
  TEST_BATTLER_Y = 216 # Y Coordinate of the Test Battler getting hit
  SKILL_MENU_INDEX = 1 # Position of option that opens Skill Menu minus 1
  FIRST_ID = 17 # First Element ID used as a category tag
  # Icon & Picture Filenames
  ICONS = ['gem citrinus', 'physical', 'gem pale', 'gem dark',
    'gem ruby', 'gem emerald']
  DESCRIPTIONS = [ # 1 for each extra Element
    'Select a category',
    'Strength is the way of the fighter!',
    'Because health does matter!',
    'Patience is just for fools!',
    'Blood is a valuable resouce!',
    'Nature is your friend!'
  ]
  SCOPES = [ # 1 for each Skill Scope
    'Nobody',
    'Single Enemy',
    'All Enemies',
    'One Ally',
    'All Allies',
    'Dead Ally',
    'Dead Allies',
    'User Only'
  ]
  ALLY_SCOPES = [3,4,5,6,7]
  NO_STATE = "Normal"
  LABELS = {} # Ignore this line!
  LABELS[:title] = 'Skill Data'
  LABELS[:no_skill] = 'No data was found!'
  LABELS[:cost] = 'Mana'
  LABELS[:power] = 'Power'
  LABELS[:scope] = 'Scope'
  # End of Configuration #
  class << self
    def label() @elements[@index] end
    def type_id() FIRST_ID + @index end
    def description() DESCRIPTIONS[@index] end
    def get_scope(skill_scope) SCOPES[skill_scope] end
    attr_accessor :index
  end
  @elements = load_data('Data/System.rxdata').elements[FIRST_ID..-1]
  @index = 0
end

unless $HIDDENCHEST

module Graphics
  def self.width() 640 end
  def self.height() 480 end
end

end

class Window_Help
  def initialize
    super(0, 0, Graphics.width, 64)
    self.contents = Bitmap.new(width - 32, height - 32)
  end
end

class Window_Skill
  def initialize(actor)
    if (in_battle = $game_temp.in_battle)
      ny = 64
      nh = 256
    else
      ny = 96
      nh = Graphics.height - ny
    end
    super(0, ny, 220, nh)
    @data = []
    @actor = actor
    skills = @actor.skills
    skills.each{|n| @data << $data_skills[n] }
    @general_data = @data.dup
    refresh
    self.index = 0
    self.back_opacity = in_battle ? 160 : 0
    self.opacity = 0 unless in_battle
  end

  def no_contents!
    return unless self.contents
    self.contents.dispose
    self.contents = nil
  end

  def refresh
    no_contents!
    @data = @general_data
    if KSkillTypes.index > 0
      tid = KSkillTypes.type_id
      @data = @data.select{|s| s.element_set.include?(tid) }
    end
    @item_max = @data.size
    return if @item_max == 0
    self.contents = Bitmap.new(width - 32, row_max * 32)
    @bitmap = self.contents
    @item_max.times{|i| draw_item(i) }
  end

  def draw_item(index)
    skill = @data[index]
    can_use =  @actor.skill_can_use?(skill.id)
    @bitmap.font.color = can_use ? normal_color : disabled_color
    by = index * 32
    rect = Rect.new(4, by, self.width / @column_max - 32, 32)
    @bitmap.fill_rect(rect, Color.new(0, 0, 0, 0))
    bitmap = RPG::Cache.icon(skill.icon_name)
    @bitmap.blt(4, by + 4, bitmap, Rect.new(0, 0, 24, 24), can_use ? 255 : 128)
    @bitmap.draw_text(32, by, 204, 32, skill.name, 0)
  end
  def item_id() @data[@index] ? @data[@index].id : nil end
end

class KSpriteset
  def basic_setup(nx, ny)
    @x = nx
    @y = ny
    @sprites = []
  end

  def dispose
    @sprites.each{|s| s.dispose }
    @sprites.clear
  end
  attr_reader :x, :y
end

class KIconSpriteset < KSpriteset
  def initialize(nx, ny, pictures)
    basic_setup(nx, ny)
    @pictures = []
    @icons = []
    @index = 0
    @max = pictures.size
    @max.times do |n|
      bit = RPG::Cache.picture(pictures[n])
      @pictures << sprite = Sprite.new
      h = bit.height
      w1 = bit.width
      this_x = @x - n * 6 + n * w1
      sprite.visible = false
      sprite.x = this_x
      sprite.y = @y
      sprite.bitmap = bit
      @icons << sprite = Sprite.new
      sprite.x = this_x + w1 / 2 - 12
      sprite.y = @y + h / 2 - 12
      sprite.bitmap = RPG::Cache.icon(pictures[n])
    end
    pic = @pictures[-1]
    @margin_right = pic.x + pic.bitmap.width
    update_cursor
    @sprites = @pictures + @icons
  end

  def update
    if Input.trigger?(Input::LEFT)
      update_icon
      @index = (@index - 1) % @max
      update_cursor
    elsif Input.trigger?(Input::RIGHT)
      update_icon
      @index = (@index + 1) % @max
      update_cursor
    end
  end

  def update_icon
    @pictures[@index].visible = false
    @icons[@index].visible = true
  end

  def update_cursor
    @pictures[@index].visible = true
    @icons[@index].visible = false
  end

  def dispose
    super
    @pictures.clear
    @icons.clear
  end
  attr_reader :index, :margin_right
end

class KLabelSpriteset < KSpriteset
  def initialize(nx, ny, nh, picture=nil)
    basic_setup(nx, ny)
    @offset_x = 0
    @width = Graphics.width - nx
    @height = nh
    @sprites << @backdrop = Sprite.new
    @backdrop.x = nx
    @backdrop.y = ny
    picture = '' unless picture
    @backdrop.bitmap = RPG::Cache.picture(picture)
    @backdrop.src_rect.set(0, 0, @width, @height)
    @sprites << @title = Sprite.new
    @title.x = nx
    @title.y = ny
    @title.bitmap = Bitmap.new(@width, @height)
    @font_size = @height - 8
    @white = Color.new(255, 255, 255)
    @red = Color.new(255, 64, 0)
    @yellow = Color.new(255, 255, 64)
  end

  def character=(new_char)
    @character = new_char
    refresh
  end

  def refresh
    set_label(8, 2, @width / 4, @character.name)
    font = @title.bitmap.font
    @states = @character.states
    text = @states.empty? ? KSkillTypes::NO_STATE : retrieve_state_name
    font.color = @red if @dead
    set_label(120, 2, 120, text)
    font.color = @yellow if (fourth = @character.hp <= @character.maxhp / 4)
    font.color = @white unless @dead or fourth
    hpx = 132 + @title.bitmap.text_size(text).width
    terms = $data_system.words
    set_label(hpx, 2, 32, terms.hp, 2)
    hpx += 36
    set_label(hpx, 2, 64, @character.hp.to_s, 2)
    set_label(hpx + 64, 2, 64, '/' + @character.maxhp.to_s)
    font.color = @white
    set_label(hpx + 132, 2, 32, terms.sp, 2)
    hpx += 168
    set_label(hpx, 2, 64, @character.sp.to_s, 2)
    set_label(hpx + 64, 2, 64, '/' + @character.maxsp.to_s)
  end

  def retrieve_state_name
    return "Knockout" if (@dead = @character.hp == 0)
    ratings = @states.map{|n| $data_states[n].rating }
    pos = ratings.index(ratings.max)
    $data_states[@states[pos]].name
  end

  def set_label(x, y, w, label, align=0)
    @title.bitmap.draw_text(x, y, w, @font_size, label, align)
  end

  def set_title(title, align=1)
    by = @height / 2 - @font_size / 2
    b = @title.bitmap
    b.clear
    b.font.size = @font_size
    b.draw_text(@offset_x, by, @width - @offset_x, @font_size, title, align)
  end
  def clear_text() @title.bitmap.clear end
  alias :set_text :set_title
  attr_reader :width, :height
  attr_writer :skill_window, :font_size, :offset_x
end

class KSkillStats < Sprite
  def initialize(w, h, new_skill)
    @skill_id = new_skill
    super(nil)
    self.bitmap = Bitmap.new(w, h)
    @white = Color.new(255, 255, 255)
    @black = Color.new(0, 0, 0)
    @dy = 38
    refresh
  end

  def skill_id=(new_id)
    @skill_id = new_id
    refresh
  end

  def refresh
    labels = KSkillTypes::LABELS
    bit = self.bitmap
    bit.clear
    bit.font.size = 26
    bit.draw_text(0, 0, bit.width, 26, labels[:title], 1)
    rect = Rect.new(8, 30, bit.width - 16, 4)
    bit.fill_rect(rect, @black)
    rect = Rect.new(9, 31, bit.width - 16, 2)
    bit.fill_rect(rect, @white)
    bit.font.size = 22
    return clear_no_skill unless @skill_id
    skill = $data_skills[@skill_id]
    bit.draw_text(0, @dy, 100, 24, labels[:cost])
    bit.draw_text(100, @dy, 96, 24, skill.sp_cost.to_s, 2)
    bit.draw_text(208, @dy, 100, 24, labels[:power])
    bit.draw_text(308, @dy, 96, 24, skill.power.to_s, 2)
    bit.draw_text(0, @dy + 26, 80, 24, labels[:scope])
    bit.draw_text(84, @dy + 26, 112, 24, KSkillTypes.get_scope(skill.scope), 2)
  end

  def clear_no_skill
    text = KSkillTypes::LABELS[:no_skill]
    bitmap.draw_text(0, @dy, bitmap.width, 24, text, 1)
  end
end

class Scene_Skill
  alias :kyon_scn_skill_up_skill :update_skill
  def main
    KSkillTypes.index = 0
    backdrop = KSkillTypes::TITLE_STRIPE_BACKDROP
    @start = true
    @actors = $game_party.actors
    @actor = @actors[@actor_index]
    @backdrop = Sprite.new
    @backdrop.y = 96
    @backdrop.bitmap = RPG::Cache.title(KSkillTypes::BACKDROP)
    @backdrop.src_rect.set(0, 0, Graphics.width, Graphics.height - 96)
    @name_sprite = KLabelSpriteset.new(0, 0, 40, backdrop)
    @help_sprite = KLabelSpriteset.new(0, 40, 28, backdrop)
    @help_sprite.font_size = 24
    @help_sprite.set_title(KSkillTypes.description, 1)
    @status_window = KLabelSpriteset.new(0, 68, 28, backdrop)
    @status_window.font_size = 24
    @status_window.character = @actor
    @skill_window = Window_Skill.new(@actor)
    @skill_window.active = false
    @skill_window.help_window = @help_sprite
    @skill_window.index = -1
    @help_sprite.skill_window = @skill_window
    @target_window = Window_Target.new
    @target_window.visible = false
    @target_window.active = false
    @icon_menu = KIconSpriteset.new(8, 4, KSkillTypes::ICONS)
    if @icon_menu.margin_right > Graphics.width / 3
      @name_sprite.offset_x = @icon_menu.margin_right + 12
    end
    @name_sprite.set_title(KSkillTypes.label, 0)
    @data_sprite = KSkillStats.new(408, 100, @actor.skills[0])
    @data_sprite.x = 228
    @data_sprite.y = 100
    @target_sprite = RPG::Sprite.new
    @target_sprite.y = KSkillTypes::TEST_BATTLER_Y
    @test_battler = $data_enemies[KSkillTypes::TEST_BATTLER_ID]
    name = @test_battler.battler_name
    @enemy_bitmap = RPG::Cache.battler(name, @test_battler.battler_hue)
    @actor_bitmap = RPG::Cache.battler(@actor.battler_name, @actor.battler_hue)
    @target_sprite.x = 228
    @target_sprite.opacity = 255
    Graphics.transition
    until $scene != self
      Graphics.update
      Input.update
      update
    end
    Graphics.freeze
    @actor_bitmap.dispose
    @enemy_bitmap.dispose
    @target_sprite.dispose
    @data_sprite.dispose
    @icon_menu.dispose
    @name_sprite.dispose
    @help_sprite.dispose
    @status_window.dispose
    @skill_window.dispose
    @target_window.dispose
    @backdrop.dispose
  end

  def set_target(skill_id)
    @data_sprite.skill_id = skill_id
    return unless skill_id
    skill = $data_skills[skill_id]
    ally_scope = KSkillTypes::ALLY_SCOPES.include?(skill.scope)
    if @last_result != ally_scope
      bitmap = ally_scope ? @actor_bitmap : @enemy_bitmap
      @tsx = 228 + (Graphics.width - 228 - bitmap.width) / 2
      @target_sprite.x = @tsx
      @target_sprite.bitmap = bitmap
      @last_result = ally_scope
    end
    anime = $data_animations[skill.animation2_id]
    @target_sprite.animation(anime, true)
  end

  def update
    @skill_window.update
    @target_window.update
    if @start
      return update_section
    elsif @skill_window.active
      return update_skill
    elsif @target_window.active
      update_target
    end
  end

  def update_section
    @icon_menu.update
    if Input.trigger?(Input::B)
      $game_system.se_play($data_system.cancel_se)
      return $scene = Scene_Menu.new(KSkillTypes::SKILL_MENU_INDEX)
    elsif Input.trigger?(Input::C)
      $game_system.se_play($data_system.decision_se)
      @skill_window.index = 0
      @skill_window.active = true
      set_target(@skill_window.item_id)
      return @start = nil
    elsif Input.trigger?(Input::UP)
      refresh_data
      return
    elsif Input.trigger?(Input::DOWN)
      refresh_data
      return
    elsif Input.trigger?(Input::L)
      $game_system.se_play($data_system.cursor_se)
      pos = (@actor_index - 1) % @actors.size
      $scene = Scene_Skill.new(pos)
      return
    elsif Input.trigger?(Input::R)
      $game_system.se_play($data_system.cursor_se)
      pos = (@actor_index + 1) % @actors.size
      $scene = Scene_Skill.new(pos)
    end
  end

  def refresh_data
    $game_system.se_play($data_system.cursor_se)
    KSkillTypes.index = @icon_menu.index
    @name_sprite.set_title(KSkillTypes.label, 0)
    @help_sprite.set_title(KSkillTypes.description)
    @skill_window.refresh
  end

  def update_skill
    @target_sprite.update
    if Input.trigger?(Input::B)
      $game_system.se_play($data_system.cancel_se)
      @skill_window.index = -1
      @skill_window.active = false
      @help_sprite.set_title(KSkillTypes.description)
      return @start = true
    elsif Input.dir4 > 0
      set_target(@skill_window.item_id)
    end
    kyon_scn_skill_up_skill
  end
end

Terms & Conditions

You must include my nickname in your game credits.
Free for non commercial games or demos.
Include the URL of the website or forum where you found it!
 
Last edited:

Users Who Are Viewing This Thread (Users: 0, Guests: 1)

Latest Threads

Latest Profile Posts

The only upside of this remote semester was the plenty of funny photoshop material those facecams provided. Not that I would do that. Ever.
New skit is up for grid battle system. Less tactics battle engine looking battle systems, more final fantasy/breath of fire looking battle systems.

Dororo wrote on Tsukihime's profile.
For the grid battle system: a function to check if another actor is in a given range - to trigger combo actions or benefit of passive aura/morale ranges.
Uuuh I cannot find any good RPG to play
Gimme some free RPG recommendations plz
I need to consume it
I'm in a need of excitement caused by doing literally nothing on my laptop and then thinking I did something useful and then realising that I didnt and crying internally

Forum statistics

Threads
100,512
Messages
976,666
Members
132,080
Latest member
nwr
Top