Envision, Create, Share

Welcome to HBGames, a leading amateur game development forum and Discord server. All are welcome, and amongst our ranks you will find experts in their field from all aspects of video game design and development.

[VX] Skill Draw

Skill Draw
by Dargor
Version 1.10


Introduction

For those who have played FFVIII, you know what this script does!
First of all, the idea behind the Draw system is to basically 'Steal' skills from a enemy.
The unusual thing is that in FFVIII, you have skill numbers instead of MP. So when you use the Draw command, you steal an amount of skill number (between 1 and 9 depending on your level and the skill).

With my version of this system, you will need both MP and skill number to cast a skill.
You have 2 Draw methods. Stock and Cast.
With 'Stock' you will stock an amount of skill number
With 'Cast' you will cast the selected skill on the enemy

I know, a lot of people hate this system but I don't care about it, I think it's cool! :tongue:

Screenshots


Script

Code:
#==============================================================================

# ** Skill Draw (FFVIII)

#------------------------------------------------------------------------------

#  © Dargor, 2008

#  02/06/08

#  Version 1.10

#------------------------------------------------------------------------------

#  VERSION HISTORY:

#   - 1.0 (11/05/08), Initial release

#   - 1.1 (14/05/08), Bug fixed with consuming skill number

#   - 1.2 (14/05/08), Bug fixed with initial skill number

#   - 1.3 (18/05/08), Another bug fixed with initial skill number

#   - 1.4 (20/05/08), Added a Color variable for skill number

#   - 1.5 (27/05/08), Added an array of independent skills.

#                     These skills won't require skill number to be used.

#   - 1.6 (01/06/08), Added an array of actors with the Draw command

#   - 1.7 (01/06/08), Added an array of independent actors.

#                     These actors won't require skill number to cast a skill.

#   - 1.8 (01/06/08), Bug fixed with the skill window when an actor is independent

#   - 1.9 (02/06/08), Bug fixed with the skill window when an skill is independent

#   - 1.10(02/06/08), Added a variable to hide skills with 0 skill number

#------------------------------------------------------------------------------

#  INSTRUCTIONS:

#   1) Paste the script above main

#   2) Edit the Vocab variables

#   2) Edit the constants in the Skill_Draw module

#==============================================================================

 

# Command name

Vocab::CommandDraw = 'Draw'

Vocab::CommandDrawStock = 'Stock'

Vocab::CommandDrawCast = 'Cast'

Vocab::UnknownSkill = '??????'

Vocab::UseDraw = "%s uses #{Vocab::CommandDraw}!"

Vocab::DrawGain = "%s draw %s %s!"

Vocab::DrawFail = "%s's draw failed."

 

module Skill_Draw

  # Actors with the Draw command

  Actors = [1,2,3,4]

  # Actors who are not dependent over skill number

  Independent_Actors = [3,4]

  # The Draw Animation

  Animation_id = 41

  # Prevent from drawing specific enemy skills

  # SYNTAX: enemy_id => [skill_id, ...]

  Dont_Draw = {

                1 => [2,3]

              }

  # Color based on the windowskin's palette

  Skill_Number_Color = 14

  # Skills that don't need skill number to be casted

  Independent_Skills = [1,2,3,4,5,6,94]

  # Hide skills with 0 skill number

  Hide_Zero_Skills = false

end

 

#==============================================================================

# ** Game_System

#------------------------------------------------------------------------------

#  This class handles system-related data. Also manages vehicles and BGM, etc.

# The instance of this class is referenced by $game_system.

#==============================================================================

 

class Game_System

  #--------------------------------------------------------------------------

  # * Public Instance Variables

  #--------------------------------------------------------------------------

  attr_accessor :skill_drawned

  #--------------------------------------------------------------------------

  # * Alias Listing

  #--------------------------------------------------------------------------

  alias dargor_vx_draw_system_initialize initialize

  #--------------------------------------------------------------------------

  # * Object Initialization

  #--------------------------------------------------------------------------

  def initialize

    dargor_vx_draw_system_initialize

    @skill_drawned = []

  end

end

#==============================================================================

# ** Game_BattleAction

#------------------------------------------------------------------------------

#  This class handles battle actions. This class is used within the

# Game_Battler class.

#==============================================================================

 

