#encoding:utf-8
#===========================================================================
# RMVA 豪华型技能加点|技能被动效果: v1.05
# By希忆 66rpg.com
# 转载或修改请保留此类信息
#===========================================================================
# 在游戏系统类的实现
#
# 完工了,大概
#===========================================================================
#角色类,新增一堆方法。
class Game_Actor < Game_Battler
#初始化角色
#@skill_level:存放技能等级数据的哈希表,技能id=>技能等级
#@sp:剩余技能点
alias setup_201410131453 setup
def setup(actor_id)
@skill_level=Hash.new(0)
setup_201410131453(actor_id)
@sp = (@level-1) * SkillLevel::LEVELUPSP + SkillLevel::INITIALSP
auto_skill_levelup if self.class.auto_sp
end
#读取技能点的方法,如果是自动升级技能的职业,则没必要有技能点
def sp
return 0 if self.class.auto_sp
@sp
end
#读取技能基础等级,
#锁定技能等级优先度最高,
#链接技能等级次之,这个我好像在计算技能最终等级的方法里面又来了一遍。
#主要是技能基础等级是升级技能的窗口看到的等级,最终等级是使用技能的窗口。
def skill_basic_level(skill_id)
return 0 if skill_id == 0
lock = $data_skills[skill_id].lock_level
return lock if lock != 0
lnk = $data_skills[skill_id].link_skill
return skill_basic_level(lnk) if lnk != 0
@skill_level[skill_id]
end
#获取装备增加技能的等级之和
def skill_plus_level(skill_id)
self.equips.compact.inject(0){|skl,eqp| skl+eqp.add_skill(skill_id)}
end
#读取技能最终等级,如果技能基础等级为零,则不加装备提升直接等于零。
#最后返回基础等级+装备附加与技能最大等级中的小值
def skill_level(skill_id)
return 0 if skill_id == 0
lock = $data_skills[skill_id].lock_level
return lock if lock != 0
lnk = $data_skills[skill_id].link_skill
return skill_level(lnk) if lnk != 0
return 0 unless @skills.include?(skill_id)
return 0 if skill_basic_level(skill_id) == 0
[skill_basic_level(skill_id) + skill_plus_level(skill_id) ,\
$data_skills[skill_id].max_level].min
end
#升一级技能技能能升级就升级,返回成功,否则返回失败
def level_up_skill(skill_id)
skl = $data_skills[skill_id]
if skill_can_levelup?(skl)
@sp -= skl.sp_cost
@skill_level[skill_id] += 1
return true
else
return false
end
end
#初始化角色时初始化技能的方法,
#这里是不管默认的技能设定直接加载能学到的所有技能,也就是职业列表下的那些。
def init_skills
@skills = []
self.class.learnings.each do |learning|
@skills.push(learning.skill_id)
end
@skills.sort!
end
#主要用在技能列表的窗口里的。确保只有技能等级为1级及以上的技能才能显示。
def has_skill?(skill)
skills.include?(skill) && skill_basic_level(skill.id) > 0
end
#判断是否学习了技能,同样要确保只有技能等级为1级及以上的技能才能显示。
#和上面的区别是上面的可以有装备附带,状态附带的技能等级不为0的技能
#这里只能是职业列表下“领悟”的技能,装备状态附带的都不算
def skill_learn?(skill)
skill.is_a?(RPG::Skill) && @skills.include?(skill.id) && skill_basic_level(skill.id) > 0
end
#判断前置技能是否都满足
def skill_former_match?(skill)
skill.former.each do |former|
return false unless skill_basic_level(former[0]) >= former[1]
end
true
end
#判断技能是否已经学到精通了、
def skill_max_learn?(skill)
skill_basic_level(skill.id) == skill.max_learn
end
#计算学习下一等级的技能所需要的人物等级
#如果精通了return false【感觉好像有点奇葩。。。】
def skill_next_level(skill)
return false if skill_max_learn?(skill)
skill.learn_level[0] + skill_basic_level(skill.id) * skill.learn_level[1]
end
#技能能否升级?首先看是否锁定,是否链接,是否精通,
#再看等级是否符合学习下一级,sp是否足够,前置技能是否满足要求。
def skill_can_levelup?(skill)
return false if skill.lock_level != 0
return false if skill.link_skill != 0
return false if skill_max_learn?(skill)
@level >= skill_next_level(skill) && @sp >= skill.sp_cost && skill_former_match?(skill)
end
#好像没什么用处。。。当初修改的用意是直接设置技能等级,后来觉得不好控制。。。
#反正就放着吧,不去管它好了
def learn_skill(skill_id,sk_level=0)
unless skill_learn?($data_skills[skill_id])
@skills.push(skill_id)
@skills.sort!
@skill_level[skill_id]=sk_level unless @skill_level.has_key?(skill_id)
end
end
#自动升级技能。
def auto_skill_levelup
@skills.each do |skill|
skl=$data_skills[skill]
if self.class.auto_sp
while skill_next_level(skl) && skill_next_level(skl) <= @level do
@skill_level[skill] += 1
end
elsif skl.auto_levelup
while level_up_skill(skill) do
end
end
end
end
#升级时发生的事情,等级+1,sp增加,如果是自动升级技能的职业则自动升级技能
def level_up
@level += 1
@sp += SkillLevel::LEVELUPSP
auto_skill_levelup
end
#被动技能提升的基础属性(加法叠加的部分)
#SkillLevel.formula:带入公式计算。
def skill_plus(param_id)
skills.inject(0) do |plu,skl|
plu + SkillLevel.formula(self.skill_level(skl.id),skl.param_add(param_id))
end
end
#被动技能提升的基础属性倍率(乘法叠加)
def skill_rate(param_id)
skills.inject(1.00) do |plu,skl|
plu * SkillLevel.formula(self.skill_level(skl.id),skl.param_rate(param_id))
end
end
#被动技能影响的属性抗性(乘法叠加)
def skill_element_rate(element_id)
skills.inject(1.00) do |plu,skl|
plu * SkillLevel.formula(self.skill_level(skl.id),skl.element_rate(element_id))
end
end
#状态提升的基础属性(加法叠加的部分)
def state_param_plus(param_id)
states.inject(0) do |plu,sta|
plu + SkillLevel.formula(@state_level[sta.id],sta.param_add(param_id))
end
end
#状态提升的基础属性倍率(乘法叠加)
def state_param_rate(param_id)
states.inject(1.00) do |plu,sta|
plu * SkillLevel.formula(@state_level[sta.id],sta.param_rate(param_id))
end
end
#状态额外影响的属性抗性(乘法叠加)
def state_element_rate(element_id)
states.inject(1.00) do |plu,sta|
plu * SkillLevel.formula(@state_level[sta.id],sta.element_rate(element_id))
end
end
#基础属性的计算,添加了被动技能的提升,按默认的先加后乘
def param(param_id)
value = param_base(param_id) + param_plus(param_id) +
skill_plus(param_id) + state_param_plus(param_id)
value *= param_rate(param_id) * param_buff_rate(param_id) *
skill_rate(param_id) * state_param_rate(param_id)
[[value, param_max(param_id)].min, param_min(param_id)].max.to_i
end
#状态影响的附加属性xparam
def state_xparam(xparam_id)
states.inject(0.0) do |plu,sta|
plu + SkillLevel.formula(@state_level[sta.id],sta.xparam(xparam_id))
end
end
#附加属性xparam的计算,命中暴击什么的,迭代加算。
def xparam(xparam_id)
state_xparam(xparam_id) + @skills.inject(super(xparam_id)) do |plu,skl|
plu + SkillLevel.formula(self.skill_level(skl),$data_skills[skl].xparam(xparam_id))
end
end
#状态影响特殊属性sparam的计算
def state_sparam(sparam_id)
states.inject(1.0) do |plu,sta|
plu * SkillLevel.formula(@state_level[sta.id],sta.sparam(sparam_id))
end
end
#特殊属性sparam的计算,经验值比率什么的,迭代连乘计算。
def sparam(sparam_id)
state_sparam(sparam_id)*skills.inject(super(sparam_id)) do |plu,skl|
plu * SkillLevel.formula(self.skill_level(skl.id),skl.sparam(sparam_id))
end
end
#技能消耗mp由于技能等级修正的倍率,
#反正就是到SkillLevel.formula找对应编号的公式。
def skill_mp_rate(skill)
SkillLevel.formula(skill_level(skill.id),skill.mp_type)
end
#计算最终技能消耗mp的量
def skill_mp_cost(skill)
(skill.mp_cost * mcr * skill_mp_rate(skill)).to_i
end
#计算暴击伤害倍率super:Game_Battler中的critical_rate,返回1.5
#人物提升,职业提升,被动技能修正和装备提升
def critical_rate
v = super
v *= (1.0 + self.actor.critical_rate/100.0)
v *= (1.0 + self.class.critical_rate/100.0)
v *= skills.inject(1.00) do |plu,skl|
plu * SkillLevel.formula(self.skill_level(skl.id),skl.critical_rate)
end
v*equips.compact.inject(1.00){ |rat,equip| rat*(1.00+equip.critical_rate/100.0) }
end
#属性伤害修正。
def element_rate(element_id)
super(element_id) * skill_element_rate(element_id) * state_element_rate(element_id)
end
#被动技能影响的属性强化效果。
def skill_element_damage(element_id)
skills.inject(1.00) do |plu,skl|
plu * SkillLevel.formula(self.skill_level(skl.id),skl.element_damage(element_id))
end
end
def state_element_damage(element_id)
states.inject(1.00) do |plu,sta|
plu * SkillLevel.formula(@state_level[sta.id],sta.element_damage(element_id))
end
end
#基础属性强化,角色备注和职业备注修正。
def basic_element_damage(element_id)
(1.0 + self.actor.element_damage(element_id)/100.0) *
(1.0 + self.class.element_damage(element_id)/100.0)
end
#计算最终属性强化基础技能装备迭代连乘
def element_damage(element_id)
basic_element_damage(element_id) *
equips.compact.inject(skill_element_damage(element_id)) do |rat,equip|
rat*(1.00+equip.element_damage(element_id)/100.0)
end
end
#受到hp伤害转移给mp的比例,遍历计算并返回最大值
def damage_convert
skl = skills.collect{|sk| sk = SkillLevel.formula(self.skill_level(sk.id),sk.damage_convert)}
sta = states.collect{|st| st = SkillLevel.formula(@state_level[st.id],st.damage_convert)}
(skl+sta).max
end
#洗技能了,
alias item_apply_201411181846 item_apply
def item_apply(user, item)
item_apply_201411181846(user, item)
if item.is_a?(RPG::Item) and item.id == SkillLevel::RESETITEM
if self.reset_skill
self.hp = [self.hp,self.mhp].min
self.mp = [self.mp,self.mmp].min
end
end
end
#洗技能的方法
def reset_skill
return false if self.class.auto_sp
@sp = (@level-1) * SkillLevel::LEVELUPSP + SkillLevel::INITIALSP
@skills.each { |skill| @skill_level[skill]=0 }
return true
end
end
#有关洗点水的使用判断,想和上面洗点放在一起。于是没有放进场景相关。
class Scene_ItemBase < Scene_MenuBase
def item_usable?
if item.id == SkillLevel::RESETITEM
return false if item_target_actors[0].class.auto_sp
return true
end
user.usable?(item) && item_effects_valid?
end
end
class Game_Enemy
#敌人属性强化
def element_damage(id)
1.0 + self.enemy.element_damage(id)/100.0
end
#敌人暴击倍率 super:Game_Battler定义的critical_rate,返回1.5
#~ def critical_rate
#~ super * (1+self.enemy.element_damage/100.0)
#~ end
#敌人的技能等级,要么锁定,要么1
def skill_level(skill_id)
lock = $data_skills[skill_id].lock_level if $data_skills[skill_id]
return lock if lock != 0
return 1
end
#状态提升的基础属性(加法叠加的部分)
def state_param_plus(param_id)
states.inject(0) do |plu,sta|
plu + SkillLevel.formula(@state_level[sta.id],sta.param_add(param_id))
end
end
#状态提升的基础属性倍率(乘法叠加)
def state_param_rate(param_id)
states.inject(1.00) do |plu,sta|
plu * SkillLevel.formula(@state_level[sta.id],sta.param_rate(param_id))
end
end
#状态额外影响的属性抗性(乘法叠加)
def state_element_rate(element_id)
states.inject(1.00) do |plu,sta|
plu * SkillLevel.formula(@state_level[sta.id],sta.element_rate(element_id))
end
end
#基础属性的计算,添加了被动技能的提升,按默认的先加后乘
def param(param_id)
value = param_base(param_id) + param_plus(param_id) +
state_param_plus(param_id)
value *= param_rate(param_id) * param_buff_rate(param_id) *
state_param_rate(param_id)
[[value, param_max(param_id)].min, param_min(param_id)].max.to_i
end
#状态影响的附加属性xparam
def state_xparam(xparam_id)
states.inject(0.0) do |plu,sta|
plu + SkillLevel.formula(@state_level[sta.id],sta.xparam(xparam_id))
end
end
#附加属性xparam的计算,命中暴击什么的,迭代加算。
def xparam(xparam_id)
state_xparam(xparam_id) + super(xparam_id)
end
#状态影响特殊属性sparam的计算
def state_sparam(sparam_id)
states.inject(1.0) do |plu,sta|
plu * SkillLevel.formula(@state_level[sta.id],sta.sparam(sparam_id))
end
end
#特殊属性sparam的计算,经验值比率什么的,迭代连乘计算。
def sparam(sparam_id)
super(sparam_id)*state_sparam(sparam_id)
end
def state_element_damage(element_id)
states.inject(1.00) do |plu,sta|
plu * SkillLevel.formula(@state_level[sta.id],sta.element_damage(element_id))
end
end
def element_rate(element_id)
super(element_id) * state_element_rate(element_id)
end
end
class Game_Battler < Game_BattlerBase
#attr_reader :state_level
#@state_level 保存状态等级的数组
alias initialize_201410131453 initialize
def initialize
initialize_201410131453
@state_level = Hash.new(0)
end
#属性修正的计算,将使用者属性强化也计算在内的
def item_element_rate(user, item)
if item.damage.element_id < 0
user.atk_elements.empty? ? 1.0 : elements_max_rate(user)
else
element_rate(item.damage.element_id)*user.element_damage(item.damage.element_id)
end
end
#将使用者属性强化也计算在内的最有效属性。
def elements_max_rate(user)
user.atk_elements.inject([0.0]) {|r, i| r.push(element_rate(i)*user.element_damage(i)) }.max
end
def damage_convert #受到hp伤害转移给mp的比例
0
end
#计算伤害,SkillLevel.formula找公式算修正。
def make_damage_value(user, item)
value = item.damage.eval(user, self, $game_variables)
if item.is_a?(RPG::Skill)
value *= SkillLevel.formula(user.skill_level(item.id),item.damage_increase_type)
end
value *= item_element_rate(user, item)
value *= pdr if item.physical?
value *= mdr if item.magical?
value *= rec if item.damage.recover?
value = apply_critical(value,user) if @result.critical
value = apply_variance(value, item.damage.variance)
value = apply_guard(value)
if value > 0 && damage_convert > 0
valmp = [(value*damage_convert).to_i,self.mp].min
self.mp -= valmp
value -= valmp
end
@result.make_damage(value.to_i, item)
end
#计算暴击修正,添加了参数user
def apply_critical(value,user)
value * user.critical_rate
end
#基础暴击修正
def critical_rate
1.5
end
#状态附加,添加参数user,写的有点奇怪。如果有明确的user,
#就提取技能等级user.skill_level($data_states[state_id].link_skill)
#然后按SkillLevel.formula公式算得到附加概率,如果随机数比概率大(算是失败)
#就直接返回,再下去按部就班如果没有状态就附加新状态,如果有明确的user,
#状态的等级就等于之前提取的技能等级,否则为1。
def add_state(state_id,user = nil)
if state_addable?(state_id)
if user != nil
lv = user.skill_level($data_states[state_id].link_skill)
else
lv = 1
end
return if rand > SkillLevel.formula(lv,$data_states[state_id].chance)
add_new_state(state_id) unless state?(state_id)
if user != nil
@state_level[state_id] = lv
else
@state_level[state_id] = 1
end
reset_state_counts(state_id)
@result.added_states.push(state_id).uniq!
end
end
def item_effect_add_state_attack(user, item, effect)
user.atk_states.each do |state_id|
chance = effect.value1
chance *= state_rate(state_id)
chance *= user.atk_states_rate(state_id)
chance *= luk_effect_rate(user)
if rand < chance
add_state(state_id,user)
@result.success = true
end
end
end
def item_effect_add_state_normal(user, item, effect)
chance = effect.value1
chance *= state_rate(effect.data_id) if opposite?(user)
chance *= luk_effect_rate(user) if opposite?(user)
if rand < chance
add_state(effect.data_id,user)
@result.success = true
end
end
end