Targaryen

Veteran
Veteran
Joined
Oct 23, 2015
Messages
51
Reaction score
11
First Language
Spanish
Primarily Uses
I have been using Hime's Skill Link script for RPG Maker VX Ace, and I'm wondering if someone could rewrite it to javascript.

 

=begin#===============================================================================

 Title: Skill Links

 Author: Hime

 Date: Feb 15, 2015

 URL: http://www.himeworks.com/2014/03/30/skill-links/

--------------------------------------------------------------------------------

 ** Change log

 Feb 15, 2014

   - fixed typo

 Dec 1, 2014

   - Implemented skill link conditions

 Jul 14, 2014

   - skill links are not activated if there is no current action

 Mar 30, 2014

   - Initial release

--------------------------------------------------------------------------------   

 ** Terms of Use

 * Free to use in non-commercial projects

 * Contact me for commercial use

 * No real support. The script is provided as-is

 * Will do bug fixes, but no compatibility patches

 * Features may be requested but no guarantees, especially if it is non-trivial

 * Credits to Hime Works in your project

 * Preserve this header

--------------------------------------------------------------------------------

 ** Description

 

 This script allows you to create "skill links" which are basically a way to

 connect skill effects together.

 

 Skill links are purely a development concept: they are created to allow you

 to specify multiple behavior that should occur when a single skill is used.

 In particular, it allows a single skill to execute damage formulas and effects

 under different scopes.

 

 For example, suppose you wanted to create a skill that damages the enemies,

 but also heals all allies as a secondary effect. By default, there is no easy

 way to accomplish this without resorting to common events or complex formulas,

 and even that may have its own limitations.

 

 However, there are few  things that you CAN do.

 It is easy to create a skill that will damage all enemies

 It is also easy to create a skill that will heal all allies.

 

 This script introduces the link between the two skills: you simply specify the

 healing skill as a "linked skill" to the damaging skill, and now whenever you

 execute the damaging skill, the healing skill will automatically run as well.

 

--------------------------------------------------------------------------------

 ** Installation

 

 In the script editor, place this script below Materials and above Main

 

--------------------------------------------------------------------------------

 ** Usage 

 

 To create a skill link, note-tag a skill or item with

 

   <link skill: ID>

   

 Where ID is the ID of the skill you want to link.

 

 You can also create item links. Note-tag a skill or item with

 

   <link item: ID>

   

 Where ID is the ID of the item you want to link.

 

 You can have items linked to skills, or skills linked to items.

 

 -- Link Conditions --

 

 You can create link conditions. These conditions specify whether the linked

 skill or item will be executed. They will be executed only if the conditions

 are met.

 

 To create a link condition, use the note-tag

 

   <link condition: link_ID>

     FORMULA

   </link condition>

   

 Where the link ID is the ID of the link data that you created earlier.

 The ID is assigned based on the order that they appear, so the very first

 <link skill> tag is ID 1, the next is ID 2, and so on.

 

 The following variables are available

 

   a - action user

   b - action target

   p - game party

   t - game troop

   s - game switches

   v - game variables

 

--------------------------------------------------------------------------------

 ** Notes

 

 This script does not play animations for skill links. 

 

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

=end

$imported = {} if $imported.nil?

$imported[:TH_SkillLinks] = true

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

# ** Configuration

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

module TH

  module Skill_Links

    Regex = /<(link[-_ ]item|link[-_ ]skill):\s*(\d+)\s*>/i    

    Cond_Regex = /<link[-_ ]condition:\s*(\d+)\s*>(.*?)<\/link[-_ ]condition>/im

  end

end

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

# ** Rest of script

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

module RPG

  class UsableItem < BaseItem

    

    def skill_links

      load_notetag_skill_links unless @skill_links

      return @skill_links

    end

    

    def load_notetag_skill_links

      @skill_links = []

      results = self.note.scan(TH::Skill_Links::Regex)

      results.each do |res|

        data = Data_SkillLink.new

        data.id = res[1].to_i

        if res[0] =~ /skill/i

          data.type = :skill

        else

          data.type = :item

        end

        @skill_links << data

      end

      

      results = self.note.scan(TH::Skill_Links::Cond_Regex)

      results.each do |res|

        id = res[0].to_i

        cond = res[1].strip

        @skill_links[id-1].condition = cond

      end

    end

  end