class Game_BattleAction

  #--------------------------------------------------------------------------

  # * Public Instance Variables

  #--------------------------------------------------------------------------

  attr_accessor :draw_kind                # draw kind (stock/cast)

  #--------------------------------------------------------------------------

  # * Alias Listing

  #--------------------------------------------------------------------------

  alias dargor_vx_draw_battle_action_clear clear

  alias dargor_vx_draw_battle_action_make_targets make_targets

  #--------------------------------------------------------------------------

  # * Clear

  #--------------------------------------------------------------------------

  def clear

    @draw_kind = -1

    # The usual

    dargor_vx_draw_battle_action_clear

  end

  #--------------------------------------------------------------------------

  # * Set Skill

  #     skill_id : skill ID

  #     draw_kind: draw kind (stock/cast)

  #--------------------------------------------------------------------------

  def set_skill(skill_id, draw_kind = -1)

    @kind = 1

    @skill_id = skill_id

    @draw_kind = draw_kind

  end

  #--------------------------------------------------------------------------

  # * Draw Determination

  #--------------------------------------------------------------------------

  def draw?

    return @kind == 1 && [0,1].include?(@draw_kind)

  end

  #--------------------------------------------------------------------------

  # * Create Target Array

  #--------------------------------------------------------------------------

  def make_targets

    targets = []

    if draw?

      targets.push(opponents_unit.smooth_target(@target_index))

      return targets

    end

    dargor_vx_draw_battle_action_make_targets

  end

end

#==============================================================================

# ** Game_Battler

#------------------------------------------------------------------------------

#  This class deals with battlers. It's used as a superclass of the Game_Actor

# and Game_Enemy classes.

#==============================================================================

 

class Game_Battler 

  #--------------------------------------------------------------------------

  # * Draw Success

  #     skill : skill

  #     number: number to draw

  #--------------------------------------------------------------------------

  def draw_success?(skill, number)

    return false unless self.is_a?(Game_Actor)

    return false if number == 0

    level_factor = (self.level / 10) / 2

    random = [10-level_factor, 0].max

    success = (self.level / 10) + rand(random) 

    return success >= number 

  end

end

 

#==============================================================================

# ** Game_Actor

#------------------------------------------------------------------------------

#  This class handles actors. It's used within the Game_Actors class

# ($game_actors) and referenced by the Game_Party class ($game_party).

#==============================================================================

 

class Game_Actor < Game_Battler

  #--------------------------------------------------------------------------

  # * Public Instance Variables

  #--------------------------------------------------------------------------

  attr_reader   :skills_number

  #--------------------------------------------------------------------------

  # * Alias Listing

  #--------------------------------------------------------------------------

  alias dargor_vx_draw_actor_skill_can_use? skill_can_use?

  alias dargor_vx_draw_actor_setup setup

  #--------------------------------------------------------------------------

  # * Setup

  #     actor_id : actor ID

  #--------------------------------------------------------------------------

  def setup(actor_id)

    @skills_number = []

    dargor_vx_draw_actor_setup(actor_id)

    for learning in self.class.learnings

      skill = $data_skills[learning.skill_id]

      gain_skill(skill, 1)

    end

    # Add battle commands

    if Skill_Draw::Actors.include?(@actor_id)

      # Add 'Draw' to actor 1

      add_command(1, Vocab::CommandDraw)

    end

  end

  #--------------------------------------------------------------------------

  # * Learn Skill

  #     skill_id : skill ID

  #--------------------------------------------------------------------------

  def learn_skill(skill_id)

    $game_system.skill_drawned << skill_id

    unless skill_learn?($data_skills[skill_id])

      @skills.push(skill_id)

      @skills.sort!

    end

  end

  #--------------------------------------------------------------------------

  # * Get Number of Items Possessed

  #     item : item

  #--------------------------------------------------------------------------

  def skill_number(skill)

    number = @skills_number[skill.id]

    return number == nil ? 0 : number

  end

  #--------------------------------------------------------------------------

  # * Determine Usable Skills

  #     skill : skill

  #--------------------------------------------------------------------------

  def skill_can_use?(skill)

    unless Skill_Draw::Independent_Skills.include?(skill.id) or

        Skill_Draw::Independent_Actors.include?(@actor)

      return false unless skill_number(skill) > 0

    end

    dargor_vx_draw_actor_skill_can_use?(skill)

  end

  #--------------------------------------------------------------------------

  # * Gain Items (or lose)

  #     item          : Item

  #     n             : Number

  #     include_equip : Include equipped items

  #--------------------------------------------------------------------------

  def gain_skill(skill, n)

    $game_system.skill_drawned << skill.id

    number = skill_number(skill)

    @skills_number[skill.id] = [[number + n, 0].max, 99].min

    n += number

  end

  #--------------------------------------------------------------------------

  # * Lose Items

  #     item          : Item

  #     n             : Number

  #     include_equip : Include equipped items

  #--------------------------------------------------------------------------

  def lose_skill(skill, n)

    gain_skill(skill, -n)

  end

