=begin
很多游戏都有被动技能,所谓被动技能就是学会后不能使用,但有这样那样自动
效果的技能,比如增加HP,增加力量,增加防御等等.RMXP原本是没有被动技能的
设定的,增加这些值只能依靠武器防具装备和状态等.不过,要实现被动技能并不
复杂,甚至你可以通过数据库来设定被动技能的效果.
心得:一直就很想做这样一个系统,又不甘心到脚本里去用case..../if...这样
的条件分歧来手工一条条设定技能效果(因为麻烦,不通用,想改还不好改).不过
,在彻底了解了数据库的格式后,被动技能的系统便水到渠成了.
本文虽然算是脚本发布,但更重的偏重于教学吧
被动技能的实现原理:
1.通过将该技能的使用场合设定为"不能使用"来明确声明这个技能是一个被动技
能(其实也没想到RMXP会在数据库中留这一手)
2.重新定义技能的各项数值,让它们成为被动技能的加成值,我这里用了一个充分
利用每一格,但同时兼顾直观并充分利用空间的定义方法
3.在Game_Actor里,通过修改取得的各种数据判定,追加被动技能的实际效果
这个脚本发布的被动技能,其设定方法如下:
可能使用时: 不能使用 (重要,这是识别被动技能的标志也是惟一的标志,凡是设
定成这样的技能,不论其他设定如何,都会被认为是被动技能)
效果范围: 无 (这个实际上可以控制被动技能的分页,这一项有8条,也就可以设定
8页,每一页上的各个格子都可以赋予某个意义,原则上,你可以想出的任何千差万别
的被动技能都可以定义出来) 作为示范,脚本中所有的被动技效果,都是在效果范围
设成"无"时的效果,如果你设成其他的,就会失效(你可以自己去定义)
动画/SE/公共事件, 反正技能用不了,也没意义....留空就行了
下面那些格子是关键所在:
消费SP : 这是一个设定范围在0到9999间的格子,脚本中,我将它用做其他格子数值
正负的开关(因为很多格子不能设定负数),每个二进制位控制一个格子,9999以下可
以写出14个二进制位,足够使用了(只需要用10个),特别的,在本脚本中,当消费SP的
第12位被置成1时(其值为2048),代表被动技能效果"物理攻击强制命中"
威力 : 这是12格中惟一一个允许设定负数的格子,所以我将它和右边的属性/状态联
系起来(因为那两栏是无限扩展的,不好用消费SP的值来控制正负数开关)
余下的格子,除了攻击力F是0-200范围外,其余都是0-100,不过已经够了,基本上可以
满足脚本中使用功能的需要
攻击力F: 设为0以外的数值时,角色攻击力将增加(减少)这个数值的百分比
回避F: 设为0以外的数值时,角色回避力将增加(减少)这个数值的百分比
力量F: 设为0以外的数值时,角色力量将......百分比
灵巧F: 设为0以外的数值时,角色灵巧将......百分比
速度F: ........速度.....百分比
魔力F: .......魔力....百分比
防御力F: .....防御力.....
魔防力F: .....魔防力.....
只有"命中率"和"分散"两个值特殊,这里我将它们用做了MaxHP和MaxSP增加的百分比
数值的正负,通过消费SP值的二进制位来控制,从"攻击力"到"分散",按照格子的排列
顺序,对应消费SP值的第1位到第10位.某一位置1,这一格的值就会按负数计算
因为大多数情况下被动技能不太可能有降低属性值的效果,所以可能不会碰到这么复
杂的设定,这里只是留一个功能以防需要时使用.
然后说一下右边那两排:
属性: 打勾的话,对应属性的防御度,会增加(威力)的数值
如果你想要实现属性相克的效果,比如提升火属性防御度会降低冰属性防御度,
也简单, 将"状态"那一栏里,横向相对的那一个状态打上减号,那么这个属性防御就会
减低(脚本中减低的数值是威力值的一半,你可以修改这个比率)
状态: 刚说了,这个是控制属性增减符号的,如果你想用它来控制状态,把属性里所有的
格子全部留空不打勾就可以了,这时,打了+状态属性的防御度,会增加(威力)的数值(更
不容易中这个状态),打了-状态属性的防御度,则会降低(威力)的数值(更容易中这个状态).
另外,如果你把SP消费的第11位置成1(值1024),那么+和-的定义会发生改变:打了
+状态,会变成角色的自动状态(就像你穿上有自动状态的防具一样),打了-的状态,则会
变成完全免疫的状态(就像防具的防御状态一样).
例子: 一个学会后增加力量值百分之六十的技能
可以看到,以上的讨论,都是基于"被动技能是给角色增减能力"的情况,如果你要实现更
多的功能,比如"一人装备,全队生效",比如"己方装备,对敌人有效果",的情况,就要修改
Game_Party或Game_Enemy的相关部分.这个脚本仅仅限于对Game_Actor的修改(少量Game
_Battler,仅一处),在大多数情况下,已经够用了,基本能力的加成全都可以解决.
被动技能生效的前提是学会这个技能, 如果你想实现像装备那样有栏位的....其实我已
经做到了,考虑到这个是我自己游戏系统比较核心的部分,就先暂缓放出来了....
脚本,加了注释的,稍微通一些RGSS就能看出来其实这个系统实际上并不复杂(基本就是把
各个角色能力值全部重新定义一遍),只是难度比较高(因为牵涉到对数据库解释器的修改).
=end
#--------------------------------------------------------------------------
# □ RPG::Skill
#--------------------------------------------------------------------------
module RPG
class Skill
#--------------------------------------------------------------------------
# ● 特技类型 (0 : 攻击, 1 : 回复, 2 : 支援, 3 : 被动)
#--------------------------------------------------------------------------
def type
if @occasion == 3
return 3
elsif @power == 0 and @atk_f == 0
return 2
elsif @power < 0
return 1
else
return 0
end
end
#--------------------------------------------------------------------------
# ● 被动技判定
#--------------------------------------------------------------------------
def innate?
return (type == 3)
end
#--------------------------------------------------------------------------
# ● 获得被动特技类型
# skill : 特技
#--------------------------------------------------------------------------
def innate_type
# 不是被动特技的情况下
if not innate?
return -1
end
case @scope
when 0
# 属性防御类特技
if @element_set != []
return 1
# 状态防御类特技
elsif @minus_state_set != [] or @plus_state_set != []
return 2
# 数值加成类特技
else
return 0
end
when 1
return 3
end
end
#--------------------------------------------------------------------------
# ● 判断增加或减少
# index : 判断项目
#--------------------------------------------------------------------------
def sign(index)
unless innate?
return 0
end
if index >= 0
return (@sp_cost & (2 ** index) == 2 ** index) ? -1 : 1
else
case innate_type
when 0
return 0
when 1
return @minus_state_set.include?(-index) ? -0.5 : 1
when 2
return (@sp_cost & 1024 == 1024) ? true : false
end
end
end
#--------------------------------------------------------------------------
# ● 最大 HP 上升量
#--------------------------------------------------------------------------
def maxhp_plus
return (innate? and innate_type <= 2) ? @hit * sign(6) : 0
end
#--------------------------------------------------------------------------
# ● 最大 SP 上升量
#--------------------------------------------------------------------------
def maxsp_plus
return (innate? and innate_type <= 2) ? @variance * sign(9) : 0
end
#--------------------------------------------------------------------------
# ● 力量上升量
#--------------------------------------------------------------------------
def str_plus
return (innate? and innate_type <= 2) ? @str_f * sign(2) : 0
end
#--------------------------------------------------------------------------
# ● 灵巧上升量
#--------------------------------------------------------------------------
def dex_plus
return (innate? and innate_type <= 2) ? @dex_f * sign(3): 0
end
#--------------------------------------------------------------------------
# ● 速度上升量
#--------------------------------------------------------------------------
def agi_plus
return (innate? and innate_type <= 2) ? @agi_f * sign(4) : 0
end
#--------------------------------------------------------------------------
# ● 魔力上升量
#--------------------------------------------------------------------------
def int_plus
return (innate? and innate_type <= 2) ? @int_f * sign(5) : 0
end
#--------------------------------------------------------------------------
# ● 攻击力上升量
#--------------------------------------------------------------------------
def atk_plus
return (innate? and innate_type <= 2) ? @atk_f * sign(0) : 0
end
#--------------------------------------------------------------------------
# ● 防御力上升量
#--------------------------------------------------------------------------
def pdef_plus
return (innate? and innate_type <= 2) ? @pdef_f * sign(7) : 0
end
#--------------------------------------------------------------------------
# ● 魔防力上升量
#--------------------------------------------------------------------------
def mdef_plus
return (innate? and innate_type <= 2) ? @mdef_f * sign(8) : 0
end
#--------------------------------------------------------------------------
# ● 回避修正上升量
#--------------------------------------------------------------------------
def eva_plus
return (innate? and innate_type <= 2) ? @eva_f * sign(1) : 0
end
#--------------------------------------------------------------------------
# ● 属性防御上升量
# element_id : 属性ID
#--------------------------------------------------------------------------
def element_plus(element_id)
unless innate? and innate_type == 1
return 0
else
if @element_set.include?(element_id)
return Integer(@power * sign(-element_id))
else
return 0
end
end
end
#--------------------------------------------------------------------------
# ● 状态防御上升量
# state_id : 状态ID
#--------------------------------------------------------------------------
def state_plus(state_id)
unless innate? and innate_type == 2 and not sign(-1)
return 0
else
if @plus_state_set.include?(state_id)
return @power
elsif @minus_state_set.include?(state_id)
return -@power
else
return 0
end
end
end
#--------------------------------------------------------------------------
# ● 状态防御集合
#--------------------------------------------------------------------------
def guard_state_set
return (innate? and innate_type == 2 and sign(-1)) ? @minus_state_set : []
end
#--------------------------------------------------------------------------
# ● 自动状态集合
#--------------------------------------------------------------------------
def auto_states
return (innate? and innate_type == 2 and sign(-1)) ? @plus_state_set : []
end
end
end
#==============================================================================
# ■ Game_Actor (分割定义 2)
#------------------------------------------------------------------------------
# 处理角色的类。本类在 Game_Actors 类 ($game_actors)
# 的内部使用、Game_Party 类请参考 ($game_party) 。
#==============================================================================
class Game_Actor
#--------------------------------------------------------------------------
# ● 定义实例变量
#--------------------------------------------------------------------------
attr_reader :innate_skills # 被动特技
alias sailcat_setup setup
alias sailcat_learn_skill learn_skill
alias sailcat_forget_skill forget_skill
alias sailcat_base_maxhp base_maxhp
alias sailcat_base_maxsp base_maxsp
alias sailcat_base_str base_str
alias sailcat_base_dex base_dex
alias sailcat_base_agi base_agi
alias sailcat_base_int base_int
alias sailcat_base_atk base_atk
alias sailcat_base_pdef base_pdef
alias sailcat_base_mdef base_mdef
alias sailcat_base_eva base_eva
alias sailcat_element_rate element_rate
alias sailcat_state_guard? state_guard?
alias sailcat_hit hit
#--------------------------------------------------------------------------
# ● 设置
# actor_id : 角色 ID
#--------------------------------------------------------------------------
def setup(actor_id)
@innate_skills = []
sailcat_setup(actor_id)
end
#--------------------------------------------------------------------------
# ● 领悟特技
# skill_id : 特技 ID
#--------------------------------------------------------------------------
def learn_skill(skill_id)
sailcat_learn_skill(skill_id)
unless @innate_skills.include?(skill_id)
@innate_skills.push(skill_id)
@innate_skills.sort!
update_skill_state(nil, $data_skills[skill_id])
end
end
#--------------------------------------------------------------------------
# ● 遗忘特技
# skill_id : 特技 ID
#--------------------------------------------------------------------------
def forget_skill(skill_id)
sailcat_forget_skill(skill_id)
@innate_skills.delete(skill_id)
update_skill_state($data_skills[skill_id], nil)
end
#--------------------------------------------------------------------------
# ● 更新被动特技的自动状态
# old_skill : 去除的特技
# new_skill : 设定的特技
#--------------------------------------------------------------------------
def update_skill_state(old_skill, new_skill)
if old_skill != nil and old_skill.auto_states != []
for state in old_skill.auto_states
remove_state(state, true)
end
end
if new_skill != nil and new_skill.auto_states != []
for state in new_skill.auto_states
add_state(state, true)
end
end
end
#--------------------------------------------------------------------------
# ● 获取基本 MaxHP
#--------------------------------------------------------------------------
def base_maxhp
m = n = sailcat_base_maxhp
for skill_id in @innate_skills
skill = $data_skills[skill_id]
n += m * (skill != nil ? skill.maxhp_plus : 0) / 100
end
return n
end
#--------------------------------------------------------------------------
# ● 获取基本 MaxSP
#--------------------------------------------------------------------------
def base_maxsp
m = n = sailcat_base_maxsp
for skill_id in @innate_skills
skill = $data_skills[skill_id]
n += m * (skill != nil ? skill.maxsp_plus : 0) / 100
end
return n
end
#--------------------------------------------------------------------------
# ● 获取基本力量
#--------------------------------------------------------------------------
def base_str
m = n = sailcat_base_str
for skill_id in @innate_skills
skill = $data_skills[skill_id]
n += m * (skill != nil ? skill.str_plus : 0) / 100
end
return [n, 999].min
end
#--------------------------------------------------------------------------
# ● 获取基本灵巧
#--------------------------------------------------------------------------
def base_dex
m = n = sailcat_base_dex
for skill_id in @innate_skills
skill = $data_skills[skill_id]
n += m * (skill != nil ? skill.dex_plus : 0) / 100
end
return [n, 999].min
end
#--------------------------------------------------------------------------
# ● 获取基本速度
#--------------------------------------------------------------------------
def base_agi
m = n = sailcat_base_agi
for skill_id in @innate_skills
skill = $data_skills[skill_id]
n += m * (skill != nil ? skill.agi_plus : 0) / 100
end
return [n, 999].min
end
#--------------------------------------------------------------------------
# ● 获取基本魔力
#--------------------------------------------------------------------------
def base_int
m = n = sailcat_base_int
for skill_id in @innate_skills
skill = $data_skills[skill_id]
n += m * (skill != nil ? skill.int_plus : 0) / 100
end
return [n, 999].min
end
#--------------------------------------------------------------------------
# ● 获取基本攻击力
#--------------------------------------------------------------------------
def base_atk
m = n = sailcat_base_atk
for skill_id in @innate_skills
skill = $data_skills[skill_id]
n += m * (skill != nil ? skill.atk_plus : 0) / 100
end
return [n, 999].min
end
#--------------------------------------------------------------------------
# ● 获取基本物理防御
#--------------------------------------------------------------------------
def base_pdef
m = n = sailcat_base_pdef
for skill_id in @innate_skills
skill = $data_skills[skill_id]
n += m * (skill != nil ? skill.pdef_plus : 0) / 100
end
return [n, 999].min
end
#--------------------------------------------------------------------------
# ● 获取基本魔法防御
#--------------------------------------------------------------------------
def base_mdef
m = n = sailcat_base_mdef
for skill_id in @innate_skills
skill = $data_skills[skill_id]
n += m * (skill != nil ? skill.mdef_plus : 0) / 100
end
return [n, 999].min
end
#--------------------------------------------------------------------------
# ● 获取基本回避修正
#--------------------------------------------------------------------------
def base_eva
n = sailcat_base_eva
for skill_id in @innate_skills
skill = $data_skills[skill_id]
n += skill != nil ? skill.eva_plus : 0
end
return [n, 100].min
end
#--------------------------------------------------------------------------
# ● 获取命中率
#--------------------------------------------------------------------------
def hit
n = sailcat_hit
for skill_id in @innate_skills
skill = $data_skills[skill_id]
n = (skill != nil and skill.sign(12) == -1) ? 100 : n
end
return n
end
#--------------------------------------------------------------------------
# ● 判定防御状态
# state_id : 状态 ID
#--------------------------------------------------------------------------
def state_guard?(state_id)
n = sailcat_state_guard?(state_id)
for skill_id in @innate_skills
skill = $data_skills[skill_id]
n |= skill.guard_state_set.include?(state_id) if skill != nil
end
return n
end
#--------------------------------------------------------------------------
# ● 取得属性修正值
# element_id : 属性 ID
#--------------------------------------------------------------------------
def element_rate(element_id)
result = sailcat_element_rate(element_id)
for skill_id in @innate_skills
skill = $data_skills[skill_id]
if skill != nil
result -= skill.element_plus(element_id)
result = [[result, 300].min, -200].max
end
end
return result
end
#--------------------------------------------------------------------------
# ● 取得状态修正值
# state_id : 状态 ID
#--------------------------------------------------------------------------
def state_rate(state_id)
table = [0,100,80,60,40,20,0]
result = table[self.state_ranks[state_id]]
for skill_id in @innate_skills
skill = $data_skills[skill_id]
if skill != nil
result -= skill.state_plus(state_id)
result = [[result, 100].min, 0].max
end
end
return result
end
end
class Game_Battler
#--------------------------------------------------------------------------
# ● 状态变化 (+) 的适用
# plus_state_set : 状态变化 (+)
#--------------------------------------------------------------------------
def states_plus(plus_state_set)
# 清除有效标志
effective = false
# 循环 (附加状态)
for i in plus_state_set
# 无法防御本状态的情况下
unless self.state_guard?(i)
# 这个状态如果不是 full 的话就设置有效标志
effective |= self.state_full?(i) == false
# 状态为 [不能抵抗] 的情况下
if $data_states[i].nonresistance
# 设置状态变化标志
@state_changed = true
# 附加状态
add_state(i)
# 这个状态不是 full 的情况下
elsif self.state_full?(i) == false
# 将状态的有效度变换为概率、与随机数比较
if rand(100) < self.state_rate(i)
# 设置状态变化标志
@state_changed = true
# 附加状态
add_state(i)
end
end
end
end
# 过程结束
return effective
end
end
class Game_Enemy
#--------------------------------------------------------------------------
# ● 获取状态修正值
# state_id : 状态 ID
#--------------------------------------------------------------------------
def state_rate(state_id)
return [0,100,80,60,40,20,0][self.state_ranks[state_id]]
end
end