end

 

class Data_SkillLink

 

  attr_accessor :id

  attr_accessor :type

  attr_accessor :condition

  

  def initialize

    @type = nil

    @id = 0

    @condition = ""

  end

  

  def item

    return $data_skills[@id] if @type == :skill

    return $data_items[@id] if @type == :item

  end

  

  def condition_met?(user, target)

    return true if @condition.empty?

    return eval_condition(user, target)

  end

  

  def eval_condition(a, b, p=$game_party, t=$game_troop, s=$game_switches, v=$game_variables)

    eval(@condition)

  end

end

 

class Scene_Battle < Scene_Base

  

  alias :th_skill_links_use_item :use_item

  def use_item

    th_skill_links_use_item

    check_item_links

  end

 

  def check_item_links

    return unless @subject.current_action

    item = @subject.current_action.item

    item.skill_links.each do |link_data|

      

      use_item_link(link_data)

    end

  end

  

  def use_item_link(link_data)

    link_item = link_data.item

    @subject.use_item(link_item)

    refresh_status

    if link_item.is_a?(RPG::Skill)

      @subject.current_action.set_skill(link_item.id)

    else

      @subject.current_action.set_item(link_item.id)

    end

    targets = @subject.current_action.make_targets.compact

    targets.each do |target|    

      link_item.repeats.times do

        next unless link_data.condition_met?(@subject, target)

        invoke_item(target, link_item)

      end

    end

  end

end
Also, this amazing addon to check some really good conditions:

=begin
==============================================================================
Hime's Skill Links Plugin
RogueDeus - Conditional Links v1.0.1
Released: 2014.05.07

-- v1.0 :: 2014.05.06
+ Initial Version.
-- v1.0.1 :: 2014.05.13
+ Fixed potential target array size issue.
+ Added 'unique' target variable collection.



==============================================================================
DESCRIPTION:
==============================================================================
This plugin adds a new note tag for skill links, that allows for simple %
chance, as well as complex formula evaluation, conditions. There are few if
any limitations on what your formula can contain so long as it resolves
true/false.

==============================================================================
CREDIT:
==============================================================================

Tsukihime - Skill Links
http://www.himeworks.com/2014/03/30/skill-links/

==============================================================================
TERMS OF USE:
==============================================================================
See: Tsukihime - Skill Links

==============================================================================

** Installation
Place directly underneath Hime's Skill Links
Requires:
Tsukihime - Skill Links

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

** Usage

All note tags are processed individually, in order.
Tag conditions that reference another tags success will need to be placed
UNDER such references. (See: Example 7)

NOTE TAG:

id: X
chance: Y
condition: Z


X: (skill/item ID)

Y: (1.0 = 100%)

Z: (formula must eval true/false)
Primary Condition Formula Variable References:
a = actor using the item
l = last conditionally linked item (for conditional, conditional links!)
r = results_stats (combo of all linked results)

p = $game_party (Ex: p.highest_level > 10)
t = $game_troop (Ex: t.turn_count > 1)
v = $game_variables (Ex: v[100] >= 3)
s = $game_switches (Ex: s[100] == true)

Base Example:
This example will fire off skill(2) 100% of the time, but only if nothing
died as a result of the linking skills use. If the linking skill was a
single target scope, then the original target must still be alive for
skill(2) to be performed. If the linking skill was a multi-target scope
then neither of its targets can have died. See Detailed Descriptions
below for more accurate measures.


id: 2
chance: 1
condition: r.is_alive


#---------------------------------------------------------------------------
RESULTS STATS:
This is a collection of the total effect on all targets,
accomplished by the last item/skill used in battle
by the current actor.

Important!!! This information is cleared upon the execution of
the next successful item/skill link. Keep that in mind when
creating conditional trees. You will only be able to reference
the most previous of all the successful links.