end

 

#==============================================================================

# ** Game_Enemy

#------------------------------------------------------------------------------

#  This class handles enemy characters. It's used within the Game_Troop class

# ($game_troop).

#==============================================================================

 

class Game_Enemy < Game_Battler

  #--------------------------------------------------------------------------

  # * Skills

  #--------------------------------------------------------------------------

  def skills

    result = []

    for action in enemy.actions

      next unless action.skill?

      result << $data_skills[action.skill_id]

    end

    return result

  end

end

 

#==============================================================================

# ** Window_Skill

#------------------------------------------------------------------------------

#  This window displays a list of usable skills on the skill screen, etc.

#==============================================================================

 

class Window_Skill < Window_Selectable

  alias dargor_vx_draw_skill_window_refresh refresh  

  #--------------------------------------------------------------------------

  # * Refresh

  #--------------------------------------------------------------------------

  def refresh

    dargor_vx_draw_skill_window_refresh

    if Skill_Draw::Hide_Zero_Skills

      @data = []

      for skill in @actor.skills

        @data.push(skill) unless @actor.skill_number(skill) == 0

        if skill.id == @actor.last_skill_id

          self.index = @data.size - 1

        else

          self.index = 0

        end

      end

      @item_max = @data.size

      create_contents

      for i in 0...@item_max

        draw_item(i)

      end

    end

  end

  #--------------------------------------------------------------------------

  # * Draw Item

  #     index : item number

  #--------------------------------------------------------------------------

  def draw_item(index)

    rect = item_rect(index)

    self.contents.clear_rect(rect)

    skill = @data[index]

    if skill != nil

      rect.width -= 4

      enabled = @actor.skill_can_use?(skill)

      draw_item_name(skill, rect.x, rect.y, enabled)

      self.contents.draw_text(rect, @actor.calc_mp_cost(skill), 2)

      # Draw skill number

      rect.x -= 24

      self.contents.draw_text(rect, ":", 2)

      rect.x -= 12

      skill_number = @actor.skill_number(skill)

      if Skill_Draw::Independent_Actors.include?(@actor.id) or

          Skill_Draw::Independent_Skills.include?(skill.id) 

        skill_number = ''

      end

      if enabled

        self.contents.font.color = text_color(Skill_Draw::Skill_Number_Color)

      end

      self.contents.draw_text(rect, skill_number.to_s, 2)

    end

  end

end

 

#==============================================================================

# ** Window_Skill

#------------------------------------------------------------------------------

#  This window displays a list of usable skills on the skill screen, etc.

#==============================================================================

 

