Passive Augments
Authors: Xelias
Version: 1.01
Type: Skill Enhancement
Key Term: Custom Skill System
Authors: Xelias
Version: 1.01
Type: Skill Enhancement
Key Term: Custom Skill System
Introduction
This script allows to make passive abilities. These abilities are made from skills. They affect attacks, skills, and equipment. More information in the script.
Features
- Allows multiple special effects, such as Demi MP, Brawler, Once more... And many others.
- Need special passive abilities to cast magic.
- Need special passive abilities to equip weapons and armors.
- Allows attacking without weapons.
Screenshots
Demo
Not really.
Script
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
# Passive Augments by Xelias
# Version: 1.01
# Type: Skill Enhacement
# Date v1.01: 18.12.2009
#
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
#
# This work is protected by the following license:
# #----------------------------------------------------------------------------
# #
# # Creative Commons - Attribution-NonCommercial-ShareAlike 3.0 Unported
# # ( http://creativecommons.org/licenses/by-nc-sa/3.0/ )
# #
# # You are free:
# #
# # to Share - to copy, distribute and transmit the work
# # to Remix - to adapt the work
# #
# # Under the following conditions:
# #
# # Attribution. You must attribute the work in the manner specified by the
# # author or licensor (but not in any way that suggests that they endorse you
# # or your use of the work).
# #
# # Noncommercial. You may not use this work for commercial purposes.
# #
# # Share alike. If you alter, transform, or build upon this work, you may
# # distribute the resulting work only under the same or similar license to
# # this one.
# #
# # - For any reuse or distribution, you must make clear to others the license
# # terms of this work. The best way to do this is with a link to this web
# # page.
# #
# # - Any of the above conditions can be waived if you get permission from the
# # copyright holder.
# #
# # - Nothing in this license impairs or restricts the author's moral rights.
# #
# #----------------------------------------------------------------------------
##
## Version history
##
## 1.01
##
## *Added new Passive Skills (From RESIST_STATES to GEOMANCY)
## *Fixed a bug
##
# #----------------------------------------------------------------------------
# This script creates "Passive Skills". The "Passive Skills" you list in
# PASSIVE_SKILLS_IDS = [] are displayed in a separate menu.
# They are simple skills you can give an Icon, a name, a description...
# You can change the menu's name in PASSIVE_WORD = "Augments"
# Replace "Augments" by whatever name you want.
#
# Passive Skills only work on actors !
#
# Passive skills effects are listed here :
#
# GUARD_PLUS will decrease even more the damage taken while defending.
# MP_SHIELD will allow damage to be inflicted on SP instead of HP until you run out of SP.
# MARTYR allows the character to gain SP when taking damage
# INQUISITOR allows the character to gain SP when dealing physical damage.
# WARMAGE allows the character to gain SP when dealing damage with spells.
# BLOOD_PRICE allows the character to pay HP instead of SP. HP cost is SP cost*5
# DEMI_MP allows the character to cast spells for half the SP cost
# TURBO_MP doubles the SP cost as well as the power of the skills.
# SPELLBREAKER increases the damage dealt by spells when you have low HP
# ADRENALINE increases the damage dealt by attacks when you have low HP
# LAST_STAND decreases the damage taken when you have low HP
# CHARGED_ATTACKS increases the power of physical attacks for 6 SP a hit until you run out of SP.
# BRAWLER allows you to inflict more damage when no weapons are equipped. Note that
# thanks to this script, bare-handed attacks are available. Just modify the BARE_ANIMATION_SELF_ID
# and BARE_ANIMATION_ID to modify the animations that play on the attacker and on the enemy
# while attacking without weapons, respectively.
# CRITICAL_BOOST increases the critical hit ratio
# FOCUS slightly increases the damage dealt by attacks when at full HP
# SERENITY slightly increases the damage dealt by spells when at full HP
# ONCE_MORE allows the actor to survive all hits when his HP are higher than 1 : then his
# HP will become 1, and next strike will be deadly. Think about Kingdom Hearts for this one.
# LEARNING allows the actor to learn blue magic. This blue magic is set in BLUE_SKILLS_IDS = []
# HEALER increases the potency of healing spells and objects on the actor.
# STATE_RESIST halves the chances the actor will be affected by a status effect
# BLOOD_SWORD absorbs 1/4 of damage done by physical attacks as HP for the actor.
# ELEMENTALISM reduces an enemy's resistance to elemental spells
# GEOMANCY increases the user's resistance to elemental spells.
#
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=
PASSIVE_SKILLS_IDS = [81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101]
PASSIVE_WORD = "Augments"
GUARD_PLUS_ID = 81
MP_SHIELD_ID = 82
MARTYR_ID = 83
INQUISITOR_ID = 84
WARMAGE_ID = 85
BLOOD_PRICE_ID = 86
DEMI_MP_ID = 87
TURBO_MP_ID = 88
SPELLBREAKER_ID = 89
ADRENALINE_ID = 90
LAST_STAND_ID = 91
CHARGED_ATTACKS_ID = 92
BRAWLER_ID = 93
CRITICAL_BOOST_ID = 94
FOCUS_ID = 95
SERENITY_ID = 96
ONCE_MORE_ID = 97
LEARNING_ID = 98
HEALER_ID = 99
STATE_RESIST_ID = 100
BLOOD_SWORD_ID = 101
ELEMENTALISM_ID = 102
GEOMANCY_ID = 103
BLUE_SKILLS_IDS = [61,62]
BARE_ANIMATION_SELF_ID = 0
BARE_ANIMATION_ID = 4
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:
#
# Passive skills can also be used to equip weapons and armors, and to be able to use skills.
# Configure it like that :
#
# When [weapon/armor id] then return [passive skill id]
# When [skill id] then return [passive skill id]
#
# Note that passive skills overwrite class restrictions : if a warrior gets a "Equip Staffs"
# passive ability, he will be able to equip staffs.
#
# On a sad note, all weapons/armors need to be set to a skill in order to be equipped.
# If you put "nil" or "0", the game will crash.
# So set a skill for each different weapon or armor. Default is 100
# The same applies for skills. Skills won't crash, but won't be able to be used. Which is bad.
# However if you put "when skill X then return skill X", the skill will be usable if you have it, which
# means you won't have to learn another passive skill.
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:
module Xelias
def self.ers_config(item)
# weapon configuration
if item.is_a?(RPG::Weapon)
case item.id
# START Weapon Configuration
when 2 then return [100]
# END Weapon Configuration
end
elsif item.is_a?(RPG::Armor)
case item.id
# START Armor Configuration
when 2 then return [100]
# END Armor Configuration
end
end
return [100]
end
def self.req_skill(id)
case id
# START Skill Configuration
when 8 then return 101
end
return
end
end
class Game_Battler
def states_plus(plus_state_set)
# 有効フラグをクリア
effective = false
# ループ (付加するステート)
for i in plus_state_set
# このステートが防御されていない場合
unless self.state_guard?(i)
# このステートがフルでなければ有効フラグをセット
effective |= self.state_full?(i) == false
# ステートが [抵抗しない] の場合
if $data_states[i].nonresistance
# ステート変化フラグをセット
@state_changed = true
# ステートを付加
add_state(i)
# このステートがフルではない場合
elsif self.state_full?(i) == false
# ステート有効度を確率に変換し、乱数と比
if self.is_a?(Game_Actor) && self.skill_learn?(STATE_RESIST_ID)
if rand(100) < [0,50,40,30,20,10,0][self.state_ranks[i]]
# ステート変化フラグをセット
@state_changed = true
# ステートを付加
add_state(i)
end
end
unless self.is_a?(Game_Actor) && self.skill_learn?(STATE_RESIST_ID)
if rand(100) < [0,100,80,60,40,20,0][self.state_ranks[i]]
@state_changed = true
# ステートを付加
add_state(i)
end
end
end
end
end
# メソッド終了
return effective
end
#==============================================================================
# ■ Game_Battler (分割定義 3)
#------------------------------------------------------------------------------
# バトラーを扱うクラスです。このクラスは Game_Actor クラスと Game_Enemy クラ
# スのスーパークラスとして使用されます。
#==============================================================================
def attack_effect(attacker)
# クリティカルフラグをクリア
self.critical = false
# 第一命中判定
hit_result = (rand(100) < attacker.hit)
# 命中の場合
if hit_result == true
# 基本ダメージを計算
atk = [attacker.atk - self.pdef / 2, 0].max
self.damage = atk * (20 + attacker.str) / 20
if attacker.is_a?(Game_Actor) && attacker.atk == 0
atk = [100 + attacker.str/8 - self.pdef / 2, 0].max
self.damage = atk * (20 + attacker.str) / 20
if attacker.skill_learn?(BRAWLER_ID)
atk = [100 + attacker.str/3 - self.pdef / 2, 0].max
self.damage = atk * (20 + attacker.str) / 20
end
# 属性修正
self.damage *= elements_correct(attacker.element_set)
self.damage /= 100
# ダメージの符号が正の場合
if self.damage > 0
# クリティカル修正
if attacker.is_a?(Game_Actor) && attacker.skill_learn?(CRITICAL_BOOST_ID)
if rand(100) < 6 * attacker.dex / self.agi
self.damage *= 2
self.critical = true
end
else
if rand(100) < 4 * attacker.dex / self.agi
self.damage *= 2
self.critical = true
end
end
end
# 防御修正
if self.guarding?
self.damage /= 2
end
if self.is_a?(Game_Actor) && self.guarding? && self.skill_learn?(GUARD_PLUS_ID)
self.damage /= 2
end
end
# 分散
if self.damage.abs > 0
amp = [self.damage.abs * 15 / 100, 1].max
self.damage += rand(amp+1) + rand(amp+1) - amp
end
# 第二命中判定
eva = 8 * self.agi / attacker.dex + self.eva
hit = self.damage < 0 ? 100 : 100 - eva
hit = self.cant_evade? ? 100 : hit
hit_result = (rand(100) < hit)
end
# 命中の場合
if hit_result == true
# ステート衝撃解除
remove_states_shock
# HP からダメージを減算
if self.is_a?(Game_Actor) && self.skill_learn?(MARTYR_ID)
sp_recovery = self.damage/10
self.sp += sp_recovery
end
if attacker.is_a?(Game_Actor) && attacker.skill_learn?(INQUISITOR_ID)
sp_recovery = self.damage/10
attacker.sp += sp_recovery
end
if attacker.is_a?(Game_Actor) && attacker.skill_learn?(BLOOD_SWORD_ID)
hp_recovery = self.damage/4
attacker.hp += hp_recovery
end
if attacker.is_a?(Game_Actor) && attacker.skill_learn?(ADRENALINE_ID) && ((attacker.hp*100)/attacker.maxhp) < 30
self.damage*= 2
end
if attacker.is_a?(Game_Actor) && attacker.skill_learn?(FOCUS_ID) && attacker.hp = attacker.maxhp
self.damage*= 2
end
if self.is_a?(Game_Actor) && self.skill_learn?(LAST_STAND_ID) && ((self.hp*100)/self.maxhp) < 30
self.damage/= 2
end
if attacker.is_a?(Game_Actor) && attacker.skill_learn?(CHARGED_ATTACKS_ID) && attacker.sp > 0
attacker.sp -= 6
self.damage += self.damage/3
end
if self.is_a?(Game_Actor) && self.skill_learn?(ONCE_MORE_ID) && self.hp > 1 && self.damage > self.hp
self.damage = self.hp - 1
end
if self.is_a?(Game_Actor) && self.skill_learn?(MP_SHIELD_ID) && self.sp > 0
self.sp -= self.damage
else
self.hp -= self.damage
end
# ステート変化
@state_changed = false
states_plus(attacker.plus_state_set)
states_minus(attacker.minus_state_set)
# ミスの場合
else
# ダメージに "Miss" を設定
self.damage = "Manqué!"
# クリティカルフラグをクリア
self.critical = false
end
# メソッド終了
return true
end
#--------------------------------------------------------------------------
# ● スキルの効果適用
# user : スキルの使用者 (バトラー)
# skill : スキル
#--------------------------------------------------------------------------
def skill_effect(user, skill)
# クリティカルフラグをクリア
self.critical = false
# スキルの効果範囲が HP 1 以上の味方で、自分の HP が 0、
# またはスキルの効果範囲が HP 0 の味方で、自分の HP が 1 以上の場合
if ((skill.scope == 3 or skill.scope == 4) and self.hp == 0) or
((skill.scope == 5 or skill.scope == 6) and self.hp >= 1)
# メソッド終了
return false
end
# 有効フラグをクリア
effective = false
# コモンイベント ID が有効の場合は有効フラグをセット
effective |= skill.common_event_id > 0
# 第一命中判定
hit = skill.hit
if skill.atk_f > 0
hit *= user.hit / 100
end
hit_result = (rand(100) < hit)
# 不確実なスキルの場合は有効フラグをセット
effective |= hit < 100
# 命中の場合
if hit_result == true
# 威力を計算
power = skill.power + user.atk * skill.atk_f / 100
if power > 0
power -= self.pdef * skill.pdef_f / 200
power -= self.mdef * skill.mdef_f / 200
power = [power, 0].max
end
# 倍率を計算
rate = 20
rate += (user.str * skill.str_f / 100)
rate += (user.dex * skill.dex_f / 100)
rate += (user.agi * skill.agi_f / 100)
rate += (user.int * skill.int_f / 100)
# 基本ダメージを計算
self.damage = power * rate / 20
# 属性修正
elements = (elements_correct(skill.element_set))
if user.is_a?(Game_Actor) && user.skill_learn?(ELEMENTALISM_ID) && skill.mdef_f > 0
elements += 100
end
if self.is_a?(Game_Actor) && self.skill_learn?(GEOMANCY_ID) && skill.mdef_f > 0
elements -= 50
end
self.damage *= elements
self.damage /= 100
# ダメージの符号が正の場合
if self.damage > 0
# 防御修正
if self.guarding?
self.damage /= 2
end
if self.is_a?(Game_Actor) && self.guarding? && self.skill_learn?(GUARD_PLUS_ID)
self.damage /= 2
end
end
# 分散
if skill.variance > 0 and self.damage.abs > 0
amp = [self.damage.abs * skill.variance / 100, 1].max
self.damage += rand(amp+1) + rand(amp+1) - amp
end
# 第二命中判定
eva = 8 * self.agi / user.dex + self.eva
hit = self.damage < 0 ? 100 : 100 - eva * skill.eva_f / 100
hit = self.cant_evade? ? 100 : hit
hit_result = (rand(100) < hit)
# 不確実なスキルの場合は有効フラグをセット
effective |= hit < 100
end
# 命中の場合
if hit_result == true
# 威力 0 以外の物理攻撃の場合
if skill.power != 0 and skill.atk_f > 0
# ステート衝撃解除
remove_states_shock
# 有効フラグをセット
effective = true
end
# HP からダメージを減算
last_hp = self.hp
if self.is_a?(Game_Actor) && self.skill_learn?(MARTYR_ID)
sp_recovery = self.damage/10
self.sp += sp_recovery
end
if user.is_a?(Game_Actor) && user.skill_learn?(WARMAGE_ID) && self.damage > 0 && skill.mdef_f > 0
sp_recovery = self.damage/10
user.sp += sp_recovery
end
if user.is_a?(Game_Actor) && user.skill_learn?(BLOOD_SWORD_ID) && skill.pdef_f > 0
hp_recovery = self.damage/4
user.hp += hp_recovery
end
if user.is_a?(Game_Actor) && user.skill_learn?(TURBO_MP_ID) && skill.mdef_f > 0
self.damage*=2
end
if user.is_a?(Game_Actor) && user.skill_learn?(SPELLBREAKER_ID) && skill.mdef_f > 0 && ((user.hp*100)/ user.maxhp) < 30
self.damage*=2
end
if user.is_a?(Game_Actor) && user.skill_learn?(ADRENALINE_ID) && skill.pdef_f > 0 && ((user.hp*100)/ user.maxhp) < 30
self.damage*=2
end
if user.is_a?(Game_Actor) && user.skill_learn?(SERENITY_ID) && skill.mdef_f > 0 && user.hp = user.maxhp
self.damage += self.damage/3
end
if user.is_a?(Game_Actor) && user.skill_learn?(FOCUS_ID) && skill.pdef_f > 0 && user.hp = user.maxhp
self.damage += self.damage/3
end
if self.is_a?(Game_Actor) && self.skill_learn?(LAST_STAND_ID) && ((self.hp*100)/self.maxhp) < 30
self.damage/= 2
end
if self.is_a?(Game_Actor) && self.skill_learn?(ONCE_MORE_ID) && self.hp > 1 && self.damage > self.hp
self.damage = self.hp - 1
end
if self.is_a?(Game_Actor) && self.skill_learn?(HEALER_ID) && self.damage < 0
self.damage *= 2
end
if self.is_a?(Game_Actor) && self.skill_learn?(LEARNING_ID) && BLUE_SKILLS_IDS.include?(skill.id)
learn_skill(skill.id)
end
if self.is_a?(Game_Actor) && self.skill_learn?(MP_SHIELD_ID) && self.sp > 0
self.sp -= self.damage
else
self.hp -= self.damage
end
effective |= self.hp != last_hp
# ステート変化
@state_changed = false
effective |= states_plus(skill.plus_state_set)
effective |= states_minus(skill.minus_state_set)
# 威力が 0 の場合
if skill.power == 0
# ダメージに空文字列を設定
self.damage = ""
# ステートに変化がない場合
unless @state_changed
# ダメージに "Miss" を設定
self.damage = "Manqué!"
end
end
# ミスの場合
else
# ダメージに "Miss" を設定
self.damage = "Manqué!"
end
# 戦闘中でない場合
unless $game_temp.in_battle
# ダメージに nil を設定
self.damage = nil
end
# メソッド終了
return effective
end
#--------------------------------------------------------------------------
# ● アイテムの効果適用
# item : アイテム
#--------------------------------------------------------------------------
def item_effect(item)
# クリティカルフラグをクリア
self.critical = false
# アイテムの効果範囲が HP 1 以上の味方で、自分の HP が 0、
# またはアイテムの効果範囲が HP 0 の味方で、自分の HP が 1 以上の場合
if ((item.scope == 3 or item.scope == 4) and self.hp == 0) or
((item.scope == 5 or item.scope == 6) and self.hp >= 1)
# メソッド終了
return false
end
# 有効フラグをクリア
effective = false
# コモンイベント ID が有効の場合は有効フラグをセット
effective |= item.common_event_id > 0
# 命中判定
hit_result = (rand(100) < item.hit)
# 不確実なスキルの場合は有効フラグをセット
effective |= item.hit < 100
# 命中の場合
if hit_result == true
# 回復量を計算
recover_hp = maxhp * item.recover_hp_rate / 100 + item.recover_hp
recover_sp = maxsp * item.recover_sp_rate / 100 + item.recover_sp
if recover_hp < 0
recover_hp += self.pdef * item.pdef_f / 20
recover_hp += self.mdef * item.mdef_f / 20
recover_hp = [recover_hp, 0].min
end
# 属性修正
recover_hp *= elements_correct(item.element_set)
recover_hp /= 100
recover_sp *= elements_correct(item.element_set)
recover_sp /= 100
# 分散
if item.variance > 0 and recover_hp.abs > 0
amp = [recover_hp.abs * item.variance / 100, 1].max
recover_hp += rand(amp+1) + rand(amp+1) - amp
end
if item.variance > 0 and recover_sp.abs > 0
amp = [recover_sp.abs * item.variance / 100, 1].max
recover_sp += rand(amp+1) + rand(amp+1) - amp
end
# 回復量の符号が負の場合
if recover_hp < 0
# 防御修正
if self.guarding?
recover_hp /= 2
end
end
# HP 回復量の符号を反転し、ダメージの値に設定
if self.is_a?(Game_Actor) && self.skill_learn?(HEALER_ID) && recover.hp > 0
recover_hp *= 2
end
self.damage = -recover_hp
# HP および SP を回復
last_hp = self.hp
last_sp = self.sp
self.hp += recover_hp
self.sp += recover_sp
effective |= self.hp != last_hp
effective |= self.sp != last_sp
# ステート変化
@state_changed = false
effective |= states_plus(item.plus_state_set)
effective |= states_minus(item.minus_state_set)
# パラメータ上昇値が有効の場合
if item.parameter_type > 0 and item.parameter_points != 0
# パラメータで分岐
case item.parameter_type
when 1 # MaxHP
@maxhp_plus += item.parameter_points
when 2 # MaxSP
@maxsp_plus += item.parameter_points
when 3 # 腕力
@str_plus += item.parameter_points
when 4 # 器用さ
@dex_plus += item.parameter_points
when 5 # 素早さ
@agi_plus += item.parameter_points
when 6 # 魔力
@int_plus += item.parameter_points
end
# 有効フラグをセット
effective = true
end
# HP 回復率と回復量が 0 の場合
if item.recover_hp_rate == 0 and item.recover_hp == 0
# ダメージに空文字列を設定
self.damage = ""
# SP 回復率と回復量が 0、パラメータ上昇値が無効の場合
if item.recover_sp_rate == 0 and item.recover_sp == 0 and
(item.parameter_type == 0 or item.parameter_points == 0)
# ステートに変化がない場合
unless @state_changed
# ダメージに "Miss" を設定
self.damage = "Manqué!"
end
end
end
# ミスの場合
else
# ダメージに "Miss" を設定
self.damage = "Manqué!"
end
# 戦闘中でない場合
unless $game_temp.in_battle
# ダメージに nil を設定
self.damage = nil
end
# メソッド終了
return effective
end
#--------------------------------------------------------------------------
# ● スリップダメージの効果適用
#--------------------------------------------------------------------------
def slip_damage_effect
# ダメージを設定
self.damage = self.maxhp / 10
# 分散
if self.damage.abs > 0
amp = [self.damage.abs * 15 / 100, 1].max
self.damage += rand(amp+1) + rand(amp+1) - amp
end
# HP からダメージを減算
self.hp -= self.damage
# メソッド終了
return true
end
end
class Scene_Battle
def make_skill_action_result
# スキルを取得
@skill = $data_skills[@active_battler.current_action.skill_id]
# 強制アクションでなければ
unless @active_battler.current_action.forcing
# SP 切れなどで使用できなくなった場合
unless @active_battler.skill_can_use?(@skill.id)
# アクション強制対象のバトラーをクリア
$game_temp.forcing_battler = nil
# ステップ 1 に移行
@phase4_step = 1
return
end
end
if @active_battler.is_a?(Game_Actor) && @active_battler.skill_learn?(DEMI_MP_ID)
@skill.sp_cost/=2
end
if @active_battler.is_a?(Game_Actor) && @active_battler.skill_learn?(TURBO_MP_ID)
@skill.sp_cost*=2
end
# SP 消費
if @active_battler.is_a?(Game_Actor) && @active_battler.skill_learn?(BLOOD_PRICE_ID)
@active_battler.hp -= (@skill.sp_cost *5 )
else
@active_battler.sp -= @skill.sp_cost
end
# ステータスウィンドウをリフレッシュ
@status_window.refresh
# ヘルプウィンドウにスキル名を表示
@help_window.set_text(@skill.name, 1)
# アニメーション ID を設定
@animation1_id = @skill.animation1_id
@animation2_id = @skill.animation2_id
# コモンイベント ID を設定
@common_event_id = @skill.common_event_id
# 対象側バトラーを設定
set_target_battlers(@skill.scope)
# スキルの効果を適用
for target in @target_battlers
target.skill_effect(@active_battler, @skill)
end
end
end
#==============================================================================
# ■ Window_Passive
#------------------------------------------------------------------------------
# スキル画面、バトル画面で、使用できるスキルの一覧を表示するウィンドウです。
#==============================================================================
class Window_Passive < Window_Selectable
#--------------------------------------------------------------------------
# ● オブジェクト初期化
# actor : アクター
#--------------------------------------------------------------------------
def initialize(actor)
super(0, 128, 640, 352)
@actor = actor
@column_max = 2
refresh
self.index = 0
# 戦闘中の場合はウィンドウを画面中央へ移動し、半透明にする
if $game_temp.in_battle
self.y = 64
self.height = 256
self.back_opacity = 160
end
end
#--------------------------------------------------------------------------
# ● スキルの取得
#--------------------------------------------------------------------------
def skill
return @data[self.index]
end
#--------------------------------------------------------------------------
# ● リフレッシュ
#--------------------------------------------------------------------------
def refresh
if self.contents != nil
self.contents.dispose
self.contents = nil
end
@data = []
for i in 0...@actor.skills.size
skill = $data_skills[@actor.skills[i]]
if skill != nil && PASSIVE_SKILLS_IDS.include?(skill.id)
@data.push(skill)
end
end
# 項目数が 0 でなければビットマップを作成し、全項目を描画
@item_max = @data.size
if @item_max > 0
self.contents = Bitmap.new(width - 32, row_max * 32)
self.contents.font.name = $fontface
self.contents.font.size = $fontsize
for i in 0...@item_max
draw_item(i)
end
end
end
#--------------------------------------------------------------------------
# ● 項目の描画
# index : 項目番号
#--------------------------------------------------------------------------
def draw_item(index)
skill = @data[index]
self.contents.font.color = normal_color
x = 4 + index % 2 * (288 + 32)
y = index / 2 * 32
rect = Rect.new(x, y, self.width / @column_max - 32, 32)
self.contents.fill_rect(rect, Color.new(0, 0, 0, 0))
bitmap = RPG::Cache.icon(skill.icon_name)
opacity = self.contents.font.color == normal_color ? 255 : 128
self.contents.blt(x, y + 4, bitmap, Rect.new(0, 0, 24, 24), opacity)
self.contents.draw_text(x + 28, y, 204, 32, skill.name, 0)
end
#--------------------------------------------------------------------------
# ● ヘルプテキスト更新
#--------------------------------------------------------------------------
def update_help
@help_window.set_text(self.skill == nil ? "" : self.skill.description)
end
end
#==============================================================================
# ■ Scene_Skill
#------------------------------------------------------------------------------
# スキル画面の処理を行うクラスです。
#==============================================================================
class Scene_Passive
#--------------------------------------------------------------------------
# ● オブジェクト初期化
# actor_index : アクターインデックス
#--------------------------------------------------------------------------
def initialize(actor_index = 0, equip_index = 0)
@actor_index = actor_index
end
#--------------------------------------------------------------------------
# ● メイン処理
#--------------------------------------------------------------------------
def main
# アクターを取得
@actor = $game_party.actors[@actor_index]
# ヘルプウィンドウ、ステータスウィンドウ、スキルウィンドウを作成
@help_window = Window_Help.new
@status_window = Window_SkillStatus.new(@actor)
@skill_window = Window_Passive.new(@actor)
# ヘルプウィンドウを関連付け
@skill_window.help_window = @help_window
# ターゲットウィンドウを作成 (不可視・非アクティブに設定)
@target_window = Window_Target.new
@target_window.visible = false
@target_window.active = false
# トランジション実行
Graphics.transition
# メインループ
loop do
# ゲーム画面を更新
Graphics.update
# 入力情報を更新
Input.update
# フレーム更新
update
# 画面が切り替わったらループを中断
if $scene != self
break
end
end
# トランジション準備
Graphics.freeze
# ウィンドウを解放
@help_window.dispose
@status_window.dispose
@skill_window.dispose
@target_window.dispose
end
#--------------------------------------------------------------------------
# ● フレーム更新
#--------------------------------------------------------------------------
def update
# ウィンドウを更新
@help_window.update
@status_window.update
@skill_window.update
@target_window.update
# スキルウィンドウがアクティブの場合: update_skill を呼ぶ
if @skill_window.active
update_skill
return
end
# ターゲットウィンドウがアクティブの場合: update_target を呼ぶ
if @target_window.active
update_target
return
end
end
#--------------------------------------------------------------------------
# ● フレーム更新 (スキルウィンドウがアクティブの場合)
#--------------------------------------------------------------------------
def update_skill
# B ボタンが押された場合
if Input.trigger?(Input::B)
# キャンセル SE を演奏
$game_system.se_play($data_system.cancel_se)
# メニュー画面に切り替え
$scene = Scene_Menu.new(2)
return
end
# C ボタンが押された場合
if Input.trigger?(Input::C)
# スキルウィンドウで現在選択されているデータを取得
@skill = @skill_window.skill
# 使用できない場合
if @skill == nil or not @actor.skill_can_use?(@skill.id)
# ブザー SE を演奏
$game_system.se_play($data_system.buzzer_se)
return
end
# 決定 SE を演奏
$game_system.se_play($data_system.decision_se)
# 効果範囲が味方の場合
if @skill.scope >= 3
# ターゲットウィンドウをアクティブ化
@skill_window.active = false
@target_window.x = (@skill_window.index + 1) % 2 * 304
@target_window.visible = true
@target_window.active = true
# 効果範囲 (単体/全体) に応じてカーソル位置を設定
if @skill.scope == 4 || @skill.scope == 6
@target_window.index = -1
elsif @skill.scope == 7
@target_window.index = @actor_index - 10
else
@target_window.index = 0
end
# 効果範囲が味方以外の場合
else
# コモンイベント ID が有効の場合
if @skill.common_event_id > 0
# コモンイベント呼び出し予約
$game_temp.common_event_id = @skill.common_event_id
# スキルの使用時 SE を演奏
$game_system.se_play(@skill.menu_se)
# SP 消費
@actor.sp -= @skill.sp_cost
# 各ウィンドウの内容を再作成
@status_window.refresh
@skill_window.refresh
@target_window.refresh
# マップ画面に切り替え
$scene = Scene_Map.new
return
end
end
return
end
# R ボタンが押された場合
if Input.trigger?(Input::R)
# カーソル SE を演奏
$game_system.se_play($data_system.cursor_se)
# 次のアクターへ
@actor_index += 1
@actor_index %= $game_party.actors.size
# 別のスキル画面に切り替え
$scene = Scene_Skill.new(@actor_index)
return
end
# L ボタンが押された場合
if Input.trigger?(Input::L)
# カーソル SE を演奏
$game_system.se_play($data_system.cursor_se)
# 前のアクターへ
@actor_index += $game_party.actors.size - 1
@actor_index %= $game_party.actors.size
# 別のスキル画面に切り替え
$scene = Scene_Skill.new(@actor_index)
return
end
end
#--------------------------------------------------------------------------
# ● フレーム更新 (ターゲットウィンドウがアクティブの場合)
#--------------------------------------------------------------------------
def update_target
# B ボタンが押された場合
if Input.trigger?(Input::B)
# キャンセル SE を演奏
$game_system.se_play($data_system.cancel_se)
# ターゲットウィンドウを消去
@skill_window.active = true
@target_window.visible = false
@target_window.active = false
return
end
# C ボタンが押された場合
if Input.trigger?(Input::C)
# SP 切れなどで使用できなくなった場合
unless @actor.skill_can_use?(@skill.id)
# ブザー SE を演奏
$game_system.se_play($data_system.buzzer_se)
return
end
# ターゲットが全体の場合
if @target_window.index == -1
# パーティ全体にスキルの使用効果を適用
used = false
for i in $game_party.actors
used |= i.skill_effect(@actor, @skill)
end
end
# ターゲットが使用者の場合
if @target_window.index <= -2
# ターゲットのアクターにスキルの使用効果を適用
target = $game_party.actors[@target_window.index + 10]
used = target.skill_effect(@actor, @skill)
end
# ターゲットが単体の場合
if @target_window.index >= 0
# ターゲットのアクターにスキルの使用効果を適用
target = $game_party.actors[@target_window.index]
used = target.skill_effect(@actor, @skill)
end
# スキルを使った場合
if used
# スキルの使用時 SE を演奏
$game_system.se_play(@skill.menu_se)
# SP 消費
@actor.sp -= @skill.sp_cost
# 各ウィンドウの内容を再作成
@status_window.refresh
@skill_window.refresh
@target_window.refresh
# 全滅の場合
if $game_party.all_dead?
# ゲームオーバー画面に切り替え
$scene = Scene_Gameover.new
return
end
# コモンイベント ID が有効の場合
if @skill.common_event_id > 0
# コモンイベント呼び出し予約
$game_temp.common_event_id = @skill.common_event_id
# マップ画面に切り替え
$scene = Scene_Map.new
return
end
end
# スキルを使わなかった場合
unless used
# ブザー SE を演奏
$game_system.se_play($data_system.buzzer_se)
end
return
end
end
end
#==============================================================================
# ■ Scene_Menu
#------------------------------------------------------------------------------
# メニュー画面の処理を行うクラスです。
#==============================================================================
class Scene_Menu
#--------------------------------------------------------------------------
# ● オブジェクト初期化
# menu_index : コマンドのカーソル初期位置
#--------------------------------------------------------------------------
def initialize(menu_index = 0)
@menu_index = menu_index
end
#--------------------------------------------------------------------------
# ● メイン処理
#--------------------------------------------------------------------------
def main
# コマンドウィンドウを作成
s1 = $data_system.words.item
s2 = $data_system.words.skill
s3 = PASSIVE_WORD
s4 = $data_system.words.equip
s5 = "État"
s6 = "Sauvegarder"
s7 = "Quitter"
@command_window = Window_Command.new(160, [s1, s2, s3, s4, s5, s6])
@command_window.index = @menu_index
# パーティ人数が 0 人の場合
if $game_party.actors.size == 0
# アイテム、スキル、装備、ステータスを無効化
@command_window.disable_item(0)
@command_window.disable_item(1)
@command_window.disable_item(2)
@command_window.disable_item(3)
end
# セーブ禁止の場合
if $game_system.save_disabled
# セーブを無効にする
@command_window.disable_item(4)
end
# プレイ時間ウィンドウを作成
@playtime_window = Window_PlayTime.new
@playtime_window.x = 0
@playtime_window.y = 224
# 歩数ウィンドウを作成
@steps_window = Window_Steps.new
@steps_window.x = 0
@steps_window.y = 320
# ゴールドウィンドウを作成
@gold_window = Window_Gold.new
@gold_window.x = 0
@gold_window.y = 416
# ステータスウィンドウを作成
@status_window = Window_MenuStatus.new
@status_window.x = 160
@status_window.y = 0
# トランジション実行
Graphics.transition
# メインループ
loop do
# ゲーム画面を更新
Graphics.update
# 入力情報を更新
Input.update
# フレーム更新
update
# 画面が切り替わったらループを中断
if $scene != self
break
end
end
# トランジション準備
Graphics.freeze
# ウィンドウを解放
@command_window.dispose
@playtime_window.dispose
@steps_window.dispose
@gold_window.dispose
@status_window.dispose
end
#--------------------------------------------------------------------------
# ● フレーム更新
#--------------------------------------------------------------------------
def update
# ウィンドウを更新
@command_window.update
@playtime_window.update
@steps_window.update
@gold_window.update
@status_window.update
# コマンドウィンドウがアクティブの場合: update_command を呼ぶ
if @command_window.active
update_command
return
end
# ステータスウィンドウがアクティブの場合: update_status を呼ぶ
if @status_window.active
update_status
return
end
end
#--------------------------------------------------------------------------
# ● フレーム更新 (コマンドウィンドウがアクティブの場合)
#--------------------------------------------------------------------------
def update_command
# B ボタンが押された場合
if Input.trigger?(Input::B)
# キャンセル SE を演奏
$game_system.se_play($data_system.cancel_se)
# マップ画面に切り替え
$scene = Scene_Map.new
return
end
# C ボタンが押された場合
if Input.trigger?(Input::C)
# パーティ人数が 0 人で、セーブ、ゲーム終了以外のコマンドの場合
if $game_party.actors.size == 0 and @command_window.index < 4
# ブザー SE を演奏
$game_system.se_play($data_system.buzzer_se)
return
end
# コマンドウィンドウのカーソル位置で分岐
case @command_window.index
when 0 # アイテム
# 決定 SE を演奏
$game_system.se_play($data_system.decision_se)
# アイテム画面に切り替え
$scene = Scene_Item.new
when 1 # スキル
# 決定 SE を演奏
$game_system.se_play($data_system.decision_se)
# ステータスウィンドウをアクティブにする
@command_window.active = false
@status_window.active = true
@status_window.index = 0
when 2 # スキル
# 決定 SE を演奏
$game_system.se_play($data_system.decision_se)
# ステータスウィンドウをアクティブにする
@command_window.active = false
@status_window.active = true
@status_window.index = 0
when 3 # 装備
# 決定 SE を演奏
$game_system.se_play($data_system.decision_se)
# ステータスウィンドウをアクティブにする
@command_window.active = false
@status_window.active = true
@status_window.index = 0
when 4 # ステータス
# 決定 SE を演奏
$game_system.se_play($data_system.decision_se)
# ステータスウィンドウをアクティブにする
@command_window.active = false
@status_window.active = true
@status_window.index = 0
when 5 # セーブ
# セーブ禁止の場合
if $game_system.save_disabled
# ブザー SE を演奏
$game_system.se_play($data_system.buzzer_se)
return
end
# 決定 SE を演奏
$game_system.se_play($data_system.decision_se)
# セーブ画面に切り替え
$scene = Scene_Save.new
when 6 # ゲーム終了
# 決定 SE を演奏
$game_system.se_play($data_system.decision_se)
# ゲーム終了画面に切り替え
$scene = Scene_End.new
end
return
end
end
#--------------------------------------------------------------------------
# ● フレーム更新 (ステータスウィンドウがアクティブの場合)
#--------------------------------------------------------------------------
def update_status
# B ボタンが押された場合
if Input.trigger?(Input::B)
# キャンセル SE を演奏
$game_system.se_play($data_system.cancel_se)
# コマンドウィンドウをアクティブにする
@command_window.active = true
@status_window.active = false
@status_window.index = -1
return
end
# C ボタンが押された場合
if Input.trigger?(Input::C)
# コマンドウィンドウのカーソル位置で分岐
case @command_window.index
when 1 # スキル
# このアクターの行動制限が 2 以上の場合
if $game_party.actors[@status_window.index].restriction >= 2
# ブザー SE を演奏
$game_system.se_play($data_system.buzzer_se)
return
end
# 決定 SE を演奏
$game_system.se_play($data_system.decision_se)
# スキル画面に切り替え
$scene = Scene_Skill.new(@status_window.index)
when 2 # スキル
# このアクターの行動制限が 2 以上の場合
if $game_party.actors[@status_window.index].restriction >= 2
# ブザー SE を演奏
$game_system.se_play($data_system.buzzer_se)
return
end
# 決定 SE を演奏
$game_system.se_play($data_system.decision_se)
# スキル画面に切り替え
$scene = Scene_Passive.new(@status_window.index)
when 3 # 装備
# 決定 SE を演奏
$game_system.se_play($data_system.decision_se)
# 装備画面に切り替え
$scene = Scene_Equip.new(@status_window.index)
when 4 # ステータス
# 決定 SE を演奏
$game_system.se_play($data_system.decision_se)
# ステータス画面に切り替え
$scene = Scene_Status.new(@status_window.index)
end
return
end
end
end
#==============================================================================
# ■ Window_Skill
#------------------------------------------------------------------------------
# スキル画面、バトル画面で、使用できるスキルの一覧を表示するウィンドウです。
#==============================================================================
class Window_Skill < Window_Selectable
#--------------------------------------------------------------------------
# ● オブジェクト初期化
# actor : アクター
#--------------------------------------------------------------------------
def initialize(actor)
super(0, 128, 640, 352)
@actor = actor
@column_max = 2
refresh
self.index = 0
# 戦闘中の場合はウィンドウを画面中央へ移動し、半透明にする
if $game_temp.in_battle
self.y = 64
self.height = 256
self.back_opacity = 160
end
end
#--------------------------------------------------------------------------
# ● スキルの取得
#--------------------------------------------------------------------------
def skill
return @data[self.index]
end
#--------------------------------------------------------------------------
# ● リフレッシュ
#--------------------------------------------------------------------------
def refresh
if self.contents != nil
self.contents.dispose
self.contents = nil
end
@data = []
for i in 0...@actor.skills.size
skill = $data_skills[@actor.skills[i]]
if skill != nil && PASSIVE_SKILLS_IDS.include?(skill.id)
elsif skill != nil
@data.push(skill)
end
end
# 項目数が 0 でなければビットマップを作成し、全項目を描画
@item_max = @data.size
if @item_max > 0
self.contents = Bitmap.new(width - 32, row_max * 32)
self.contents.font.name = $fontface
self.contents.font.size = $fontsize
for i in 0...@item_max
draw_item(i)
end
end
end
#--------------------------------------------------------------------------
# ● 項目の描画
# index : 項目番号
#--------------------------------------------------------------------------
def draw_item(index)
skill = @data[index]
if @actor.skill_can_use?(skill.id)
self.contents.font.color = normal_color
else
self.contents.font.color = disabled_color
end
x = 4 + index % 2 * (288 + 32)
y = index / 2 * 32
rect = Rect.new(x, y, self.width / @column_max - 32, 32)
self.contents.fill_rect(rect, Color.new(0, 0, 0, 0))
bitmap = RPG::Cache.icon(skill.icon_name)
opacity = self.contents.font.color == normal_color ? 255 : 128
self.contents.blt(x, y + 4, bitmap, Rect.new(0, 0, 24, 24), opacity)
self.contents.draw_text(x + 28, y, 204, 32, skill.name, 0)
if skill.sp_cost > 0
self.contents.draw_text(x + 232, y, 48, 32, skill.sp_cost.to_s, 2)
end
end
#--------------------------------------------------------------------------
# ● ヘルプテキスト更新
#--------------------------------------------------------------------------
def update_help
@help_window.set_text(self.skill == nil ? "" : self.skill.description)
end
end
class Game_Actor < Game_Battler
def animation1_id
weapon = $data_weapons[@weapon_id]
return weapon != nil ? weapon.animation1_id : BARE_ANIMATION_SELF_ID
end
def animation2_id
weapon = $data_weapons[@weapon_id]
return weapon != nil ? weapon.animation2_id : BARE_ANIMATION_ID
end
end
class Scene_Equip
alias update_item_ers_later update_item
def update_item
itemskill = Xelias.ers_config(@item_window.item)
if Input.trigger?(Input::C)
unless (@actor.skill_learn?(itemskill[0]))
$game_system.se_play($data_system.buzzer_se)
return
end
end
update_item_ers_later
end
end
class Game_Battler
alias skill_met? skill_can_use?
if is_a?(Game_Actor)
def skill_can_use?(skill_id)
data = Xelias.req_skill(skill_id)
unless skill_learn?(data) ? false : skill_met?(skill_id)
return data != nil
end
end
end
end
Instructions
Place it above main. Other instructions in the script.
Compatibility
Causes problems with exotic CMS.
Although that can be fixed by :
*Deleting the "Scene_Menu", "Scene_Skill", "Window_Skill", "Window_Passive" and Scene_Passive" part of the script
*Copying and pasting your CMS's Scene_Skill and Window_Skill so you have two of them.
*Modifying its class from Scene_Skill to Scene_Passive and Window_Skill to Window_Passive
*Searching for the line
if skill != nil
@data.push(skill)
in Window_Passive and replacing it by
if skill != nil && PASSIVE_SKILLS_IDS.include?(skill.id)
@data.push(skill)
*Searching for the line
@skill_window = Window_Skill.new(@actor)
in Scene_Passive and replacing it with
@skill_window = Window_Passive.new(@actor)
*Searching for the line
if skill != nil
@data.push(skill)
in Window_Skill and replacing it by
if skill != nil && PASSIVE_SKILLS_IDS.include?(skill.id)
elsif skill != nil
@data.push(skill)
*Going to Scene_Menu and adding the command
Scene = Scene_Passive.new
I cannot explain to you where you should put it, cause the location changes with Menus...
For exotic CBS, I'm not sure...
Hopefully, works with Blizzard's Passive Skills.
Credits and Thanks
- Xelias, for making this script
- NAMKCOR, for allowing the "Equip Weapon/Armor" Passive Skills scriptlet, which is a derived of his "Equipment Requirement System"
- [Faint], for allowing the "Use Skill" Passive Skills scriptlet, which is a derived of his "State Requirement Skills"
Author's Notes
- On a side note, I modified a little something in the "Skill Menu" : if a skill has a SP cost of 0, the "0" is not displayed.
- On another side, I would like a good scripter to help me solving a little problem : with the Demi MP ability, only half of the SP is paid, but the same SP cost is represented. Idem for Turbo MP.