>>> Failed links are not tracked at all. <<<

EXTENDED EXAMPLE FORMULA REFERENCES
***********************************************************
**** Remember all Array indexes start at 0 not 1 ****
***********************************************************
r.results[x] # (in order) Array of all linked results
r.results[x].hit? # Returns if target did not miss or evade
r.targets[x] # (in order) Array of all battlers targeted
r.targets[x].dead? # Returns if the target died in the attack
r.killed[x] # (in order) Array of battlers killed
r.killed[x].size # Returns the number of targets killed
***********************************************************
r.u_targets[x] # (in order) Array of unique targets
***********************************************************
r.all_dead # Did all targets die?
r.is_alive # Did ANY target die?
r.last # Last battler targeted
***********************************************************
r.count # Total uses (for comparison of below)
r.misses # Num of uses that did-not hit
r.evades # Num of uses that were evaded
r.hits # Num of uses that weren't evaded or missed
r.successes # Num of *hits that dealt damage
r.crits # Num of *hits that crit
***********************************************************
r.u_evades # Num of uses that were evaded vs. unique targets
r.u_hits # Num of uses that weren't evaded or missed vs. unique targets
r.u_successes # Num of *hits that dealt damage vs. unique targets
r.u_crits # Num of *hits that crit vs. unique targets
***********************************************************
r.thp_dam # Total HP Damage dealt
r.tmp_dam # Total MP Damage dealt
r.ttp_dam # Total TP Damage dealt
r.thp_drain # Total HP Drained
r.tmp_drain # Total MP Drained
***********************************************************
r.added_states # All states applied by last item/skill
r.removed_states # All states removed by last item/skill
***********************************************************

Notes:
(r.is_alive) is provided for easy reference. It is meant to be used
to prevent links from firing if the intended target is
already dead. Thus preventing a skill from unintentionally
jumping between targets. If added to a condition, ANY
target death results in the failure of condition:.

- Thus, to check if ALL targets lived, use r.is_alive
- To check if the initial target of an item/skill is alive,
use r.targets[0].alive?
- To check if all targets died, use r.all_dead
Remember that battle ends if all targets = all battlers.
So 'All Enemies' scoped skills with r.all_dead are moot.

(r.hits) is the total number of non-missed and non-evaded skill uses.
However, to check to see if a specific target was hit,
you'll need to reference the specific r.result[x].

(r.result[x]) allows you to access each separate repeat of the previous
skill. So if you want to check the details of the 3rd
attempt of a multi-hit skill to hit its target, you'd
reference r.result[2].hit?

(r.targets[x]) allows you to access each battler targeted by (but not
necessarily effected by) the previous skill. You'd have to
include r.result[x].hit? in the condition to make sure it
didn't miss, or evade its target.

- All battler parameters can be referenced like normal.
i.e.: r.targets[x].hp will return the targets current HP

i.e.: r.targets[x].state?(50) will be true if the target
is effected by state_id(50). However if you want to
check if the last action resulted in the state, use
r.added_states.include?(50) instead. (See: Example 8)


#---------------------------------------------------------------------------
**Example Conditions
#---------------------------------------------------------------------------
Example 1: Does the attacker have more than half its MHP?

condition: a.hp > (a.mhp * 0.5)

Example 2: Did the linking skill hit at least once?

condition: r.hits > 0

Example 3: Did the last target die?

condition: r.last.dead?

Example 4: Did the linking skill deal at least 10% of the first targets
health in total damage?

condition: r.thp_dam > (r.targets[0].mhp * 0.1)

Example 5: Did the linking skill kill 2 or more enemies?

condition: r.killed.length > 1

Example 6: Was the linking skills first HIT target a darkspawn?
Requires Hime's Tag Manager

condition: r.targets[0].tags.include?("darkspawn") && r.results[0].hit?

Example 7: Was the LAST linked skill/item ID:5?
Note: if there is only one possible link item/skill, 'l' will
reference the original linking item/skill

condition: l.id == 5

