RoleLogic.lua 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608
  1. RoleLogic = {}
  2. RoleLogic.__index = RoleLogic
  3. --local RoleLogic = RoleLogic
  4. --local RoleDataName = RoleDataName
  5. --local BattleLogic = BattleLogic
  6. local Random = Random
  7. local floor = math.floor
  8. local max = math.max
  9. local min = math.min
  10. local skillPool = BattleObjectPool.New(function ()
  11. return Skill:New()
  12. end)
  13. function RoleLogic.New()
  14. local instance = {uid=0,roleData=0,data=RoleData.New(),camp=0,name=0,aiIndex=1,position=0,sp=0,spPass=0,
  15. shield=BattleList.New(),
  16. exCalDmgList=BattleList.New(),
  17. proTranList=BattleList.New(),
  18. buffFilter=BattleList.New(),
  19. Event = BattleEvent:New(),passiveList={},isDead=false,IsDebug=false}
  20. setmetatable(instance, RoleLogic)
  21. return instance
  22. end
  23. function RoleLogic:Init(uid, data, position)
  24. self.uid = uid
  25. self.position = position
  26. self.roleData = data
  27. self.roleId=data.roleId
  28. self.data:Init(self, data.property)
  29. -- WYLog("HP")
  30. -- WYLog(self:GetRoleData(RoleDataName.Hp))
  31. self.isDead = self:GetRoleData(RoleDataName.Hp) <= 0
  32. self.isRealDead = self.isDead
  33. self.camp = data.camp --阵营 0:我方 1:敌方
  34. self.name = data.name
  35. self.element = data.element
  36. self.professionId = data.professionId
  37. self.star = data.star or 1
  38. -- LogError("英雄uid".. self.roleId .." " .. self.star)
  39. self.shield:Clear() --护盾列表
  40. self.exCalDmgList:Clear() --额外计算伤害列表
  41. self.buffFilter:Clear() --buff屏蔽列表
  42. self.proTranList:Clear() --属性转换列表
  43. self.Event:ClearEvent()
  44. -- self.skill = data.skill
  45. -- self.superSkill = data.superSkill
  46. self.skillArray = data.skillArray
  47. --首次读条时间=速度/(20*(等级+10)
  48. self.sp = 0
  49. local time = self:GetRoleData(RoleDataName.Speed)/(20*(self:GetRoleData(RoleDataName.Level)+10))
  50. self.spPass = floor( BattleUtil.ErrorCorrection(time) * BattleLogic.GameFrameRate)
  51. -- 初始化怒气值(默认2)
  52. self.Rage = 2
  53. self.RageGrow = 2 -- 普通技能怒气成长
  54. self.SuperSkillRage = 4 -- 技能需要释放的怒气值,默认为4
  55. self.NoRageRate = 0 -- 不消耗怒气值的概率
  56. --
  57. self.passiveList = {}
  58. WYLog(data.passivity)
  59. --> 之前的一维改二维 每个passivity 包含多个
  60. if data.passivity and #data.passivity > 0 then
  61. for i = 1, #data.passivity do
  62. local v = data.passivity[i]
  63. local ids = v[1]
  64. for k = 1, #ids do
  65. local args = {}
  66. for j = 1, #v[k + 1] do
  67. args[j] = v[k + 1][j]
  68. end
  69. local id = ids[k]
  70. if BattleUtil.Passivity[id] then
  71. BattleUtil.Passivity[id](self, args)
  72. -- 加入被动列表
  73. table.insert(self.passiveList, {id, args})
  74. else
  75. LogRed(Language[10232]..id..Language[10233])
  76. end
  77. end
  78. end
  79. end
  80. -- 初始怒气值放在被动之后计算,使被动对初始怒气的影响生效
  81. --> deprecated
  82. self.Rage = 0--self.Rage + self:GetRoleData(RoleDataName.InitRage)-- 当前怒气值
  83. --
  84. self.aiOrder = data.ai
  85. self.aiIndex = 1
  86. self.aiTempCount = 0
  87. self.IsDebug = false
  88. self.lockTarget = nil --嘲讽
  89. self.ctrl_dizzy = false --眩晕 不能释放所有技能
  90. self.ctrl_slient = false --沉默 只能1技能
  91. self.ctrl_palsy = false --麻痹 只能2技能
  92. self.ctrl_noheal = false --禁疗
  93. self.ctrl_blind = false --致盲
  94. self.ctrltimes = 0 --< 控制次数
  95. self.deadFilter = true -- 控制死亡,置为false则角色暂时无法死亡
  96. self.reliveFilter = true -- 控制复活的标志位,置为false角色将不再享受复活效果
  97. self.reliveHPF = 1
  98. self.IsCanAddSkill = true -- 是否可以追加技能
  99. self.effect218times = 0 --< effect 218 触发次数
  100. self.skilling = false --< 技能间
  101. end
  102. -- 添加一个被动技能
  103. function RoleLogic:AddPassive(id, args, isRepeat)
  104. --判断是否可以叠加
  105. if not isRepeat then
  106. -- 不可以叠加, 如果重复则不再加入
  107. for _, pst in ipairs(self.passiveList) do
  108. if pst[1] == id then
  109. return
  110. end
  111. end
  112. end
  113. -- 被动生效
  114. BattleUtil.Passivity[id](self, args)
  115. -- 加入被动列表
  116. table.insert(self.passiveList, {id, args})
  117. end
  118. --
  119. function RoleLogic:CanCastSkill()
  120. return self.sp >= self.spPass and not self.IsDebug
  121. end
  122. -- 废弃的方法
  123. function RoleLogic:GetSkillCD()
  124. return max(self.spPass - self.sp, 0)
  125. end
  126. -- 废弃的方法
  127. function RoleLogic:AddSkillCD(value, type)
  128. self.Event:DispatchEvent(BattleEventName.RoleCDChanged)
  129. if value == 0 then --为0直接清CD
  130. self.sp = self.spPass
  131. return
  132. end
  133. local cdTotal = self.spPass
  134. local delta = 0
  135. if type == 1 then --加算
  136. delta = floor(value * BattleLogic.GameFrameRate)
  137. elseif type == 2 then --乘加算(百分比属性加算)
  138. delta = floor(value * cdTotal)
  139. elseif type == 3 then --减算
  140. delta = -floor(value * BattleLogic.GameFrameRate)
  141. elseif type == 4 then --乘减算(百分比属性减算)
  142. delta = -floor(value * cdTotal)
  143. end
  144. if delta > 0 then --加cd加cd最大值
  145. self.spPass = self.spPass + delta
  146. else --减cd减cd当前值
  147. delta = -delta
  148. self.sp = min(self.sp + delta, self.spPass)
  149. end
  150. end
  151. -- 改变怒气值
  152. function RoleLogic:AddRage(value, type)
  153. local delta = 0
  154. if type == 1 then --加算
  155. delta = value
  156. elseif type == 2 then --乘加算(百分比属性加算)
  157. delta = floor(value * self.SuperSkillRage)
  158. elseif type == 3 then --减算
  159. delta = -value
  160. elseif type == 4 then --乘减算(百分比属性减算)
  161. delta = -floor(value * self.SuperSkillRage)
  162. end
  163. --
  164. self.Event:DispatchEvent(BattleEventName.RoleRageChange, delta)
  165. --怒气值不可为负值
  166. self.Rage = max(self.Rage + delta, 0)
  167. end
  168. function RoleLogic:GetRoleData(property)
  169. local tarPro = self.data:GetData(property)
  170. local item
  171. for i=1, self.proTranList.size do
  172. item = self.proTranList.buffer[i]
  173. if item.proName == property then
  174. local value
  175. if item.changeType == 1 then --加算
  176. value = item.tranFactor
  177. elseif item.changeType == 2 then --乘加算(百分比属性加算)
  178. value = BattleUtil.ErrorCorrection(self.data:GetData(item.tranProName) * item.tranFactor)
  179. elseif item.changeType == 3 then --减算
  180. value = -item.tranFactor
  181. elseif item.changeType == 4 then --乘减算(百分比属性减算)
  182. value = -BattleUtil.ErrorCorrection(self.data:GetData(item.tranProName) * item.tranFactor)
  183. end
  184. tarPro = tarPro + value
  185. end
  186. end
  187. return tarPro
  188. end
  189. --proA替换的属性,factor系数,proB被替换的属性, duration持续时间
  190. --读取proB属性时,得到的值为proB + proA * factor
  191. function RoleLogic:AddPropertyTransfer(proA, factor, proB, ct, duration)
  192. local proTran = {proName = proB, tranProName = proA, tranFactor = factor, changeType = ct}
  193. self.proTranList:Add(proTran)
  194. local index = self.proTranList.size
  195. if duration then
  196. BattleLogic.WaitForTrigger(duration, function ()
  197. self:RemovePropertyTransfer(index, proTran)
  198. end)
  199. end
  200. return index, proTran
  201. end
  202. -- 删除临时属性
  203. function RoleLogic:RemovePropertyTransfer(index, tran)
  204. if index <= self.proTranList.size and tran == self.proTranList.buffer[index] then
  205. self.proTranList:Remove(index)
  206. end
  207. end
  208. -- 是否为指定id,指定星级的英雄 by:王振兴 2020/07/29
  209. function RoleLogic:IsAssignHeroAndHeroStar(id,star)
  210. if self.roleId==id and self.star==star then
  211. return true
  212. end
  213. return false
  214. end
  215. function RoleLogic:AddBuff(buff)
  216. if self:IsRealDead() then
  217. BattleLogic.BuffMgr:PutBuff(buff)
  218. return
  219. end
  220. -- buff的miss率
  221. local missF = 0
  222. -- 检测被动对miss概率的影响
  223. local cl = {}
  224. local function _CallBack(v, ct)
  225. if v then
  226. table.insert(cl, {v, ct})
  227. end
  228. end
  229. BattleLogic.Event:DispatchEvent(BattleEventName.RoleAddBuffMiss, _CallBack, self, buff)
  230. missF = BattleUtil.CountChangeList(missF, cl)
  231. -- 如果概率为0 或者没有miss
  232. if missF == 0 or not BattleUtil.RandomAction(missF, function() BattleLogic.BuffMgr:PutBuff(buff) end) then
  233. for i=1, self.buffFilter.size do
  234. if self.buffFilter.buffer[i](buff) then
  235. BattleLogic.BuffMgr:PutBuff(buff)
  236. return
  237. end
  238. end
  239. BattleLogic.BuffMgr:AddBuff(self, buff)
  240. end
  241. end
  242. function RoleLogic:Dispose()
  243. end
  244. -- 判断角色是否可以释放技能
  245. function RoleLogic:IsAvailable()
  246. -- 眩晕 -- 死亡
  247. if self.ctrl_dizzy or self:IsRealDead() then
  248. return false
  249. end
  250. -- 沉默麻痹同时存在
  251. if self.ctrl_palsy and self.ctrl_slient then
  252. return false
  253. end
  254. -- 麻痹同时怒气不足
  255. --if self.ctrl_palsy and self.Rage < self.SuperSkillRage then
  256. if self.ctrl_palsy then
  257. return false
  258. end
  259. return true
  260. end
  261. -- 释放技能
  262. function RoleLogic:SkillCast(skill, func)
  263. local _CastDone = function()
  264. if func then
  265. func()
  266. end
  267. end
  268. -- 角色不可用直接结束技能释放
  269. if not skill or not self:IsAvailable() then
  270. _CastDone()
  271. return
  272. end
  273. -- 没有麻痹,释放普通攻击
  274. -- if skill.type == BattleSkillType.Normal and not self.ctrl_palsy then
  275. -- -- local function _CheckRage()
  276. -- -- -- 后成长怒气
  277. -- -- if skill.isRage then
  278. -- -- -- 检测被动技能对怒气成长的影响
  279. -- -- local grow = self.RageGrow
  280. -- -- local _RageGrowPassivity = function(finalGrow)
  281. -- -- grow = finalGrow
  282. -- -- end
  283. -- -- self.Event:DispatchEvent(BattleEventName.RoleRageGrow, grow, _RageGrowPassivity)
  284. -- -- --
  285. -- -- self.Rage = self.Rage + grow
  286. -- -- end
  287. -- -- -- 释放完成
  288. -- -- _CastDone()
  289. -- -- end
  290. -- -- 释放普技
  291. -- skill:Cast(_CastDone)
  292. -- -- 没有沉默,释放大技能
  293. -- elseif skill.type == BattleSkillType.Special and not self.ctrl_slient then
  294. -- -- 先消耗怒气
  295. -- if skill.isRage then
  296. -- if self.Rage < self.SuperSkillRage then
  297. -- -- 怒气值不足不能释放技能
  298. -- _CastDone()
  299. -- return
  300. -- end
  301. -- -- 检测被动技能对怒气消耗的影响
  302. -- local costRage = self.SuperSkillRage
  303. -- local noRageRate = self.NoRageRate
  304. -- local _RageCostPassivity = function(rate, cost)
  305. -- noRageRate = noRageRate + rate
  306. -- costRage = costRage + cost
  307. -- end
  308. -- self.Event:DispatchEvent(BattleEventName.RoleRageCost, costRage, noRageRate, _RageCostPassivity)
  309. -- -- 计算消耗怒气的概率,并消耗怒气
  310. -- local costRate = 1 - noRageRate
  311. -- costRate = costRate > 1 and 1 or costRate
  312. -- costRate = costRate < 0 and 0 or costRate
  313. -- BattleUtil.RandomAction(costRate, function()
  314. -- self.Rage = self.Rage - costRage
  315. -- end)
  316. -- end
  317. -- -- 释放绝技
  318. -- skill:Cast(_CastDone)
  319. -- -- 没有符合条件的技能直接进入下一个技能检测
  320. -- else
  321. -- _CastDone()
  322. -- end
  323. skill:Cast(_CastDone)
  324. end
  325. -- 加入一个技能
  326. -- type 加入的技能类型 --< 修改为physical magic
  327. -- targets 指定目标
  328. -- isAdd 是否是追加技能
  329. -- effectData 战斗技能数据
  330. function RoleLogic:AddSkill(type, isAdd, targets, effectData)
  331. WYLog("RoleLogic:AddSkill")
  332. if not self.IsCanAddSkill and isAdd then return end
  333. -- local effectData = type == BattleSkillType.Normal and self.skill or self.superSkill
  334. SkillManager.AddSkill(self, effectData, type, targets, isAdd)
  335. --
  336. BattleLogManager.Log(
  337. "Add Skill",
  338. "camp", self.camp,
  339. "pos", self.position,
  340. "type", type,
  341. -- "isRage", tostring(isRage),
  342. "isAdd", tostring(isAdd),
  343. "targets", targets and #targets or "0"
  344. )
  345. end
  346. -- 插入一个技能
  347. function RoleLogic:InsertSkill(type, isAdd, targets, effectData)
  348. if not self.IsCanAddSkill and isAdd then return end
  349. -- local effectData = type == BattleSkillType.Normal and self.skill or self.superSkill
  350. SkillManager.InsertSkill(self, effectData, type, targets, isAdd)
  351. --
  352. BattleLogManager.Log(
  353. "Insert Skill",
  354. "camp", self.camp,
  355. "pos", self.position,
  356. "type", type,
  357. -- "isRage", tostring(isRage),
  358. "isAdd", tostring(isAdd),
  359. "targets", targets and #targets or "0"
  360. )
  361. end
  362. -- 设置是否可以追加技能
  363. function RoleLogic:SetIsCanAddSkill(isCan)
  364. self.IsCanAddSkill = isCan
  365. end
  366. -- 正常触发技能
  367. function RoleLogic:CastSkill(func)
  368. -- 设置轮转方法
  369. SkillManager.SetTurnRoundFunc(func)
  370. local haveSkill = false
  371. -- 没有沉默
  372. -- if not self.ctrl_slient and self.Rage >= self.SuperSkillRage then
  373. if not self.ctrl_slient then
  374. local isHave, skilldata = self:CheckSkill(SkillBaseType.Magic)
  375. -- 释放大技能
  376. LogBlue(Language[10234])
  377. if isHave then
  378. self:AddSkill(SkillBaseType.Magic, true, nil, skilldata)
  379. haveSkill = true
  380. else
  381. local isHave_p, skilldata_p = self:CheckSkill(SkillBaseType.Physical)
  382. if isHave_p then
  383. self:AddSkill(SkillBaseType.Physical, true, nil, skilldata_p)
  384. haveSkill = true
  385. else
  386. LogError("RoleLogic CastSkill not have physical skill_1 !!!")
  387. end
  388. end
  389. return haveSkill
  390. end
  391. -- 没有麻痹 释放普通技能
  392. if not self.ctrl_palsy then
  393. LogBlue(Language[10235])
  394. local isHave, skilldata = self:CheckSkill(SkillBaseType.Physical)
  395. if isHave then
  396. self:AddSkill(SkillBaseType.Physical, true, nil, skilldata)
  397. haveSkill = true
  398. else
  399. LogError("CastSkill not have physical skill_2 !!!")
  400. end
  401. return haveSkill
  402. end
  403. LogError("### 无法填装技能")
  404. return haveSkill
  405. -- LogBlue(Language[10236])
  406. end
  407. -- 强制释放技能,测试技能时使用
  408. -- type 追加的技能类型 1=普技 2=特殊技
  409. -- targets 追加技能的目标 nil则自动选择目标
  410. -- func 追加技能释放完成回调
  411. function RoleLogic:ForceCastSkill(type, targets, func)
  412. -- 清除技能控制
  413. self.ctrl_dizzy = false --眩晕 不能释放技能
  414. self.ctrl_slient = false --沉默 只能1技能
  415. self.ctrl_palsy = false --麻痹 只能2技能
  416. -- 设置轮转方法
  417. SkillManager.SetTurnRoundFunc(func)
  418. -- 释放技能
  419. if type == 1 and self.skill then
  420. LogBlue(Language[10237])
  421. self:AddSkill(BattleSkillType.Normal, true, false, nil)
  422. elseif type == 2 and self.superSkill then
  423. LogBlue(Language[10238])
  424. if self.Rage < self.SuperSkillRage then
  425. self.Rage = self.SuperSkillRage
  426. end
  427. self:AddSkill(BattleSkillType.Special, true, false, nil)
  428. end
  429. end
  430. -- 判断是否可以去死了
  431. function RoleLogic:IsCanDead()
  432. -- 暂时不能死
  433. if not self.deadFilter then
  434. return false
  435. end
  436. -- 还有我的技能没有释放,不能死啊
  437. if SkillManager.HaveMySkill(self) then
  438. return false
  439. end
  440. return true
  441. end
  442. -- 真的去死
  443. function RoleLogic:GoDead()
  444. if self:IsCanDead() then
  445. self.isRealDead = true
  446. self.Rage = 0
  447. BattleLogic.BuffMgr:ClearBuff(self)
  448. self.Event:DispatchEvent(BattleEventName.RoleRealDead, self)
  449. BattleLogic.Event:DispatchEvent(BattleEventName.RoleRealDead, self)
  450. return true
  451. end
  452. return false
  453. end
  454. -- 设置是否可以死亡
  455. function RoleLogic:SetDeadFilter(filter)
  456. self.deadFilter = filter
  457. end
  458. -- 要死了
  459. function RoleLogic:SetDead()
  460. self.isDead = true
  461. RoleManager.AddDeadRole(self)
  462. end
  463. -- 判断是否死亡
  464. function RoleLogic:IsDead()
  465. return self.isDead
  466. end
  467. function RoleLogic:IsRealDead()
  468. return self.isRealDead
  469. end
  470. -- 是否可以复活
  471. function RoleLogic:IsCanRelive()
  472. if not self.reliveFilter then
  473. return false
  474. end
  475. if not self.isRealDead then
  476. return false
  477. end
  478. return true
  479. end
  480. -- 复活吧, 真的去世后才能复活
  481. function RoleLogic:Relive()
  482. if self:IsCanRelive() then
  483. -- 没有指定血量则满血
  484. self.isDead = false
  485. self.isRealDead = false
  486. local maxHp = self.data:GetData(RoleDataName.MaxHp)
  487. self.data:SetValue(RoleDataName.Hp, floor(self.reliveHPF * maxHp))
  488. -- 发送复活事件
  489. self.Event:DispatchEvent(BattleEventName.RoleRelive, self)
  490. BattleLogic.Event:DispatchEvent(BattleEventName.RoleRelive, self)
  491. return true
  492. end
  493. return false
  494. end
  495. -- 设置是否可以死亡
  496. function RoleLogic:SetReliveFilter(filter)
  497. self.reliveFilter = filter
  498. end
  499. --,hpf 复活时拥有的血量的百分比
  500. function RoleLogic:SetRelive(hpf)
  501. -- 判断是否可以复活
  502. if self:IsCanRelive() then
  503. self.reliveHPF = hpf or 1
  504. RoleManager.AddReliveRole(self)
  505. end
  506. return false
  507. end
  508. --> 检测技能list中 可释放的技能
  509. function RoleLogic:CheckSkill(skilltype)
  510. local CurRound, MaxRound = BattleLogic.GetCurRound()
  511. -- WYLog("技能列表")
  512. -- WYLog(self.skillArray)
  513. for k, skill in ipairs(self.skillArray) do
  514. while true
  515. do
  516. if skilltype == SkillBaseType.Physical and skill[8].slot ~= SkillSlotPos.Slot_0 then --< 物理技能 排除magic skill
  517. break
  518. end
  519. if skilltype == SkillBaseType.Magic and skill[8].slot == SkillSlotPos.Slot_0 then
  520. break
  521. end
  522. local skillid = skill[1]
  523. local cd = skill[8].cd
  524. local release = skill[8].release
  525. if CurRound == release then --< 起始回合
  526. WYLog("ret skillid")
  527. WYLog(skillid)
  528. return true, skill
  529. elseif CurRound > release and (CurRound - release) % cd == 0 then --< cd回合
  530. return true, skill
  531. end
  532. break
  533. end
  534. end
  535. return false, nil
  536. end
  537. function RoleLogic:Update()
  538. end