class Window_EnemySkill < Window_Selectable

  #--------------------------------------------------------------------------

  # * Public Instance Variables

  #--------------------------------------------------------------------------

  attr_accessor :enemy

  #--------------------------------------------------------------------------

  # * Object Initialization

  #     x      : window x-coordinate

  #     y      : window y-coordinate

  #     width  : window width

  #     height : window height

  #     actor  : actor

  #--------------------------------------------------------------------------

  def initialize(x, y, width, height, enemy)

    super(x, y, width, height)

    @enemy = enemy

    @column_max = 2

    self.index = 0

    refresh

  end

  #--------------------------------------------------------------------------

  # * Skill

  #--------------------------------------------------------------------------

  def skill

    return @data[self.index]

  end

  #--------------------------------------------------------------------------

  # * Refresh

  #--------------------------------------------------------------------------

  def refresh

    @data = []

    for skill in @enemy.skills

      unless Skill_Draw::Dont_Draw[@enemy.id].nil?

        next if Skill_Draw::Dont_Draw[@enemy.id].include?(skill.id)

      end

      @data.push(skill)

    end

    @item_max = @data.size

    create_contents

    for i in 0...@item_max

      draw_item(i)

    end

  end

  #--------------------------------------------------------------------------

  # * Draw Item

  #     index : item number

  #--------------------------------------------------------------------------

  def draw_item(index)

    rect = item_rect(index)

    self.contents.clear_rect(rect)

    skill = @data[index]

    if skill != nil

      rect.width -= 4

      draw_item_name(skill, rect.x, rect.y, true)

    end

  end

  #--------------------------------------------------------------------------

  # * Draw Item Name

  #     item    : Item (skill, weapon, armor are also possible)

  #     x       : draw spot x-coordinate

  #     y       : draw spot y-coordinate

  #     enabled : Enabled flag. When false, draw semi-transparently.

  #--------------------------------------------------------------------------

  def draw_item_name(item, x, y, enabled = true)

    if item != nil

      draw_icon(item.icon_index, x, y, enabled)

      self.contents.font.color = normal_color

      self.contents.font.color.alpha = enabled ? 255 : 128

      if item.is_a?(RPG::Skill) && !$game_system.skill_drawned.include?(item.id)

        self.contents.draw_text(x + 24, y, 172, WLH, Vocab::UnknownSkill)

      else  

        self.contents.draw_text(x + 24, y, 172, WLH, item.name)

      end

    end

  end

  #--------------------------------------------------------------------------

  # * Frame Update

  #--------------------------------------------------------------------------

  def update

    super

  end

  #--------------------------------------------------------------------------

  # * Update Help Text

  #--------------------------------------------------------------------------

  def update_help

    if $game_system.skill_drawned.include?(skill.id)

      @help_window.set_text(skill == nil ? "" : skill.description)

    else

      @help_window.set_text(skill == nil ? "" : Vocab::UnknownSkill)

    end

  end

end

 

#==============================================================================

# ** Scene_Battle

#------------------------------------------------------------------------------

#  This class performs battle screen processing.

#==============================================================================

 