Example 8: Did the linking skill poison(50) any targets?

condition: r.added_states.include?(50)

Example 9: Did the linking skill poison(50) the first target?

condition: r.results[0].added_states.include?(50)

Example 10: Is the first target weak against fire(3) damage?

condition: r.targets[0].element_rate(3) > 1.0

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

=end


if $imported[:TH_SkillLinks]
#===============================================================================
#
#===============================================================================
module RPG
class UsableItem < BaseItem

#-----------------------------------------------------------------------------
# new:
#-----------------------------------------------------------------------------
def skill_link?
return @has_skill_link if @has_skill_link
self.note =~ /()/i
self.note =~ /()/i if !$1
$1 ? @has_skill_link = true : @has_skill_link = false
end

#-----------------------------------------------------------------------------
# new:
#-----------------------------------------------------------------------------
def skill_links_conditional
return @skill_links_conditional if @skill_links_conditional
@skill_links_conditional = self.note.scan(/(.*?)<\/link[-_ ]skill[-_ ]cond>/im)
end

#-----------------------------------------------------------------------------
# new:
#-----------------------------------------------------------------------------
def item_links_conditional
return @item_links_conditional if @item_links_conditional
@item_links_conditional = self.note.scan(/(.*?)<\/link[-_ ]item[-_ ]cond>/im)
end

#-----------------------------------------------------------------------------
# new:
#-----------------------------------------------------------------------------
def skill_links_conditional_data
return @skill_links_conditional_data if @skill_links_conditional_data

@skill_links_conditional_data = []
stuff = self.skill_links_conditional
stuff.each do |link|
id = 0
chance = 1
condition = "true"

data = link[0].strip.split(/[\r\n]+/)
for option in data
case option
when /id:\s*(\d+)/i
id = $1.to_i
when /chance:\s*(.*)/i
chance = $1.to_f if $1
when /condition:\s*(.*)/i
condition = $1 if $1
end
end
cond_link = Data_SkillLink.new(id)
cond_link.chance = chance
cond_link.condition = condition
@skill_links_conditional_data << cond_link
end
return @skill_links_conditional_data
end

#-----------------------------------------------------------------------------
# new:
#-----------------------------------------------------------------------------
def item_links_conditional_data
return @item_links_conditional_data if @item_links_conditional_data

@item_links_conditional_data = []
stuff = self.item_links_conditional
stuff.each do |link|
id = 0
chance = 1
condition = "true"

data = link[0].strip.split("\r\n")
for option in data
case option
when /id:\s*(\d+)/i
id = $1.to_i
when /chance:\s*(.*)/i
chance = $1.to_f if $1
when /condition:\s*(.*)/i
condition = $1 if $1
end
end
cond_link = Data_SkillLink.new(id)
cond_link.chance = chance
cond_link.condition = condition
@item_links_conditional_data << cond_link
end
return @item_links_conditional_data
end
end #UsableItem
end #RPG



#===============================================================================
# new class:
#===============================================================================
class Data_SkillLink
attr_accessor :id
attr_accessor :chance
attr_accessor :condition

#-----------------------------------------------------------------------------
# new:
#-----------------------------------------------------------------------------
def initialize(id)
@id = id
@chance = 1
@condition = "false"
end

#-----------------------------------------------------------------------------
# new:
# a = actor using the item
# l = last conditionally linked item
# r = results_stats (combo of all linked results)
#-----------------------------------------------------------------------------
def condition_met?(a, l, r, p=$game_party, t=$game_troop, v=$game_variables, s=$game_switches)
return false if @condition.empty?
eval(@condition)
end
end



#===============================================================================
# new class:
#===============================================================================
class Linked_Results
attr_reader :results #Linkback to item_link_results
attr_reader :is_alive #Did any target die?
attr_reader :all_dead #Did all targets die?
attr_reader :killed #Array of battlers killed
attr_reader :targets #(in order) All battlers targeted
attr_reader :last #Last battler targeted
attr_reader :count #Total uses
attr_reader :misses #Num of results that did-not succeed
attr_reader :successes #Num of results that succeeded
attr_reader :crits #Num of successes that crit
attr_reader :evades #num of successes that were evaded
attr_reader :hits #num of hits (not missed not evaded)
attr_reader :thp_dam #
attr_reader :tmp_dam #
attr_reader :ttp_dam #
attr_reader :thp_drain #
attr_reader :tmp_drain #
attr_reader :added_states #
attr_reader :removed_states #

