SkillVo = SkillVo or BaseClass()
|
|
|
|
local SkillVo = SkillVo
|
|
local string_len = string.len
|
|
local string_sub = string.sub
|
|
local table_insert = table.insert
|
|
local math_max = math.max
|
|
local tonumber = tonumber
|
|
|
|
SkillVo.SkillType =
|
|
{
|
|
Initiative = 1, --主动
|
|
Passitive = 2, --被动
|
|
Assist = 3, --辅助
|
|
Menpai = 4, --门派技能
|
|
}
|
|
|
|
--怒气技能id列表
|
|
SkillVo.AngerSkillId =
|
|
{
|
|
[101091] = true,
|
|
[102091] = true,
|
|
[103091] = true,
|
|
[104091] = true,
|
|
}
|
|
|
|
function SkillVo:__init(skillId)
|
|
self.id = skillId --技能id
|
|
self.level= 0 --技能等级
|
|
self.useTime = 0 --技能触发时间
|
|
self:getComboSkill()
|
|
|
|
self.canLearn = false
|
|
end
|
|
function SkillVo:__defineVar()
|
|
return {
|
|
_class_type = self,
|
|
--_cid = self._id,
|
|
_iid = _in_obj_ins_id,
|
|
id = 1,
|
|
level = 0,
|
|
totalLevel = 1,
|
|
canLearn = false,
|
|
skill_link = nil,
|
|
useTime = 0,
|
|
}
|
|
end
|
|
|
|
function SkillVo:getName()
|
|
if self.name == nil then
|
|
self.name = self:getBasic("name")
|
|
if self.name ~= nil then
|
|
self.name = Trim(self.name)
|
|
end
|
|
end
|
|
return self.name
|
|
end
|
|
--角色
|
|
function SkillVo:getCarrer()
|
|
if self.career == nil then
|
|
self.career = self:getBasic("career")
|
|
end
|
|
return self.career
|
|
end
|
|
|
|
-- 技能类型 1主动技能,2被动技能,3辅助技能,4增益技能
|
|
function SkillVo:GetSkillType()
|
|
if self.type == nil then
|
|
self.type = self:getBasic("type")
|
|
end
|
|
return self.type
|
|
end
|
|
|
|
--获取技能类型字符串
|
|
function SkillVo:GetSkillTypeStr()
|
|
return WordManager:GetSkillTypeStr(self:GetSkillType())
|
|
end
|
|
|
|
--是否是幻光技能
|
|
function SkillVo:IsDailyLightSkill()
|
|
if self.is_daily_litght_skill == nil then
|
|
self.is_daily_litght_skill = self:getCarrer() == 13
|
|
end
|
|
return self.is_daily_litght_skill
|
|
end
|
|
|
|
--攻击参照类型 1自己 2选取对象
|
|
function SkillVo:GetSkillAttObj()
|
|
if self.att_obj == nil then
|
|
self.att_obj = self:getBasic("att_obj")
|
|
end
|
|
return self.att_obj
|
|
end
|
|
|
|
--是否是特殊技能(永恒回复)
|
|
function SkillVo:IsSpecialSkill()
|
|
return self.id == 109100
|
|
end
|
|
|
|
--是否是禁跳技能
|
|
function SkillVo:IsForbidJumpSkill()
|
|
return self.id == 109101
|
|
end
|
|
|
|
--是否是被动技能
|
|
function SkillVo:IsPassitiveSkill()
|
|
return self:GetSkillType() == SkillVo.SkillType.Passitive
|
|
end
|
|
|
|
--是否普攻
|
|
function SkillVo:IsNormal()
|
|
if self.is_normal == nil then
|
|
self.is_normal = self:getBasic("is_normal")
|
|
end
|
|
return self.is_normal == 1
|
|
end
|
|
|
|
--是否副技能
|
|
function SkillVo:IsComboSkill()
|
|
if self.is_combo == nil then
|
|
self.is_combo = self:getBasic("is_combo")
|
|
end
|
|
return self.is_combo == 1
|
|
end
|
|
|
|
--是否怒气技能
|
|
function SkillVo:IsAngerSkill()
|
|
return SkillVo.AngerSkillId[self.id]
|
|
end
|
|
--选取模式 1自己,2最近敌方,3最近队友
|
|
function SkillVo:GetSelectType()
|
|
if self.obj == nil then
|
|
self.obj = self:getBasic("obj")
|
|
end
|
|
return self.obj
|
|
end
|
|
|
|
--(0客户端直接播放,1等服务端返回播)
|
|
function SkillVo:GetBroadcast()
|
|
if self.broadcast == nil then
|
|
self.broadcast = self:getBasic("broadcast")
|
|
end
|
|
return self.broadcast
|
|
end
|
|
|
|
--(是否前摇技能)
|
|
function SkillVo:IsPreSwingSkill()
|
|
if self.is_shake_pre == nil then
|
|
self.is_shake_pre = self:getBasic("is_shake_pre")
|
|
end
|
|
return self.is_shake_pre == 1
|
|
end
|
|
|
|
--获取蓄能连招
|
|
function SkillVo:getSkillLink()
|
|
if self.skill_link == nil then
|
|
self.skill_link = {}
|
|
local link_str = self:getBasic("skill_link")
|
|
if link_str and string_len(link_str) > 4 then
|
|
link_str = string_sub(link_str, 3, -3)
|
|
local tmp_arr = Split(link_str, ",")
|
|
for i=1, #tmp_arr do
|
|
local s = tmp_arr[i]
|
|
table_insert(self.skill_link, tonumber(s))
|
|
end
|
|
end
|
|
end
|
|
return self.skill_link
|
|
end
|
|
|
|
--获取攻击目标数量
|
|
function SkillVo:GetAttackNum(level)
|
|
--假定攻击数量不受等级影响
|
|
if not self.attack_role_num then
|
|
self.attack_role_num, self.attack_mon_num = 0,0
|
|
local level_vo = self:getLevelVo(level)
|
|
if level_vo then
|
|
local num_str = level_vo.num
|
|
if num_str and string_len(num_str) > 4 then
|
|
num_str = string_sub(num_str, 3, -3)
|
|
local tmp_arr = Split(num_str, ",")
|
|
self.attack_role_num, self.attack_mon_num = tonumber(tmp_arr[1]) or 0,tonumber(tmp_arr[2]) or 0
|
|
end
|
|
end
|
|
end
|
|
return self.attack_role_num, self.attack_mon_num
|
|
--[[
|
|
level = level or self.level
|
|
local level_vo = self:getLevelVo(level)
|
|
-- print("获取攻击目标数量", self.id, self.level, level_vo)
|
|
if level_vo then
|
|
local num_str = level_vo.num
|
|
local role_num,mon_num = 0,0
|
|
if num_str and string_len(num_str) > 4 then
|
|
num_str = string_sub(num_str, 3, -3)
|
|
local tmp_arr = Split(num_str, ",")
|
|
role_num,mon_num = tonumber(tmp_arr[1]) or 0,tonumber(tmp_arr[2]) or 0
|
|
end
|
|
return role_num,mon_num
|
|
else
|
|
return 0,0
|
|
end
|
|
]]
|
|
end
|
|
|
|
--是否群攻模式
|
|
function SkillVo:IsAoeMode()
|
|
if self.is_aoe_mode == nil then
|
|
local mod = self:getBasic("mod")
|
|
if mod then
|
|
mod = tonumber(mod)
|
|
if mod == 1 then
|
|
self.is_aoe_mode = false
|
|
else
|
|
self.is_aoe_mode = true
|
|
end
|
|
else
|
|
self.is_aoe_mode = true
|
|
end
|
|
end
|
|
return self.is_aoe_mode
|
|
end
|
|
--AOE时选取目标的方式
|
|
function SkillVo:GetAoeMode()
|
|
if self.aoe_mod == nil then
|
|
local str = self:getBasic("range")
|
|
if str then
|
|
self.aoe_mod = tonumber(str)
|
|
if self.aoe_mod == 0 then
|
|
self.aoe_mod = 1
|
|
end
|
|
else
|
|
self.aoe_mod = 1
|
|
end
|
|
end
|
|
return self.aoe_mod
|
|
end
|
|
|
|
--CD时间,配置的
|
|
function SkillVo:getCd(level)
|
|
level = level or self.level
|
|
local level_vo = self:getLevelVo(level)
|
|
if level_vo and level_vo.cd then
|
|
self.cd = tonumber(level_vo.cd) or 0
|
|
else
|
|
self.cd = 0
|
|
end
|
|
return self.cd
|
|
end
|
|
|
|
function SkillVo:startCD()
|
|
self.useTime = Status.NowTime
|
|
end
|
|
|
|
function SkillVo:clearCD()
|
|
self.useTime = 0
|
|
end
|
|
|
|
function SkillVo:refreshCD(time)
|
|
self.useTime = self.useTime - time
|
|
end
|
|
|
|
--真实的cd时间
|
|
function SkillVo:getRealCD()
|
|
local ret_cd = 0
|
|
local cfg_cd = self:getCd()
|
|
if self.useTime ~= 0 then
|
|
if Status.NowTime - self.useTime > ((self:getCd() / 1000) - 0.5) then
|
|
ret_cd = 0
|
|
else
|
|
ret_cd = math.max(0,(self:getCd() / 1000) - ( Status.NowTime - self.useTime ))
|
|
end
|
|
end
|
|
return ret_cd
|
|
end
|
|
|
|
function SkillVo:CoolDown()
|
|
local cd_info = SkillManager:getInstance().cd_skill_list[self.id]
|
|
local last_release_time = SkillManager:getInstance():GetReleaseMainSkill(self.id)
|
|
if (cd_info and cd_info:IsPlaying()) or self:getRealCD() > 0 then --or Status.NowTime - last_release_time < 1.5 then
|
|
return false
|
|
end
|
|
|
|
return true
|
|
end
|
|
|
|
function SkillVo:getLevelVo(level)
|
|
-- print("= = =SkillVo:getLevelVo:", self.id, level)
|
|
level = (level == nil or level == 0) and 1 or level
|
|
local lvs = self:getBasic("lvs")
|
|
if lvs ~= nil and level <= tonumber(lvs.lvs_total) then
|
|
return lvs[level]
|
|
end
|
|
return nil
|
|
end
|
|
|
|
function SkillVo:GetTotalLevel()
|
|
local lvs = self:getBasic("lvs")
|
|
return tonumber(lvs.lvs_total)
|
|
end
|
|
|
|
function SkillVo:IsMaxLevel()
|
|
local max_lv = self:GetTotalLevel()
|
|
return self.level and self.level >= max_lv
|
|
end
|
|
|
|
--取攻击距离
|
|
function SkillVo:GetDistance(level)
|
|
if not self.attack_distance then
|
|
level = level or self.level
|
|
local level_vo = self:getLevelVo(level)
|
|
if level_vo then
|
|
local distance = tonumber(level_vo.distance)
|
|
if distance == nil then
|
|
distance = 50
|
|
end
|
|
self.attack_distance = distance
|
|
else
|
|
self.attack_distance = 50
|
|
end
|
|
end
|
|
return self.attack_distance
|
|
--[[
|
|
level = level or self.level
|
|
local level_vo = self:getLevelVo(level)
|
|
if level_vo then
|
|
local distance = tonumber(level_vo.distance)
|
|
if distance == nil then
|
|
distance = 50
|
|
end
|
|
return distance
|
|
else
|
|
return 50
|
|
end
|
|
]]
|
|
end
|
|
|
|
--攻击范围
|
|
function SkillVo:GetArea(level)
|
|
if not self.attack_area then
|
|
level = level or self.level
|
|
local level_vo = self:getLevelVo(level)
|
|
if level_vo then
|
|
self.attack_area = tonumber(level_vo.area)
|
|
end
|
|
end
|
|
return self.attack_area
|
|
--[[
|
|
level = level or self.level
|
|
local level_vo = self:getLevelVo(level)
|
|
if level_vo then
|
|
local area = tonumber(level_vo.area)
|
|
return area
|
|
end
|
|
return 0
|
|
]]
|
|
end
|
|
|
|
|
|
--获取combo技(类似战士旋风,需要客户端自动每隔一段时间发一次技能)
|
|
function SkillVo:getComboSkill()
|
|
if self.combo_skills == nil then
|
|
self.combo_skills = {}
|
|
local skillCfg = SkillManager.Instance:GetFightSkillMovie(self.id)
|
|
local comboSkills = skillCfg and skillCfg.comboSkills
|
|
if comboSkills then
|
|
local time = 0
|
|
local info = nil
|
|
for i = 1, #comboSkills do
|
|
local delta = tonumber(comboSkills[i][1]) / 1000
|
|
local skill_id = tonumber(comboSkills[i][2])
|
|
time = time + delta
|
|
info = {time = time,
|
|
skill_id = skill_id}
|
|
|
|
|
|
table_insert(self.combo_skills, info)
|
|
end
|
|
end
|
|
end
|
|
return self.combo_skills
|
|
end
|
|
|
|
--获取多段伤害的段数跟间隔,返回值:段数(默认1,大于1才算多段伤害),时间间隔
|
|
function SkillVo:getMultiHurtInfo( )
|
|
if not self.multi_segment then
|
|
self.multi_segment = self:getBasic("multistage")
|
|
end
|
|
if self.multi_segment and self.multi_segment > 1 then
|
|
if not self.multi_interval then
|
|
self.multi_interval = tonumber(self:getBasic("stage_cd")) or 0
|
|
self.multi_interval = self.multi_interval / 1000 --毫秒转秒
|
|
end
|
|
return self.multi_segment, self.multi_interval
|
|
end
|
|
return 1, 0
|
|
end
|
|
|
|
--[[
|
|
功能:获取技能的基本信息
|
|
其他.
|
|
作者:zsm
|
|
]]
|
|
function SkillVo:getBasic(str)
|
|
local basic = SkillManager.getInstance():getSkillFromConfig(self.id)
|
|
if basic == nil then
|
|
return nil
|
|
end
|
|
return basic[str]
|
|
end
|
|
|
|
function SkillVo:__delete( )
|
|
end
|
|
|
|
function SkillVo:GetNeedLevel( level )
|
|
level = level or self.level
|
|
local levelVo = self:getLevelVo( level)
|
|
local lv = 0
|
|
if levelVo then
|
|
lv = levelVo.condition.lv
|
|
end
|
|
return lv or 0
|
|
end
|
|
function SkillVo:GetNeedCoin( level )
|
|
level = level or self.level
|
|
local levelVo = self:getLevelVo( level)
|
|
local coin = 0
|
|
if levelVo then
|
|
coin = levelVo.condition.coin
|
|
end
|
|
return coin or 0
|
|
end
|
|
|
|
function SkillVo:GetCondition()
|
|
local levelVo = self:getLevelVo(level or self.level)
|
|
if levelVo then
|
|
cdt = levelVo.condition
|
|
if cdt.lv then
|
|
return "level",cdt.lv
|
|
elseif cdt.turn then
|
|
return "turn",cdt.turn
|
|
elseif cdt.yhbg then
|
|
return "yhbg",cdt.yhbg
|
|
elseif cdt.finish_dun then
|
|
return "finish_dun",cdt.finish_dun
|
|
end
|
|
end
|
|
end
|
|
|
|
function SkillVo:GetNextConditionByKey(key, level)
|
|
level = level or self.level
|
|
local total_level = self:GetTotalLevel()
|
|
if level >= total_level then
|
|
return false
|
|
end
|
|
local levelVo = self:getLevelVo( level + 1)
|
|
if levelVo then
|
|
cdt = levelVo.condition
|
|
if cdt.lv and key == "level" then
|
|
return cdt.lv
|
|
elseif cdt.turn and key == "turn" then
|
|
return cdt.turn
|
|
elseif cdt.vip and key == "vip" then
|
|
return cdt.vip
|
|
elseif cdt.goods and key == "goods" then
|
|
return cdt.goods
|
|
end
|
|
end
|
|
return false
|
|
end
|
|
|
|
function SkillVo:getAnger(level)
|
|
level = level or self.level
|
|
local vo= self:getLevelVo(level);
|
|
if vo==nil then
|
|
return -1
|
|
end
|
|
local use_str = Trim(vo.use)
|
|
local mp_str = string_sub(use_str, 2, -2)
|
|
if string_len(mp_str)==0 then
|
|
-- print("技能不耗怒气~~", self.id)
|
|
return 0
|
|
else
|
|
mp_str = string_sub(mp_str, 2, -2)
|
|
local tmp_strs = Split(mp_str, ",")
|
|
if #tmp_strs >= 2 then
|
|
for i = 1,#tmp_strs do
|
|
if tmp_strs[i] == "anger" then
|
|
return tonumber(tmp_strs[i+1]) or 0
|
|
end
|
|
end
|
|
end
|
|
end
|
|
return 0
|
|
end
|
|
|
|
function SkillVo:GetDesc(level)
|
|
level = level or self.level
|
|
local vo= self:getLevelVo(level);
|
|
if vo == nil then
|
|
return -1
|
|
end
|
|
return Trim(vo.desc)
|
|
end
|
|
|
|
|
|
function SkillVo:GetPower(level)
|
|
local is_have = true
|
|
level = level or self.level
|
|
if level == 0 then
|
|
is_have = false
|
|
level = 1
|
|
end
|
|
local _,power = GetSkillAttrBySkill( self.id, level, true, is_have)
|
|
return power
|
|
end
|
|
|
|
function SkillVo:GetAttrOffsetByLevel(cur_level, next_level)
|
|
local t = {}
|
|
|
|
if cur_level == 0 then
|
|
local next_vo = self:getLevelVo(next_level)
|
|
local next_attr = Trim(next_vo.base_attr)
|
|
if next_attr ~= "" and next_attr ~= "[]" then
|
|
local next_attr_list =ErlangParser:GetInstance():Parse(next_attr)
|
|
t = next_attr_list
|
|
end
|
|
elseif next_level > cur_level then
|
|
local next_vo = self:getLevelVo(next_level)
|
|
local cur_vo = self:getLevelVo(cur_level)
|
|
local next_attr = Trim(next_vo.base_attr)
|
|
local cur_attr = Trim(cur_vo.base_attr)
|
|
if next_attr ~= "" and next_attr ~= "[]" and cur_attr ~= "" and cur_attr ~= "[]" then
|
|
local next_attr_list =ErlangParser:GetInstance():Parse(next_attr)
|
|
local cur_attr_list =ErlangParser:GetInstance():Parse(cur_attr)
|
|
for i,v in ipairs(next_attr_list) do
|
|
t[i] = v
|
|
for _i,_v in ipairs(cur_attr_list) do
|
|
if v[2] == _v[2] then
|
|
t[i][3] = math.abs(v[3]-_v[3])
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
return t
|
|
end
|
|
|
|
--是否可以升级
|
|
function SkillVo:CanUp(level)
|
|
local b = false
|
|
level = level or self.level
|
|
local total_level = self:GetTotalLevel()
|
|
if level < total_level then
|
|
local is_enable = true
|
|
--还没有达到技能的学习条件
|
|
is_enable = self:CanUpButGoods(level)
|
|
if not is_enable then
|
|
return false
|
|
end
|
|
|
|
--判断是否有足够的材料升级
|
|
local goods = self:GetNextConditionByKey("goods", level)
|
|
if goods then
|
|
for i,v in ipairs(goods) do
|
|
local own_count = GoodsModel:getInstance():GetTypeGoodsNum(v[1])
|
|
if own_count and tonumber(v[2]) and own_count < tonumber(v[2]) then
|
|
is_enable = false
|
|
break
|
|
end
|
|
end
|
|
b = is_enable
|
|
end
|
|
end
|
|
return b
|
|
end
|
|
|
|
--除了道具可以升级
|
|
function SkillVo:CanUpButGoods(level)
|
|
local b = true
|
|
level = level or self.level
|
|
local total_level = self:GetTotalLevel()
|
|
-- print(">>> 00 = ",level , total_level, level < total_level )
|
|
if level < total_level then
|
|
--比较条件
|
|
local t = {
|
|
level = RoleManager.Instance:GetMainRoleVo().level,
|
|
turn = RoleManager.Instance:GetMainRoleVo().turn,
|
|
vip = RoleManager.Instance:GetMainRoleVo().vip_flag,
|
|
}
|
|
for k,v in pairs(t) do
|
|
local _value = self:GetNextConditionByKey(k, level)
|
|
_value = tonumber(_value)
|
|
if _value and _value > v then
|
|
return false
|
|
end
|
|
end
|
|
else
|
|
return false
|
|
end
|
|
return b
|
|
end
|
|
|
|
|
|
function SkillVo:GetSkillAttrList(ignore_list, have_level)
|
|
local attrs = {}
|
|
local total_level = self:GetTotalLevel()
|
|
for i=1,total_level do
|
|
if not ignore_list or ignore_list[i] == nil then
|
|
local des = self:GetDesc(i)
|
|
if have_level then
|
|
local t =
|
|
{
|
|
level = i,
|
|
des = des,
|
|
}
|
|
table_insert(attrs, t)
|
|
else
|
|
table_insert(attrs, des)
|
|
end
|
|
|
|
end
|
|
end
|
|
return attrs
|
|
end
|