RequestLaunchCommand.lua 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505
  1. local RequestLaunchCommand = class('RequestLaunchCommand', framework.SimpleCommand)
  2. local cjson = require("cjson")
  3. local proxyUtils = requireProxy("proxyUtils")
  4. local skillUtils = requireProxy("skillUtils")
  5. local function squLen( x, y )
  6. local maxv = math.max(math.abs(x), math.abs(y))
  7. return maxv * maxv
  8. end
  9. function RequestLaunchCommand:ctor()
  10. self._checkParamFunc = {}
  11. self._checkParamFunc[1] = handler(self, self.checkParam1)
  12. self._checkParamFunc[2] = handler(self, self.checkParam2)
  13. self._checkParamFunc[3] = handler(self, self.checkParam3)
  14. self._checkParamFunc[4] = handler(self, self.checkParam4)
  15. self._checkParamFunc[5] = handler(self, self.checkParam5)
  16. end
  17. function RequestLaunchCommand:calcDir(dest, src)
  18. local inputProxy = global.Facade:retrieveProxy(global.ProxyTable.PlayerInputProxy)
  19. return inputProxy:Vec2ToDir(cc.pSub(dest, src))
  20. end
  21. function RequestLaunchCommand:findTargetByWorldPos(worldPos, launchID, findAll)
  22. -- find pickable
  23. local target = nil
  24. if global.HUDManager.Pick then
  25. target = global.HUDManager:Pick( worldPos )
  26. end
  27. if not target then
  28. target = global.actorManager:Pick( worldPos )
  29. end
  30. -- can't find target
  31. if not target then
  32. return nil, nil
  33. end
  34. -- error type
  35. if not findAll and not proxyUtils.checkLaunchTarget(target) then
  36. if launchID == 28 and target:IsBorn() then
  37. else
  38. return nil, nil
  39. end
  40. end
  41. return target:GetID(), target
  42. end
  43. function RequestLaunchCommand:findTargetByMapPos(mapPos, launchID, findAll)
  44. local worldPos = global.sceneManager:MapPos2WorldPos(mapPos.x, mapPos.y, true)
  45. return self:findTargetByWorldPos(worldPos, launchID, findAll)
  46. end
  47. function RequestLaunchCommand:checkParam1(param)
  48. local player = global.gamePlayerController:GetMainPlayer()
  49. if not player then
  50. return false
  51. end
  52. -- cehck target
  53. local targetID, targetActor = skillUtils.checkTarget(param.launchID)
  54. -- if target, find best pos & dir
  55. if targetID and targetActor then
  56. param.vecSrc = cc.p(player:GetMapX(), player:GetMapY())
  57. param.vecDst = cc.p(targetActor:GetMapX(), targetActor:GetMapY())
  58. param.dir = self:calcDir(param.vecDst, param.vecSrc)
  59. param.targetID = targetID
  60. else
  61. -- default
  62. param.vecSrc = cc.p(player:GetMapX(), player:GetMapY())
  63. param.vecDst = cc.p(player:GetMapX(), player:GetMapY())
  64. param.dir = player:GetDirection()
  65. end
  66. return true
  67. end
  68. function RequestLaunchCommand:checkParam2(param)
  69. local player = global.gamePlayerController:GetMainPlayer()
  70. if not player then
  71. return false
  72. end
  73. -- src & dir, only
  74. param.vecSrc = cc.p(player:GetMapX(), player:GetMapY())
  75. param.vecDst = cc.p(player:GetMapX(), player:GetMapY())
  76. param.dir = player:GetDirection()
  77. return true
  78. end
  79. function RequestLaunchCommand:checkParam3(param)
  80. local player = global.gamePlayerController:GetMainPlayer()
  81. if not player then
  82. return false
  83. end
  84. -- cehck target
  85. local targetID, targetActor = skillUtils.checkTarget()
  86. -- if target, find best pos & dir
  87. if targetID and targetActor then
  88. param.vecSrc = cc.p(player:GetMapX(), player:GetMapY())
  89. param.vecDst = cc.p(targetActor:GetMapX(), targetActor:GetMapY())
  90. param.dir = self:calcDir(param.vecDst, param.vecSrc)
  91. param.targetID = targetID
  92. else
  93. -- default
  94. param.vecSrc = cc.p(player:GetMapX(), player:GetMapY())
  95. param.vecDst = cc.p(player:GetMapX(), player:GetMapY())
  96. param.dir = player:GetDirection()
  97. end
  98. return true
  99. end
  100. function RequestLaunchCommand:checkParam4(param)
  101. local player = global.gamePlayerController:GetMainPlayer()
  102. if not player then
  103. return false
  104. end
  105. local function findDestTarget(skillID)
  106. local SkillProxy = global.Facade:retrieveProxy(global.ProxyTable.Skill)
  107. local inputProxy = global.Facade:retrieveProxy(global.ProxyTable.PlayerInputProxy)
  108. local inputPos = inputProxy:GetLaunchTargetPos()
  109. if SkillProxy:IsAdditionSkill(skillID) then
  110. if inputPos then
  111. local targetID = self:findTargetByMapPos(inputPos, skillID, true)
  112. local destPos = inputPos
  113. return targetID, destPos
  114. else
  115. local targetID = player:GetID()
  116. local destPos = cc.p(player:GetMapX(), player:GetMapY())
  117. return player:GetID(), destPos
  118. end
  119. elseif SkillProxy:IsInputDestSkill(skillID) then
  120. if inputPos then
  121. local autoProxy = global.Facade:retrieveProxy( global.ProxyTable.Auto )
  122. local isAutoFight = autoProxy:IsAutoFightState()
  123. local targetID = isAutoFight and inputProxy:GetLaunchTargetID() or self:findTargetByMapPos(inputPos,skillID)
  124. if isAutoFight and targetID then
  125. inputPos = nil
  126. local actor = global.actorManager:GetActor(targetID)
  127. if actor then
  128. inputPos = cc.p(actor:GetMapX(), actor:GetMapY())
  129. end
  130. end
  131. return targetID, inputPos
  132. else
  133. return nil
  134. end
  135. end
  136. end
  137. -- 1.check target pos
  138. local targetID, targetPos = findDestTarget(param.launchID)
  139. if not targetPos then
  140. return false
  141. end
  142. param.vecSrc = cc.p(player:GetMapX(), player:GetMapY())
  143. param.vecDst = targetPos
  144. param.dir = self:calcDir(param.vecDst, param.vecSrc)
  145. param.targetID = targetID
  146. return true
  147. end
  148. function RequestLaunchCommand:checkParam5(param)
  149. local player = global.gamePlayerController:GetMainPlayer()
  150. if not player then
  151. return false
  152. end
  153. local inputProxy = global.Facade:retrieveProxy(global.ProxyTable.PlayerInputProxy)
  154. local autoProxy = global.Facade:retrieveProxy(global.ProxyTable.Auto)
  155. -- 强攻
  156. local launchType = inputProxy:GetLaunchType()
  157. if launchType == global.MMO.LAUNCH_TYPE_ATTACK then
  158. param.vecSrc = cc.p(player:GetMapX(), player:GetMapY())
  159. param.vecDst = cc.p(player:GetMapX(), player:GetMapY())
  160. param.dir = player:GetDirection()
  161. return true
  162. end
  163. ---------------------------------------------------------
  164. -- can't find target
  165. if nil == inputProxy:GetTargetID() then
  166. autoProxy:ClearAutoLock()
  167. return false
  168. end
  169. -- 无目标或目标无法攻击
  170. if false == proxyUtils.checkLaunchTargetByID(inputProxy:GetTargetID()) then
  171. inputProxy:ClearTarget()
  172. autoProxy:ClearAutoLock()
  173. -- 屏蔽此行,存在怪物血量0但是没死的情况
  174. -- global.Facade:sendNotification( global.NoticeTable.SystemTips, GET_STRING(800402) )
  175. return false
  176. end
  177. ---------------------------------------------------------
  178. -- find target
  179. local targetID, targetActor = skillUtils.checkTarget()
  180. -- find best pos & dir
  181. param.vecSrc = cc.p(player:GetMapX(), player:GetMapY())
  182. param.vecDst = cc.p(targetActor:GetMapX(), targetActor:GetMapY())
  183. param.dir = self:calcDir(param.vecDst, param.vecSrc)
  184. param.targetID = targetID
  185. return true
  186. end
  187. function RequestLaunchCommand:execute(note)
  188. local data = note:getBody()
  189. local skillID = data.skillID
  190. local inputDir = data.dir
  191. local inputDst = data.dest
  192. if not skillID then
  193. return nil
  194. end
  195. local player = global.gamePlayerController:GetMainPlayer()
  196. if not player then
  197. return nil
  198. end
  199. local inputProxy = global.Facade:retrieveProxy(global.ProxyTable.PlayerInputProxy)
  200. local skillProxy = global.Facade:retrieveProxy(global.ProxyTable.Skill)
  201. local autoProxy = global.Facade:retrieveProxy(global.ProxyTable.Auto)
  202. local priority = inputProxy:GetLaunchPriority()
  203. if skillProxy:IsComboSkill(skillID) then
  204. skillProxy:ClearComboLanunchID()
  205. end
  206. -- 请求释放参数
  207. local requestParam =
  208. {
  209. launchID = skillID,
  210. targetID = nil,
  211. dir = nil,
  212. vecSrc = nil,
  213. vecDst = nil,
  214. }
  215. if GUIFunction and GUIFunction.OnCheckAllowLaunchSkillBefore then
  216. if not GUIFunction:OnCheckAllowLaunchSkillBefore(skillID) then
  217. releasePrint("GUIFunction:OnCheckAllowLaunchSkill ban skillID ", skillID)
  218. inputProxy:ClearLaunch()
  219. return nil
  220. end
  221. end
  222. -- 1.check base condition( mp? cd? )
  223. local ret = skillProxy:CheckAbleToLaunch(skillID)
  224. if 1 ~= ret then
  225. inputProxy:ClearLaunch()
  226. return nil
  227. end
  228. -- 2.find skill info
  229. local skillConfig = skillProxy:FindConfigBySkillID(skillID)
  230. if not skillConfig then
  231. -- debug
  232. inputProxy:ClearLaunch()
  233. print("can not find skill info, check config !" .. skillID)
  234. return nil
  235. end
  236. -- 3.check target( targetID targetPos dir )
  237. local launchMode = skillProxy:GetLaunchMode(skillID)
  238. local checkParamFunc = self._checkParamFunc[launchMode]
  239. if not checkParamFunc or not checkParamFunc(requestParam) then
  240. inputProxy:ClearLaunch()
  241. return nil
  242. end
  243. -- 4.check attack range.
  244. local moveBestPos = (skillConfig.bestPos ~= 0)
  245. if nil == requestParam.targetID and requestParam.vecSrc.x == requestParam.vecDst.x and requestParam.vecSrc.y == requestParam.vecDst.y then
  246. moveBestPos = false
  247. end
  248. if moveBestPos then
  249. local srcX = requestParam.vecSrc.x
  250. local srcY = requestParam.vecSrc.y
  251. local dstX = requestParam.vecDst.x
  252. local dstY = requestParam.vecDst.y
  253. local targetID = requestParam.targetID
  254. -- move best pos to launch
  255. local launchX, launchY, moveX, moveY = skillUtils.findBestLaunchPos(skillID, targetID, srcX, srcY, dstX, dstY)
  256. if srcX ~= launchX or srcY ~= launchY then
  257. if srcX == moveX and srcY == moveY then
  258. moveX = launchX
  259. moveY = launchY
  260. end
  261. local dest = cc.p(moveX, moveY)
  262. dest.skillID = skillID
  263. dest.targetID = targetID
  264. dest.type = global.MMO.INPUT_MOVE_TYPE_LAUNCH
  265. global.Facade:sendNotification(global.NoticeTable.InputMove, dest)
  266. inputProxy:ResetLaunchDirty()
  267. -- check path points
  268. local pathPoints = inputProxy:GetCurrPathPoint()
  269. if pathPoints == 0 then
  270. -- ingore target
  271. local target = nil
  272. if targetID then
  273. target = global.actorManager:GetActor(targetID)
  274. if target then
  275. if not target:IsPauseIgnored() and not target:IsIngored() then
  276. local isPauseIgnored = false
  277. if target:IsBoss() then
  278. isPauseIgnored = true
  279. end
  280. if isPauseIgnored and autoProxy:IsAutoFightState() and global.PathFindController:checkActorLimitObstacle(cc.p(player:GetMapX(), player:GetMapY()), cc.p(target:GetMapX(), target:GetMapY())) then
  281. target:PauseIgnoredActor(true)
  282. else
  283. target:IgnoreActor(true)
  284. end
  285. end
  286. end
  287. end
  288. -- clear launch data
  289. if not target or (not target:IsPauseIgnored() and target:IsIngored()) then
  290. autoProxy:ClearAutoLock()
  291. inputProxy:ClearLaunch()
  292. inputProxy:ClearTarget()
  293. end
  294. end
  295. return nil
  296. end
  297. elseif skillProxy:IsForceDis(skillID) then
  298. local srcX = requestParam.vecSrc.x
  299. local srcY = requestParam.vecSrc.y
  300. local dstX = requestParam.vecDst.x
  301. local dstY = requestParam.vecDst.y
  302. local minLaunchDis = tonumber(skillProxy:GetMinDistance(skillID))
  303. local maxLaunchDis = tonumber(skillProxy:GetMaxDistance(skillID))
  304. if minLaunchDis and maxLaunchDis then
  305. local len = squLen( srcX - dstX, srcY - dstY )
  306. local minRange = minLaunchDis * minLaunchDis
  307. local maxRange = maxLaunchDis * maxLaunchDis
  308. if len < minRange or len > maxRange then
  309. inputProxy:ResetLaunchDirty()
  310. return nil
  311. end
  312. end
  313. end
  314. local targetID = requestParam.targetID
  315. if targetID then
  316. local target = global.actorManager:GetActor(targetID)
  317. if target and target:IsPauseIgnored() then
  318. target:PauseIgnoredActor()
  319. end
  320. end
  321. -- 5. check dir!
  322. if requestParam.dir == global.MMO.ORIENT_INVAILD then
  323. requestParam.dir = player:GetDirection()
  324. end
  325. -- 6. assist
  326. local AssistProxy = global.Facade:retrieveProxy(global.ProxyTable.AssistProxy)
  327. AssistProxy:autoDressEquipSkill(skillID)
  328. -- 7. request server
  329. -- debug
  330. -- print( "request server:", param1, GetTimeInMS() )
  331. -- dump(requestParam)
  332. local sendData = {
  333. skillID = skillID,
  334. dir = requestParam.dir,
  335. srcX = requestParam.vecSrc.x,
  336. srcY = requestParam.vecSrc.y,
  337. destX = requestParam.vecDst.x,
  338. destY = requestParam.vecDst.y,
  339. targetID = requestParam.targetID,
  340. }
  341. local netMsgID = (skillConfig.action == 0 and global.MsgType.MSG_CS_PLAYER_SKILL_ATTACK or global.MsgType.MSG_CS_PLAYER_SKILL_LAUNCH)
  342. local jsonStr = cjson.encode(sendData)
  343. LuaSendMsg(netMsgID, skillID, 0, 0, 0, jsonStr, string.len(jsonStr))
  344. -- dump(sendData)
  345. -- 7.enter cd
  346. if skillProxy:IsComboSkill(skillID) then
  347. global.Facade:sendNotification(global.NoticeTable.ComboSkillEnterCD, skillID)
  348. else
  349. global.Facade:sendNotification(global.NoticeTable.SkillEnterCD, skillID)
  350. end
  351. -- 8.enter action, and play skill effect immediately
  352. local action =
  353. {
  354. skillID = skillID,
  355. actor = player,
  356. dir = requestParam.dir,
  357. ActionId = skillProxy:GetActionID(skillID),
  358. }
  359. if skillID == global.MMO.SKILL_INDEX_YMCZ then
  360. -- 野蛮
  361. player:SetAction(global.MMO.ACTION_DASH_WAITING, true)
  362. elseif skillID == global.MMO.SKILL_INDEX_SBYS then
  363. -- 十步一杀
  364. player:SetAction(global.MMO.ACTION_DASH_WAITING, true)
  365. elseif skillID == global.MMO.SKILL_INDEX_DIG then
  366. -- 挖矿
  367. player:SetDirection(inputDir)
  368. player:SetAction(global.MMO.ACTION_MINING)
  369. -- 特殊处理下,挖矿时普通攻击进入CD,处理下挖矿的CD问题
  370. global.Facade:sendNotification(global.NoticeTable.SkillEnterCD, global.MMO.SKILL_INDEX_BASIC)
  371. elseif skillConfig.action == 0 then
  372. -- 攻击
  373. global.Facade:sendNotification(global.NoticeTable.ActorEnterAttackAction, action)
  374. elseif skillConfig.action == 1 then
  375. -- 施法
  376. global.Facade:sendNotification(global.NoticeTable.ActorEnterSkillAction, action)
  377. end
  378. -- 刀刀刺杀
  379. -- 强攻不处理
  380. local presentSkillID = skillID
  381. if skillID == global.MMO.SKILL_INDEX_CSJS and CHECK_SETTING(global.MMO.SETTING_IDX_DAODAOCISHA) == 0 and inputProxy:GetLaunchType() ~= global.MMO.LAUNCH_TYPE_ATTACK then
  382. local distance = inputProxy:calcMapDistance(requestParam.vecDst, requestParam.vecSrc)
  383. if distance < 2 then
  384. presentSkillID = global.MMO.SKILL_INDEX_BASIC
  385. end
  386. end
  387. -- persent
  388. if skillID ~= global.MMO.SKILL_INDEX_DIG then
  389. local present =
  390. {
  391. skillID = skillProxy:GetSkillPresentReplaceID(presentSkillID),
  392. launchX = requestParam.vecSrc.x,
  393. launchY = requestParam.vecSrc.y,
  394. hitX = requestParam.vecDst.x,
  395. hitY = requestParam.vecDst.y,
  396. dir = requestParam.dir,
  397. skillStage = 1,
  398. launcherID = player:GetID()
  399. }
  400. global.Facade:sendNotification(global.NoticeTable.RequestSkillPresent, present)
  401. end
  402. -- 开关技能关闭
  403. if skillID == global.MMO.SKILL_INDEX_GSJS
  404. or skillID == global.MMO.SKILL_INDEX_LHJF
  405. or skillID == global.MMO.SKILL_INDEX_LYJF
  406. or skillID == global.MMO.SKILL_INDEX_LTJF
  407. or skillID == global.MMO.SKILL_INDEX_ZRJF
  408. or skillID == global.MMO.SKILL_INDEX_KTZ
  409. or skillID == global.MMO.SKILL_INDEX_ZHJS
  410. then
  411. skillProxy:SkillOff(skillID)
  412. end
  413. -- 普攻音效
  414. if presentSkillID == global.MMO.SKILL_INDEX_BASIC then
  415. global.Facade:sendNotification(global.NoticeTable.Audio_Play, {type=global.MMO.SND_TYPE_SKILL_ATTACK})
  416. --auto on skill 普攻
  417. if not skillProxy:IsOnSkill(global.MMO.SKILL_INDEX_CSJS) and CHECK_SETTING(global.MMO.SETTING_IDX_DAODAOCISHA) == 1 then
  418. skillProxy:RequestSkillOnoff(global.MMO.SKILL_INDEX_CSJS)
  419. end
  420. end
  421. -- 十步一杀 锁定自动释放
  422. if CHECK_SETTING(global.MMO.SETTING_IDX_ALWAYS_ATTACK) == 1 and skillID == global.MMO.SKILL_INDEX_SBYS then
  423. if not autoProxy:IsAutoLockState() and not autoProxy:IsAFKState() and skillProxy:IsLockTargetSkill(global.MMO.SKILL_INDEX_BASIC) then
  424. autoProxy:SetIsAutoLockState(true)
  425. autoProxy:SetAutoLockSkillID(global.MMO.SKILL_INDEX_BASIC)
  426. end
  427. end
  428. skillProxy:ResetDelaySkillLaunch( skillID )
  429. -- clear launch data
  430. inputProxy:ClearLaunch()
  431. end
  432. return RequestLaunchCommand