attr_reader :u_targets #(in order) total unique battlers targeted
attr_reader :u_hits #num of hits (not missed not evaded)
attr_reader :u_evades #num of hits that were evaded
attr_reader :u_successes #Num of hits that dealt damage
attr_reader :u_crits #Num of successes that crit

#-----------------------------------------------------------------------------
# new:
#-----------------------------------------------------------------------------
def initialize(item_link_results)
@results = item_link_results
@is_alive = true
@all_dead = false
@killed = []
@targets = []
@count = 0
@misses = 0
@successes = 0
@crits = 0
@evades = 0
@hits = 0
@thp_dam = 0
@tmp_dam = 0
@ttp_dam = 0
@thp_drain = 0
@tmp_drain = 0
@added_states = []
@removed_states = []

@u_targets = [] #To collect unique targets list
@u_successes = 0
@u_crits = 0
@u_evades = 0
@u_hits = 0

process_results(item_link_results)
end

#-----------------------------------------------------------------------------
# new:
# Need to create array of unique targets
#-----------------------------------------------------------------------------
def process_results(item_link_results)
unique = false

item_link_results.each do |result|
@last = result.battler
unique = true if !@targets.include?(result.battler) #Target is unique if not already a target.
@targets << result.battler

if result.battler.dead?
@is_alive = false
@killed << result.battler
end

@count += 1 if result.used #For Comparisons.
@misses += 1 if result.missed #For Comparisons.

@hits += 1 if result.hit?
@u_hits += 1 if result.hit? && unique
@crits += 1 if result.critical
@u_crits += 1 if result.critical && unique
@evades += 1 if result.evaded
@u_evades += 1 if result.evaded && unique
@successes += 1 if result.success
@u_successes+= 1 if result.success && unique

proc_hp_dam(result)
proc_mp_dam(result)
proc_tp_dam(result)
proc_hp_drain(result)
proc_hp_drain(result)

@added_states = @added_states.concat(result.added_states)
@removed_states = @removed_states.concat(result.removed_states)
unique = false
end
@u_targets = @targets.uniq #Can count # of unique targets
@all_dead = true if @killed.length == @targets.length
end

#-----------------------------------------------------------------------------
# new:
#-----------------------------------------------------------------------------
def proc_hp_dam(result)
return 0 unless result.hp_damage > 0
if result.success && !result.missed && !result.evaded
@thp_dam += result.hp_damage
else
end
end
#-----------------------------------------------------------------------------
# new:
#-----------------------------------------------------------------------------
def proc_mp_dam(result)
return 0 unless result.mp_damage > 0
if result.success && !result.missed && !result.evaded
@tmp_dam += result.mp_damage
end
end
#-----------------------------------------------------------------------------
# new:
#-----------------------------------------------------------------------------
def proc_tp_dam(result)
return 0 unless result.tp_damage > 0
if result.success && !result.missed && !result.evaded
@ttp_dam += result.tp_damage
end
end
#-----------------------------------------------------------------------------
# new:
#-----------------------------------------------------------------------------
def proc_hp_drain(result)
return 0 unless result.hp_drain > 0
if result.success && !result.missed && !result.evaded
@thp_drain += result.hp_drain
end
end
#-----------------------------------------------------------------------------
# new:
#-----------------------------------------------------------------------------
def proc_hp_drain(result)
return 0 unless result.mp_drain > 0
if result.success && !result.missed && !result.evaded
@tmp_drain += result.mp_drain
end
end

end



#===============================================================================
#
#===============================================================================
class Game_ActionResult
attr_reader :battler
end



#===============================================================================
#
#===============================================================================
class Scene_Battle < Scene_Base

