- 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.
Also, this amazing addon to check some really good conditions:
[-_>[-_>[-_>[-_>
=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
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
=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?
==============================================================================
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?