class Scene_Battle < Scene_Base

  #--------------------------------------------------------------------------

  # * Alias Listing

  #--------------------------------------------------------------------------

  alias dargor_vx_draw_battle_update update

  alias dargor_vx_draw_update_actor_command_selection update_actor_command_selection

  alias dargor_vx_draw_execute_action execute_action

  alias dargor_vx_draw_execute_action_skill execute_action_skill

  alias dargor_vx_draw_update_target_enemy_selection update_target_enemy_selection

  #--------------------------------------------------------------------------

  # * Frame Update

  #--------------------------------------------------------------------------

  def update

    unless @enemy_skill_window != nil or @draw_command_window != nil

      dargor_vx_draw_battle_update

    else

      super

      update_basic(true)

      update_info_viewport                  # Update information viewport

      if $game_message.visible

        @info_viewport.visible = false

        @message_window.visible = true

      end

      unless $game_message.visible          # Unless displaying a message

        return if judge_win_loss            # Determine win/loss results

        update_scene_change

        if @enemy_skill_window.active

          update_enemy_skill_selection    # Select party changer command

        elsif @draw_command_window.active

          update_draw_command_selection    # Select party changer command

        end

      end

    end

  end

  #--------------------------------------------------------------------------

  # * Update Actor Command Selection

  #--------------------------------------------------------------------------

  def update_actor_command_selection

    dargor_vx_draw_update_actor_command_selection

    if Input.trigger?(Input::C)

      case @actor_command_window.commands[@actor_command_window.index]

      when Vocab::CommandDraw

        Sound.play_decision

        start_target_enemy_selection

      end

    end

  end

  #--------------------------------------------------------------------------

  # * Update Target Enemy Selection

  #--------------------------------------------------------------------------

  def update_target_enemy_selection

    if Input.trigger?(Input::C) && 

        @actor_command_window.selection == Vocab::CommandDraw

        Sound.play_decision

      Sound.play_decision

      @active_battler.action.target_index = @target_enemy_window.enemy.index

      start_draw_command_selection

      end_target_enemy_selection

      end_skill_selection

      end_item_selection

      return

    end

    dargor_vx_draw_update_target_enemy_selection

  end

  #--------------------------------------------------------------------------

  # * Start Draw Command Selection

  #--------------------------------------------------------------------------

  def start_draw_command_selection

    enemy = @target_enemy_window.enemy

    @help_window = Window_Help.new

    @help_window.y = 56

    @enemy_skill_window = Window_EnemySkill.new(0, 112, 544, 176, enemy)

    @enemy_skill_window.help_window = @help_window

    @enemy_skill_window.active = false

    s1 = Vocab::CommandDrawStock

    s2 = Vocab::CommandDrawCast

    @draw_command_window = Window_Command.new(544, [s1,s2], 2)

  end

  #--------------------------------------------------------------------------

  # * Update Draw Command Selection

  #--------------------------------------------------------------------------

  def update_draw_command_selection

    @draw_command_window.update

    @actor_command_window.active = false

    if Input.trigger?(Input::B)

      end_draw_command_selection

      return

    end

    if Input.trigger?(Input::C)

      @enemy_skill_window.active = true

      return

    end

  end

  #--------------------------------------------------------------------------

  # * End Draw Command Selection

  #--------------------------------------------------------------------------

  def end_draw_command_selection

    if @enemy_skill_window != nil

      @enemy_skill_window.dispose

      @enemy_skill_window = nil

      @draw_command_window.dispose

      @draw_command_window = nil

      @help_window.dispose

      @help_window = nil

    end

    @actor_command_window.active = true

  end

  #--------------------------------------------------------------------------

  # * Update Enemy Skill Selection

  #--------------------------------------------------------------------------

  def update_enemy_skill_selection

    @help_window.update

    @enemy_skill_window.update

    @actor_command_window.active = false

    if Input.trigger?(Input::B)

      @draw_command_window.active = true

      @enemy_skill_window.active = false

      return

    end

    if Input.trigger?(Input::C)

      case @draw_command_window.selection

      when Vocab::CommandDrawStock

        # Play decision SE

        Sound.play_decision

        @active_battler.action.set_skill(@enemy_skill_window.skill.id, 0)

        # Force the action to be executed

        @active_battler.action.forcing = true

        # End draw selection

        end_draw_command_selection

        # Switch to next actor

        next_actor

      when Vocab::CommandDrawCast

        Sound.play_decision

        # Prepare to cast a drawned skill

        @active_battler.action.set_skill(@enemy_skill_window.skill.id, 1)

        # Force the action to be executed

        @active_battler.action.forcing = true

        @active_battler.action.target_index = @enemy_skill_window.enemy.index

        # End draw selection

        end_draw_command_selection

        # Switch to next actor

        next_actor

      end

    end

  end

  #--------------------------------------------------------------------------

  # * Execute Battle Actions

  #--------------------------------------------------------------------------

  def execute_action

    if @active_battler.action.draw?

      case @active_battler.action.draw_kind

      when 0 # Stock

        execute_action_draw_stock

        return

      when 1 # Cast

        execute_action_draw_cast

        return

      end

    end

    # The usual

    dargor_vx_draw_execute_action

  end

  #--------------------------------------------------------------------------

  # * Execute Battle Action: Skill

  #--------------------------------------------------------------------------

  def execute_action_skill

    skill = @active_battler.action.skill

    # Remove 1 skill number

    if @active_battler.is_a?(Game_Actor)# && 

        #!@active_battler.action.draw_kind == 0

      @active_battler.lose_skill(skill, 1)

    end

    # The usual

    dargor_vx_draw_execute_action_skill

  end

  #--------------------------------------------------------------------------

  # * Execute Battle Action: Draw Stock

  #--------------------------------------------------------------------------

  def execute_action_draw_stock

    text = sprintf(Vocab::UseDraw, @active_battler.name)

    @message_window.add_instant_text(text)

    targets = @active_battler.action.make_targets

    display_animation(targets, Skill_Draw::Animation_id)

    # Add skill number

    skill = @active_battler.action.skill

    gain = rand(9)

    if @active_battler.draw_success?(skill, gain)

      if @active_battler.is_a?(Game_Actor)

        @active_battler.gain_skill(skill, gain)

        @active_battler.learn_skill(skill.id)

      end

      name = skill.name

      name += 's' if gain > 1

      text = sprintf(Vocab::DrawGain, @active_battler.name, gain, name)

      @message_window.add_instant_text(text)

      wait(60)

    else

      text = sprintf(Vocab::DrawFail, @active_battler.name)

      @message_window.add_instant_text(text)

      wait(60)

    end

  end

  #--------------------------------------------------------------------------

  # * Execute Battle Action: Draw Cast

  #--------------------------------------------------------------------------

  def execute_action_draw_cast

    # Add skill to known skills

    skill = @active_battler.action.skill

    $game_system.skill_drawned << skill.id

    # Cast the skill

    execute_action_skill

  end