#-----------------------------------------------------------------------------
# overwrite of alias:
#-----------------------------------------------------------------------------
def use_item
@item_link_results = [] #First item result array.
th_skill_links_use_item #Invoke Item(s) = fills array.
check_item_links #Uses array & repeats...
end

#-----------------------------------------------------------------------------
alias :invoke_item_rdslp :invoke_item
def invoke_item(target, item)
invoke_item_rdslp(target, item)
@item_link_results << target.result.clone
end

#-----------------------------------------------------------------------------
# overwrite:
#-----------------------------------------------------------------------------
def check_item_links
item = @subject.current_action.item
return if !item.skill_link? #No links, do nothing.
item.skill_links.each do |link_item|
use_item_link(link_item)
end

if item.is_a?(RPG::Skill)
process_skill_link_condition(item)
else
process_item_link_condition(item)
end
end

#-----------------------------------------------------------------------------
# new:
#-----------------------------------------------------------------------------
def process_skill_link_condition(item)
item.skill_links_conditional_data.each do |cond_link|
link_item = $data_skills[cond_link.id]
if link_conditions_met?(item, link_item, cond_link)
invoke_skill_link(cond_link)
end
end
end

#-----------------------------------------------------------------------------
# new:
#-----------------------------------------------------------------------------
def process_item_link_condition(item)
item.item_links_conditional_data.each do |cond_link|
link_item = $data_items[cond_link.id]
if link_conditions_met?(item, link_item, cond_link)
invoke_item_link(cond_link)
end
end
end

#-----------------------------------------------------------------------------
# new:
#-----------------------------------------------------------------------------
def link_conditions_met?(orig_item, link_item, cond_link)
return false if rand >= cond_link.chance
@last_item ||= orig_item
return false if !cond_link.condition_met?(@subject, @last_item, Linked_Results.new(@item_link_results) )
@last_item = link_item
return true
end

#-----------------------------------------------------------------------------
# new:
#-----------------------------------------------------------------------------
def invoke_skill_link(cond_link, link_item = nil)
link_item = $data_skills[cond_link.id] if !link_item
@item_link_results = []
@subject.use_item(link_item)
refresh_status
@subject.current_action.set_skill(link_item.id)
targets = @subject.current_action.make_targets.compact
targets.each {|target| link_item.repeats.times { invoke_item(target, link_item) } } #Re-Fills Result array.
end

#-----------------------------------------------------------------------------
# new:
#-----------------------------------------------------------------------------
def invoke_item_link(cond_link, link_item = nil)
link_item = $data_items[cond_link.id] if !link_item
@item_link_results = []
@subject.use_item(link_item)
refresh_status
@subject.current_action.set_item(link_item.id)
targets = @subject.current_action.make_targets.compact
targets.each {|target| link_item.repeats.times { invoke_item(target, link_item) } }
end
end #Scene_Battle
end #Imported?
[-_>[-_>[-_>[-_>
 

Targaryen

Veteran
Veteran
Joined
Oct 23, 2015
Messages
51
Reaction score
11
First Language
Spanish
Primarily Uses
That's perfect, thanks!
 

Latest Threads

Latest Profile Posts

I don't really have any neat updates today about how I screwed up programming... But if you want to observe the intensenes of me programming, then you can check out my stream :)
New Weapons.gif
No more spam from me today, I promise! Just wanted to upload this, people have been giving me feedback that my weapon sprites (which were RTP) clashed badly with my battlers for ages, so today I finally took the plunge and updated them! Really happy with how they came out :D :D
So Facebook fraudulently took money from me. They even went through my PayPal accounts to find a card that had the money on it. Thinking about deleting my Facebook account because this doesn't happen on twitter, not even close.
Today the 2nd part of the RPGMakergame "A Thief's voyage" came out.


Go show DutchPowerCreations some love.
love it when you forget to put a certain thing in the movement route and suddenly a character starts spinning at 10000 rpm

Forum statistics

Threads
116,992
Messages
1,103,663
Members
152,889
Latest member
LazyTitan
Top