end

Notes

The script requires my Custom Commands script.

-Dargor
 
I going to kill you!

I was working on this, including the Junction System aswell, well no need to work on it anymore.. I am going to Play FFVIII again.

Bye. Good work anyway =)
 
Ok, now you are my scripter hero :P

Final Fantasy is a game. But now, with your script, we can make *our* Final fantasy games!
 
I LOVE YOU!!

The draw system is one of my favourite game systems ever! (Aside from the junction system, actually!)

I'm dying for someone to make a junction system. Ever since SephirothSpawn announced he was working on it, I've been waiting and waiting... let's hope you can do this! ;)

Oh one question, can I use this script together with the  [VX] RPG Tankentai Sideview Battle System 2.6 Translated + Addons script? I can't try it out right now because our internet connection is as stable as zero and I'd need to download both scripts. Thanks!!

I'm amazed, this draw system sounds even better than the original FFVIII one...
 
New2Ya":z687d29m said:
Oh one question, can I use this script together with the  [VX] RPG Tankentai Sideview Battle System 2.6 Translated + Addons script? I can't try it out right now because our internet connection is as stable as zero and I'd need to download both scripts. Thanks!!

*butts in*

I don't think it would be a problem.  I've added a few things to that system in the past, and it worked just fine.
 
Hmm, there seems to be a problem that maybe I'm the only one noticing or having it effect but, the amount of each spell you draw doesn't decrease upon using said spell. Don't know if this is being looked into or even know, just though I'd point it out.

Example:
I draw 9 fires from one enemy, use one of those fires on the enemy and now I should have only 8 fires, but instead I still have 9.
 
^I have the same problem. Must be a mistake with the script.

Ah, and sadly it doesnt work with the side view battle system. The Draw option is there and you can choose it, but the Draw Stock Cast window doesnt pop up. Instead, it just works like the Attack command.

Too bad, cuz I'm immediatly trying to make it look more like FFVIII. XD

Is it possible to place the Draw command below the Skill Command?
 
I've fixed another minor bug, this one was conflicting with my upcoming Junction script. :wink:

See ya!
-Dargor


EDIT:

@New2Ya
You can place the command wherever you want. Look for this line
Code:
add_command(1, Vocab::CommandDraw)
and change 1 for the index you want.
 
Ah that's great Dargor, thanks for that. Having it below Skill somehow just looks better for me. Thanks!

(looking forward to your Junction system...  :thumb: )
 
Problem. I tried to remove the command for one battle like so:

Code:
$game_actors[1].remove_command(Vocab::CommandDraw)

And I got an error saying that the wrong number of arguments(0 of 1) were being used.

Basically, I want to know how I can fix that.
 
That's odd. You seem to use the correct method.
Try to use this line
Code:
$game_actors[1].remove_command("#{Vocab::CommandDraw}")
I don't see why this method would work and not the previous one, but it can't be worst :smile:

I'm not at home so I can't test it but I'll take a look at this ASAP.
 
I've updated the script to version 1.7
You can now set an array of actors with the Draw command and an array of independent actors.
Independent actors does not need skill number to cast skills.

@Ryuzaki
Your doing the right thing. I don't know why it doesn't work... Can you send me your Script.rvdata? I'd, like to take a look at it.
 

Thank you for viewing

HBGames is a leading amateur video game development forum and Discord server open to all ability levels. Feel free to have a nosey around!

Discord

Join our growing and active Discord server to discuss all aspects of game making in a relaxed environment. Join Us

Content

  • Our Games
  • Games in Development
  • Emoji by Twemoji.
    Top