KSkills.cpp
上传用户:dzyhzl
上传日期:2019-04-29
资源大小:56270k
文件大小:89k
源码类别:

模拟服务器

开发平台:

C/C++

  1.             // KSkills.cpp: implementation of the KSkills class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "KCore.h"
  5. #ifdef _STANDALONE
  6. #include "KSG_StringProcess.h"
  7. #else
  8. #include "../../Engine/Src/KSG_StringProcess.h"
  9. #endif
  10. #include "KSkills.h"
  11. #include "KMissle.h"
  12. #include "KMissleSet.h"
  13. #include "KNpc.h"
  14. #include "math.h"
  15. #include "KNpcSet.h"
  16. #include "KSubWorld.h"
  17. #include "KMath.h"
  18. #include "KEngine.h"
  19. #include "KTabFile.h"
  20. #include "KTabFileCtrl.h"
  21. #include "KMissleMagicAttribsData.h"
  22. #include "KPlayer.h"
  23. #ifndef _SERVER
  24. #include "../../Represent/iRepresent/iRepresentshell.h"
  25. #include "scene/KScenePlaceC.h"
  26. #include "../../Represent/iRepresent/KRepresentUnit.h"
  27. #include "imgref.h"
  28. #include "KMagicDesc.h"
  29. #include "KOption.h"
  30. #endif
  31. //#define SHOW_SKILL_MORE_INFO
  32. #define  NPCINDEXOFOBJECT 0 //物件发魔法时所对应的Npc编号
  33. const char * g_MagicID2String(int nAttrib);
  34. extern  const KScript * g_GetScript(DWORD dwScriptId);
  35. //////////////////////////////////////////////////////////////////////
  36. // Construction/Destruction
  37. //////////////////////////////////////////////////////////////////////
  38. /*!*****************************************************************************
  39. // Function : KSkill::KSkill
  40. // Purpose : 
  41. // Return : 
  42. // Comments :
  43. // Author : RomanDou
  44. *****************************************************************************/
  45. KSkill::KSkill()
  46. {
  47. m_nFlySkillId =  m_nCollideSkillId = m_nVanishedSkillId = 0;
  48.     // add by FreewayChen in 2003.6.6
  49.     m_nImmediateAttribsNum = m_nStateAttribsNum = m_nMissleAttribsNum = m_nDamageAttribsNum = 0;
  50. m_nSkillCostType = attrib_mana;
  51.     m_nWaitTime = 0;
  52. m_nEquiptLimited = 0;
  53. m_bDoHurt = 1;
  54. #ifndef _SERVER
  55. m_szSkillDesc[0] = 0;
  56. m_szManPreCastSoundFile[0] = 0;
  57. m_szFMPreCastSoundFile[0] = 0;
  58. #else
  59. m_dwSkillLevelUpScriptID = 0;
  60. m_dwSkillLevelDataScriptId = 0;
  61. #endif
  62. }
  63. /*!*****************************************************************************
  64. // Function : KSkill::~KSkill
  65. // Purpose : 
  66. // Return : 
  67. // Comments :
  68. // Author : RomanDou
  69. *****************************************************************************/
  70. KSkill::~KSkill()
  71. {
  72. }
  73. /*!*****************************************************************************
  74. // Function : KSkill::Param2PCoordinate
  75. // Purpose : 
  76. // Return : 
  77. // Argumant : int nLauncher
  78. // Argumant : int nParam1
  79. // Argumant : int nParam2
  80. // Argumant : int nParam3
  81. // Argumant : int *npPX
  82. // Argumant : int *npPY
  83. // Comments :
  84. // Author : RomanDou
  85. *****************************************************************************/
  86. inline int KSkill::Param2PCoordinate(int nLauncher, int nParam1, int nParam2 , int *npPX, int *npPY, eSkillLauncherType eLauncherType)  const 
  87. {
  88. int nRegionId, nDesMapX, nDesMapY ;
  89. int nTargetId = -1;
  90. if (eLauncherType == SKILL_SLT_Obj) return 0;
  91. switch(nParam1)
  92. {
  93. case -1://nParam2 参数指向某个Npc,或Obj的Index
  94. nTargetId = nParam2;
  95. nRegionId = Npc[nParam2].m_RegionIndex;
  96. nDesMapX = Npc[nParam2].m_MapX;
  97. nDesMapY = Npc[nParam2].m_MapY;
  98. if (eLauncherType == SKILL_SLT_Npc)
  99. SubWorld[Npc[nLauncher].m_SubWorldIndex].Map2Mps(nRegionId, nDesMapX , nDesMapY, Npc[nParam2].m_OffX , Npc[nParam2].m_OffY, npPX, npPY);
  100. else if(eLauncherType == SKILL_SLT_Obj)
  101. SubWorld[Object[nLauncher].m_nSubWorldID].Map2Mps(nRegionId, nDesMapX, nDesMapY, Object[nParam2].m_nOffX , Object[nParam2].m_nOffY, npPX, npPY);
  102. else;
  103. break;
  104. case -2://nParam 参数指向某个方向
  105. break;
  106. default://默认时, nParam1 与nParam2 为实际点坐标
  107. *npPX = nParam1;
  108. *npPY = nParam2;
  109. break;
  110. }
  111. if (*npPX < 0 || *npPY < 0)
  112. g_DebugLog("Param2PCoordinate函数获得参数违法!nParam1 ,nParam2 [%d,%d], nPX,nPY", nParam1, nParam2, *npPX, * npPY);
  113. return nTargetId;
  114. }
  115. BOOL KSkill::CanCastSkill(int nLauncher, int &nParam1, int &nParam2)  const 
  116. {
  117. //对自已的主动辅助技能
  118. if (m_bTargetSelf && nParam1 != -1) 
  119. {
  120. nParam1 = -1;
  121. nParam2 = nLauncher;
  122. return TRUE;
  123. }
  124. else
  125. {
  126. if (m_bTargetOnly && nParam1 != -1) return FALSE;
  127. if (nParam1 == -1)
  128. {
  129. if ( nParam2 <= 0 || nParam2 >= MAX_NPC) return FALSE;
  130. NPC_RELATION  Relation = NpcSet.GetRelation(nLauncher, nParam2);
  131. if (m_bTargetEnemy)
  132. {
  133. if (Relation & relation_enemy) goto relationisvalid;
  134. }
  135. if (m_bTargetAlly)
  136. {
  137. if (Relation & relation_ally) goto relationisvalid;
  138. }
  139. if (m_bTargetSelf)
  140. {
  141. if (Relation & relation_self) goto relationisvalid;
  142. }
  143. return FALSE;
  144. }
  145. }
  146. relationisvalid:
  147. if (Npc[nLauncher].IsPlayer())
  148. {
  149. if (IsPhysical())
  150. {
  151. int nWeapoinSkill = Npc[nLauncher].GetCurActiveWeaponSkill();
  152. if ((DWORD)nWeapoinSkill != m_nId)
  153. {
  154. return FALSE;
  155. }
  156. }
  157. //-2表示技能不受当前装备的限制,
  158. //-1表示空手限制
  159. //0-99受某种近身攻击类的装备限制 取值为该装备的具体类别号
  160. //100-199受某种远程攻击类的装备限制 取值为该装备的具体类别号 加100
  161. if (-2 != m_nEquiptLimited)
  162. {
  163. #ifdef _SERVER
  164. int nPlayerIdx = Npc[nLauncher].GetPlayerIdx();
  165. #else
  166. int nPlayerIdx = CLIENT_PLAYER_INDEX;
  167. #endif
  168. int nDetailType = Player[nPlayerIdx].m_ItemList.GetWeaponType();
  169. int nParticularType = Player[nPlayerIdx].m_ItemList.GetWeaponParticular();
  170. //近身武器
  171. if (nDetailType == 0)
  172. {
  173. }//远程武器
  174. else if (nDetailType == 1)
  175. {
  176. nParticularType += MAX_MELEEWEAPON_PARTICULARTYPE_NUM;
  177. }//空手
  178. else if (nDetailType == -1)
  179. {
  180. nParticularType = -1;
  181. }
  182. if (nParticularType != m_nEquiptLimited)
  183. return FALSE;
  184. }
  185. //0表示不限制
  186. //1表示不可以骑马发该技能
  187. //2表示必须骑马发该技能
  188. if (m_nHorseLimited)
  189. {
  190. switch(m_nHorseLimited)
  191. {
  192. case 1:
  193. {
  194. if (Npc[nLauncher].m_bRideHorse)
  195. return FALSE;
  196. }
  197. break;
  198. case 2:
  199. {
  200. if (!Npc[nLauncher].m_bRideHorse)
  201. return FALSE;
  202. }
  203. break;
  204. default:
  205. return FALSE;
  206. }
  207. }
  208. if ((m_bTargetOnly) && nParam1 == -1)
  209. {
  210. #ifndef _SERVER
  211. int distance = NpcSet.GetDistance(nLauncher, nParam2);
  212. if (distance > GetAttackRadius()) return FALSE;
  213. #endif
  214. }
  215. /*else
  216. {
  217. if (nParam1 < 0 || nParam2 < 0) return FALSE;
  218.   #ifndef _SERVER
  219.   int nLauncherPX = 0, nLauncherPY = 0;
  220.   Npc[nLauncher].GetMpsPos(&nLauncherPX, &nLauncherPY);
  221.   int ndistance = g_GetDistance(nLauncherPX, nLauncherPY, nParam1, nParam2);
  222.   if (ndistance > GetAttackRadius()) return FALSE;
  223.   #endif
  224.   }
  225. */
  226. }
  227. return TRUE;
  228. }
  229. // 当玩家调用某个技能时发生 [5/28/2002]
  230. // 客户端和服务器端在技能的调用方面有一些不同
  231. // 服务器端一般收到的经过客户端处理完的参数
  232. // 游戏世界以消息命令机制执行每个变化,因此对于发技能应该也是统一数据接口
  233. // 客户端时,如果该消息是来自本机玩家的输入,则必须将其转换为实际的消息
  234. // 来执行。同时还应将转换好的消息传给服务器端
  235. /*
  236. 有关传的参数是MapX,还是PointX根据具体的魔法技能而定
  237. 比如一般飞行魔法为Map坐标,而定点魔法为Point坐标
  238. */
  239. /*
  240. 注意当调用Cast时,必须已确保当前的nLauncherIndex与Socket相对应的dwId一致,即IsMatch()通过。
  241. */
  242. /*!*****************************************************************************
  243. // Function : KSkill::Cast
  244. // Purpose : 发技能的统一接口
  245. // Return : 
  246. // Argumant : int nLauncher 发送者Id
  247. // Argumant : int nParam1   
  248. // Argumant : int nParam2
  249. // Argumant : int nWaitTime 发送的延迟时间
  250. // Argumant : eSkillLauncherType eLauncherType 发送者类型
  251. // Comments :
  252. // Author : RomanDou
  253. *****************************************************************************/
  254. BOOL KSkill::Cast(int nLauncher, int nParam1, int nParam2, int nWaitTime, eSkillLauncherType eLauncherType)  const 
  255. {
  256. //-----------------接口函数入口点,检测参数合法性-------------------------------
  257. if (nLauncher < 0 )
  258. {
  259. g_DebugLog("Skill::Cast(), nLauncher < 0 , Return False;"); 
  260. return FALSE; 
  261. }
  262. //检查发送者是否符合要求
  263. switch(eLauncherType)
  264. {
  265. case SKILL_SLT_Npc:
  266. {
  267. if (MAX_NPC <= nLauncher) return FALSE;
  268. if (Npc[nLauncher].m_dwID < 0) return FALSE;
  269. if (nParam1 == -1)
  270. {
  271. if (nParam2 >= MAX_NPC) 
  272. return FALSE;
  273. if (
  274. (Npc[nParam2].m_Index <= 0)
  275. || Npc[nLauncher].m_SubWorldIndex != Npc[nParam2].m_SubWorldIndex
  276. )
  277. return FALSE;
  278. }
  279. }
  280. break;
  281. case SKILL_SLT_Obj:
  282. {
  283. return FALSE;
  284. if (MAX_OBJECT <= nLauncher) return FALSE;
  285. if (Object[nLauncher].m_nDataID < 0) return FALSE;
  286. }
  287. break;
  288. case SKILL_SLT_Missle:
  289. {
  290. if (MAX_MISSLE <= nLauncher) 
  291. return FALSE;
  292. if (Missle[nLauncher].m_nMissleId < 0) 
  293. return FALSE;
  294. if (nParam1 == -1)
  295. {
  296. if (nParam2 >= MAX_NPC) 
  297. return FALSE;
  298. if ((Npc[nParam2].m_Index <= 0) ||  Missle[nLauncher].m_nSubWorldId != Npc[nParam2].m_SubWorldIndex)
  299. return FALSE;
  300. }
  301. }
  302. break;
  303. default:
  304. {
  305. return FALSE;
  306. }
  307. }
  308. if (nParam1 < 0 && nParam2 < 0 ) 
  309. return FALSE;
  310. if (nWaitTime < 0 ) 
  311. {
  312. g_DebugLog("Call Skill::Cast(), nWaitTime < 0 "); 
  313. nWaitTime = 0;
  314. }
  315. //------------------------------------------------------------------------------
  316. switch(m_eSkillStyle)
  317. {
  318. case SKILL_SS_Missles: //发子弹
  319. {
  320. CastMissles(nLauncher, nParam1, nParam2, nWaitTime, eLauncherType);
  321. }
  322. break;
  323. case SKILL_SS_Melee:
  324. {
  325. }break;
  326. case SKILL_SS_InitiativeNpcState: //改变角色的主动状态
  327. {
  328. CastInitiativeSkill(nLauncher, nParam1, nParam2, nWaitTime);
  329. }
  330. break;
  331. case SKILL_SS_PassivityNpcState: //改变角色的被动状态
  332. {
  333. CastPassivitySkill(nLauncher, nParam1, nParam2, nWaitTime);
  334. }
  335. break;
  336. case SKILL_SS_CreateNpc: //产生新的Npc、怪物 
  337. {
  338. }
  339. break;
  340. case SKILL_SS_BuildPoison: //炼毒术
  341. {
  342. }
  343. break;
  344. case SKILL_SS_AddPoison: //加毒术
  345. {
  346. }
  347. break;
  348. case SKILL_SS_GetObjDirectly: //隔空取物
  349. {
  350. }
  351. break;
  352. case SKILL_SS_StrideObstacle: //跨越障碍
  353. {
  354. }
  355. break;
  356. case SKILL_SS_BodyToObject: //尸变
  357. {
  358. }
  359. break;
  360. case SKILL_SS_Mining: //采矿
  361. {
  362. }
  363. break;
  364. case SKILL_SS_RepairWeapon: //修复术
  365. {
  366. }
  367. break;
  368. case SKILL_SS_Capture: //捕捉术 
  369. {
  370. }
  371. break;
  372. }
  373. if (m_bStartEvent && m_nStartSkillId > 0 && m_nEventSkillLevel > 0)
  374. {
  375. KSkill * pOrdinSkill = (KSkill *) g_SkillManager.GetSkill(m_nStartSkillId, m_nEventSkillLevel);
  376. if (!pOrdinSkill) 
  377.             return FALSE;
  378.         pOrdinSkill->Cast(nLauncher, nParam1, nParam2, nWaitTime, eLauncherType);
  379. }
  380. return TRUE;   
  381. }
  382. /*!*****************************************************************************
  383. // Function : KSkill::Vanish
  384. // Purpose : 子弹生命结束时回调
  385. // Return : 
  386. // Argumant : KMissle* Missle
  387. // Comments :
  388. // Author : RomanDou
  389. *****************************************************************************/
  390. void KSkill::Vanish(KMissle * pMissle)  const 
  391. {
  392. OnMissleEvent(Missle_VanishEvent, pMissle);
  393. }
  394. BOOL KSkill::OnMissleEvent(unsigned short usEvent, KMissle * pMissle)  const 
  395. {
  396. if (!pMissle) 
  397.         return FALSE;
  398. int nLauncherIdx = pMissle->m_nLauncher;
  399.     if (
  400. pMissle->m_nMissleId <= 0 
  401. || pMissle->m_nMissleId >= MAX_MISSLE 
  402. || nLauncherIdx <= 0
  403. || nLauncherIdx >= MAX_NPC
  404. || Npc[nLauncherIdx].m_Index <= 0
  405. )
  406.         return FALSE;
  407. if (
  408. (!Npc[nLauncherIdx].IsMatch(pMissle->m_dwLauncherId)) 
  409. || Npc[nLauncherIdx].m_SubWorldIndex != pMissle->m_nSubWorldId
  410. || Npc[nLauncherIdx].m_RegionIndex < 0
  411. )
  412. {
  413. return FALSE;
  414. }
  415. int nEventSkillId = 0;
  416. int nEventSkillLevel = 0;
  417. switch(usEvent)
  418. {
  419. case Missle_FlyEvent:
  420. if (!m_bFlyingEvent || m_nFlySkillId <= 0 || m_nEventSkillLevel <= 0)
  421. return FALSE;
  422. nEventSkillId = m_nFlySkillId ;
  423. nEventSkillLevel = m_nEventSkillLevel;
  424. break;
  425. case Missle_StartEvent:
  426. if (!m_bStartEvent || m_nStartSkillId <= 0 || m_nEventSkillLevel <= 0)
  427. return FALSE;
  428. nEventSkillId = m_nStartSkillId ;
  429. nEventSkillLevel = m_nEventSkillLevel;
  430. break;
  431. case Missle_VanishEvent:
  432. if (!m_bVanishedEvent || m_nVanishedSkillId <= 0 || m_nEventSkillLevel <= 0)
  433. return FALSE;
  434. nEventSkillId = m_nVanishedSkillId ;
  435. nEventSkillLevel = m_nEventSkillLevel;
  436. break;
  437. case Missle_CollideEvent:
  438. if (!m_bCollideEvent || m_nCollideSkillId <= 0 || m_nEventSkillLevel <= 0)
  439. return FALSE;
  440. nEventSkillId = m_nCollideSkillId;
  441. nEventSkillLevel = m_nEventSkillLevel;
  442. break;
  443. default:
  444. return FALSE;
  445. }
  446. int nDesPX = 0, nDesPY = 0;
  447. if (m_bByMissle)
  448. {
  449. pMissle->GetMpsPos(&nDesPX, &nDesPY);
  450. }
  451. else
  452. {
  453. Npc[nLauncherIdx].GetMpsPos(&nDesPX, &nDesPY);
  454. }
  455. KSkill * pOrdinSkill = (KSkill *)g_SkillManager.GetSkill(nEventSkillId, nEventSkillLevel);
  456. if (!pOrdinSkill) 
  457.         return FALSE;
  458. BOOL bRetCode = FALSE;
  459.     if (m_bByMissle)    //When Event
  460. {
  461. if (pOrdinSkill->GetSkillStyle() == SKILL_SS_Missles)
  462. {
  463. bRetCode = pOrdinSkill->CastMissles(pMissle->m_nMissleId, nDesPX, nDesPY, 0, SKILL_SLT_Missle);
  464. }
  465. }
  466. else
  467. {
  468. if (pOrdinSkill->GetSkillStyle() == SKILL_SS_Missles)
  469. {   
  470.             bRetCode = pOrdinSkill->CastMissles(nLauncherIdx, nDesPX, nDesPY, 0, SKILL_SLT_Npc);
  471. }
  472. }
  473. return bRetCode;
  474. }
  475. /*!*****************************************************************************
  476. // Function : KSkill::FlyEvent
  477. // Purpose : 
  478. // Return : void 
  479. // Argumant : int nMissleId
  480. // Comments :
  481. // Author : RomanDou
  482. *****************************************************************************/
  483. void KSkill::FlyEvent(KMissle * pMissle)  const 
  484. {
  485. OnMissleEvent(Missle_FlyEvent, pMissle);
  486. }
  487. /*!*****************************************************************************
  488. // Function : KSkill::Collidsion
  489. // Purpose : 子弹被撞时回调
  490. // Return : 
  491. // Argumant : KMissle* Missle
  492. // Comments :
  493. // Author : RomanDou
  494. *****************************************************************************/
  495. void KSkill::Collidsion(KMissle * pMissle)  const 
  496. {
  497. OnMissleEvent(Missle_CollideEvent, pMissle);
  498. }
  499. /*!*****************************************************************************
  500. // Function : KSkill::CastMissles
  501. // Purpose : 发送子弹技能
  502. // Return : 
  503. // Argumant : int nLauncher  发送者id
  504. // Argumant : int nParam1
  505. // Argumant : int nParam2
  506. // Argumant : int nWaitTime  延长时间
  507. // Argumant : eSkillLauncherType eLauncherType 发送者类型
  508. // Comments :
  509. // Author : RomanDou
  510. *****************************************************************************/
  511. BOOL KSkill::CastMissles(int nLauncher, int nParam1, int nParam2, int nWaitTime  , eSkillLauncherType eLauncherType )  const 
  512. {
  513. int nRegionId = 0;
  514. int nDesMapX = 0;//地图坐标
  515. int nDesMapY = 0;
  516. int nDesOffX = 0;
  517. int nDesOffY = 0;
  518. int nSrcOffX = 0;
  519. int nSrcOffY = 0;
  520. int nSrcPX = 0;//点坐标
  521. int nSrcPY = 0;
  522. int nDesPX = 0;
  523. int nDesPY = 0;
  524. int nDistance = 0;
  525. int nDir = 0;
  526. int nDirIndex = 0;
  527. int nTargetId = -1;
  528. int nRefPX = 0;
  529. int nRefPY = 0;
  530. TOrdinSkillParam SkillParam ;
  531. SkillParam.eLauncherType = SKILL_SLT_Npc;
  532. SkillParam.nParent = 0;
  533. SkillParam.eParentType = (eSkillLauncherType)0;
  534. SkillParam.nWaitTime = nWaitTime;
  535. SkillParam.nTargetId = 0;
  536. if (nLauncher <= 0) return FALSE;
  537. switch(m_eMisslesForm)
  538. {
  539. /*
  540. 火墙时,第一数字参数表示子弹之间的长度间隔
  541. X2  = X1 + N * SinA
  542. Y2  = Y2 - N * CosA
  543. */
  544. case SKILL_MF_Wall: //墙形 多个子弹呈垂直方向排列,类式火墙状
  545. {
  546. //墙形魔法不可以只传方向
  547. if (nParam1 == SKILL_SPT_Direction) return FALSE;
  548. switch(eLauncherType)
  549. {
  550. case SKILL_SLT_Npc:
  551. {
  552. nTargetId = Param2PCoordinate(nLauncher,nParam1, nParam2, &nDesPX, &nDesPY,  SKILL_SLT_Npc);
  553. if (Npc[nLauncher].m_SubWorldIndex < 0) 
  554. {
  555. return FALSE;
  556. }
  557. SubWorld[Npc[nLauncher].m_SubWorldIndex].Map2Mps(Npc[nLauncher].m_RegionIndex, Npc[nLauncher].m_MapX, Npc[nLauncher].m_MapY, Npc[nLauncher].m_OffX, Npc[nLauncher].m_OffY, &nSrcPX, &nSrcPY);
  558. nDirIndex = g_GetDirIndex(nSrcPX, nSrcPY, nDesPX, nDesPY);
  559. nDir = g_DirIndex2Dir(nDirIndex, MaxMissleDir);
  560. nDir = nDir + MaxMissleDir / 4;
  561. if (nDir >= MaxMissleDir) nDir -= MaxMissleDir;
  562. SkillParam.nLauncher = nLauncher;
  563. SkillParam.eLauncherType = eLauncherType;
  564. CastWall(&SkillParam , nDir, nDesPX, nDesPY);
  565. } break;
  566. case SKILL_SLT_Obj:
  567. {
  568. }break;
  569. case SKILL_SLT_Missle:
  570. {
  571. KMissle * pMissle = &Missle[nLauncher];
  572. if (!Npc[pMissle->m_nLauncher].IsMatch(pMissle->m_dwLauncherId)) return FALSE;
  573. SubWorld[Missle[nLauncher].m_nSubWorldId].Map2Mps(pMissle->m_nRegionId, pMissle->m_nCurrentMapX, pMissle->m_nCurrentMapY , pMissle->m_nXOffset, pMissle->m_nYOffset, &nRefPX, &nRefPY);
  574. int nDir = pMissle->m_nDir + MaxMissleDir / 4;
  575. if (nDir >= MaxMissleDir) nDir -= MaxMissleDir;
  576. SkillParam.nLauncher = pMissle->m_nLauncher;
  577. SkillParam.nParent = nLauncher;
  578. SkillParam.nParent = SKILL_SLT_Missle;
  579. SkillParam.nTargetId = pMissle->m_nFollowNpcIdx;
  580. CastWall(&SkillParam,  nDir, nRefPX, nRefPY);
  581. }break;
  582. }
  583. }break;
  584. case SKILL_MF_Line: //线形 多个子弹呈平行于玩家方向排列
  585. {
  586. if (nParam1 == SKILL_SPT_Direction)
  587. {
  588. switch(eLauncherType)
  589. {
  590. case SKILL_SLT_Npc:
  591. {
  592. SubWorld[Npc[nLauncher].m_SubWorldIndex].Map2Mps(Npc[nLauncher].m_RegionIndex, Npc[nLauncher].m_MapX, Npc[nLauncher].m_MapY, Npc[nLauncher].m_OffX, Npc[nLauncher].m_OffY, &nSrcPX, &nSrcPY);
  593. if (nParam2 > MaxMissleDir || nParam2 < 0) return FALSE;
  594. nDir = nParam2;
  595. SkillParam.nLauncher = nLauncher;
  596. SkillParam.eLauncherType = eLauncherType;
  597. SkillParam.nTargetId = nTargetId;
  598. CastLine(&SkillParam, nDir, nSrcPX,nSrcPY);
  599. }break;
  600. case SKILL_SLT_Obj:
  601. {
  602. }break;
  603. case SKILL_SLT_Missle:
  604. {
  605. KMissle * pMissle = &Missle[nLauncher];
  606. if (nParam2 > MaxMissleDir || nParam2 < 0) return FALSE;
  607. if (!Npc[pMissle->m_nLauncher].IsMatch(pMissle->m_dwLauncherId)) return FALSE;
  608. nDir = nParam2;
  609. SubWorld[pMissle->m_nSubWorldId].Map2Mps(pMissle->m_nRegionId, pMissle->m_nCurrentMapX, pMissle->m_nCurrentMapY , pMissle->m_nXOffset, pMissle->m_nYOffset, &nRefPX, &nRefPY);
  610. SkillParam.nLauncher = pMissle->m_nLauncher;
  611. SkillParam.nParent = nLauncher;
  612. SkillParam.nTargetId = pMissle->m_nFollowNpcIdx;
  613. CastWall(&SkillParam, nDir,  nRefPX, nRefPY);
  614. }break;
  615. }
  616. }
  617. else
  618. {
  619. switch(eLauncherType)
  620. {
  621. case SKILL_SLT_Npc:
  622. {
  623. nTargetId = Param2PCoordinate(nLauncher,nParam1, nParam2, &nDesPX, &nDesPY,  SKILL_SLT_Npc);
  624. SubWorld[Npc[nLauncher].m_SubWorldIndex].Map2Mps(Npc[nLauncher].m_RegionIndex, Npc[nLauncher].m_MapX, Npc[nLauncher].m_MapY, Npc[nLauncher].m_OffX, Npc[nLauncher].m_OffY, &nSrcPX, &nSrcPY);
  625. nDirIndex = g_GetDirIndex(nSrcPX, nSrcPY, nDesPX, nDesPY);
  626. nDir = g_DirIndex2Dir(nDirIndex, MaxMissleDir);
  627. SkillParam.nLauncher = nLauncher;
  628. SkillParam.eLauncherType = eLauncherType;
  629. SkillParam.nTargetId = nTargetId;
  630. if (m_nChildSkillNum == 1 && (g_MisslesLib[m_nChildSkillId].m_eMoveKind == MISSLE_MMK_Line || g_MisslesLib[m_nChildSkillId].m_eMoveKind == MISSLE_MMK_Parabola) ) 
  631. {
  632. if (nSrcPX == nDesPX && nSrcPY == nDesPY) return FALSE ;
  633. nDistance = g_GetDistance(nSrcPX, nSrcPY, nDesPX, nDesPY);
  634. if (nDistance == 0 ) return FALSE;
  635. int nYLength = nDesPY - nSrcPY;
  636. int nXLength = nDesPX - nSrcPX;
  637. int nSin = (nYLength << 10) / nDistance; // 放大1024倍
  638. int nCos = (nXLength << 10) / nDistance;
  639. if (abs(nSin) > 1024) 
  640. return FALSE;
  641. if (abs(nCos) > 1024) 
  642. return FALSE;
  643. CastExtractiveLineMissle(&SkillParam, nDir, nSrcPX, nSrcPY, nCos, nSin, nDesPX, nDesPY);
  644. }
  645. else
  646. CastLine(&SkillParam, nDir, nSrcPX,nSrcPY);
  647. }break;
  648. case SKILL_SLT_Obj:
  649. {
  650. }break;
  651. case SKILL_SLT_Missle:
  652. {
  653. KMissle * pMissle = &Missle[nLauncher];
  654. if (!Npc[pMissle->m_nLauncher].IsMatch(pMissle->m_dwLauncherId)) return FALSE;
  655. SubWorld[pMissle->m_nSubWorldId].Map2Mps(pMissle->m_nRegionId, pMissle->m_nCurrentMapX, pMissle->m_nCurrentMapY , pMissle->m_nXOffset, pMissle->m_nYOffset, &nRefPX, &nRefPY);
  656. SkillParam.nLauncher = pMissle->m_nLauncher;
  657. SkillParam.nParent = nLauncher;
  658. SkillParam.eParentType = eLauncherType;
  659. SkillParam.nTargetId = pMissle->m_nFollowNpcIdx;
  660. CastLine(&SkillParam,  pMissle->m_nDir,  nRefPX, nRefPY);
  661. }break;
  662. }
  663. }
  664. }
  665. break;
  666. //  数字参数一表示子弹之间的角度差,以64方向为准
  667. //  传来的X/Y参数为格子坐标
  668. case SKILL_MF_Spread: //散形 多个子弹呈一定的角度的发散状
  669. {
  670. if (nParam1 == SKILL_SPT_Direction)
  671. {
  672. switch(eLauncherType)
  673. {
  674. case SKILL_SLT_Npc:
  675. {
  676. SubWorld[Npc[nLauncher].m_SubWorldIndex].Map2Mps(Npc[nLauncher].m_RegionIndex, Npc[nLauncher].m_MapX, Npc[nLauncher].m_MapY, Npc[nLauncher].m_OffX, Npc[nLauncher].m_OffY, &nSrcPX, &nSrcPY);
  677. if (nParam2 > MaxMissleDir || nParam2 < 0) return FALSE;
  678. nDir = nParam2;
  679. SkillParam.nLauncher = nLauncher;
  680. SkillParam.eLauncherType = eLauncherType;
  681. CastSpread(&SkillParam, nDir, nSrcPX,nSrcPY);
  682. }break;
  683. case SKILL_SLT_Obj:
  684. {
  685. }break;
  686. case SKILL_SLT_Missle:
  687. {
  688. KMissle * pMissle = &Missle[nLauncher];
  689. if (nParam2 > MaxMissleDir || nParam2 < 0) return FALSE;
  690. if (!Npc[pMissle->m_nLauncher].IsMatch(pMissle->m_dwLauncherId)) return FALSE;
  691. nDir = nParam2;
  692. SubWorld[pMissle->m_nSubWorldId].Map2Mps(pMissle->m_nRegionId, pMissle->m_nCurrentMapX, pMissle->m_nCurrentMapY , pMissle->m_nXOffset, pMissle->m_nYOffset, &nRefPX, &nRefPY);
  693. SkillParam.nLauncher = pMissle->m_nLauncher;
  694. SkillParam.nParent = nLauncher;
  695. SkillParam.eParentType = eLauncherType;
  696. SkillParam.nTargetId = pMissle->m_nFollowNpcIdx;
  697. CastSpread(&SkillParam, nDir,  nRefPX, nRefPY);
  698. }break;
  699. }
  700. }
  701. else
  702. {
  703. switch(eLauncherType)
  704. {
  705. case SKILL_SLT_Npc:
  706. {
  707. nTargetId = Param2PCoordinate(nLauncher,nParam1, nParam2, &nDesPX, &nDesPY, SKILL_SLT_Npc);
  708. SubWorld[Npc[nLauncher].m_SubWorldIndex].Map2Mps(Npc[nLauncher].m_RegionIndex, Npc[nLauncher].m_MapX, Npc[nLauncher].m_MapY, Npc[nLauncher].m_OffX, Npc[nLauncher].m_OffY, &nSrcPX, &nSrcPY);
  709. nDirIndex = g_GetDirIndex(nSrcPX, nSrcPY, nDesPX, nDesPY);
  710. nDir = g_DirIndex2Dir(nDirIndex, MaxMissleDir);
  711. SkillParam.nLauncher = nLauncher;
  712. SkillParam.eLauncherType = eLauncherType;
  713. SkillParam.nTargetId = nTargetId;
  714. if (m_nChildSkillNum == 1 && (g_MisslesLib[m_nChildSkillId].m_eMoveKind == MISSLE_MMK_Line) ) 
  715. {
  716. if (nSrcPX == nDesPX && nSrcPY == nDesPY) return FALSE ;
  717. nDistance = g_GetDistance(nSrcPX, nSrcPY, nDesPX, nDesPY);
  718. if (nDistance == 0 ) return FALSE;
  719. int nYLength = nDesPY - nSrcPY;
  720. int nXLength = nDesPX - nSrcPX;
  721. int nSin = (nYLength << 10) / nDistance; // 放大1024倍
  722. int nCos = (nXLength << 10) / nDistance;
  723. if (abs(nSin) > 1024) 
  724. return FALSE;
  725. if (abs(nCos) > 1024) 
  726. return FALSE;
  727. CastExtractiveLineMissle(&SkillParam, nDir, nSrcPX, nSrcPY, nCos, nSin, nDesPX, nDesPY);
  728. }
  729. else
  730. CastSpread(&SkillParam, nDir, nSrcPX, nSrcPY);
  731. }break;
  732. case SKILL_SLT_Obj:
  733. {
  734. }break;
  735. case SKILL_SLT_Missle:
  736. {
  737. KMissle * pMissle = &Missle[nLauncher];
  738. if (!Npc[pMissle->m_nLauncher].IsMatch(pMissle->m_dwLauncherId)) return FALSE;
  739. SubWorld[pMissle->m_nSubWorldId].Map2Mps(pMissle->m_nRegionId, pMissle->m_nCurrentMapX, pMissle->m_nCurrentMapY , pMissle->m_nXOffset, pMissle->m_nYOffset, &nRefPX, &nRefPY);
  740. SkillParam.nLauncher = pMissle->m_nLauncher;
  741. SkillParam.nParent = nLauncher;
  742. SkillParam.eParentType = eLauncherType;
  743. SkillParam.nTargetId = pMissle->m_nFollowNpcIdx;
  744. CastSpread(&SkillParam ,pMissle->m_nDir,  nRefPX, nRefPY);
  745. }break;
  746. }
  747. }
  748. }break;
  749. //以当前点为圆点产生多个围扰的子弹
  750. //分成两种情况,一种为以原地为原心发出,另一种为以目标点为原心发出
  751. // 数字参数一表示 是否为原地发出
  752. case SKILL_MF_Circle: //圆形 多个子弹围成一个圈
  753. {
  754. if (nParam1 == SKILL_SPT_Direction) return FALSE;
  755. switch(eLauncherType)
  756. {
  757. case SKILL_SLT_Npc:
  758. {
  759. nTargetId = Param2PCoordinate(nLauncher,nParam1, nParam2,  &nDesPX, &nDesPY, eLauncherType);
  760. SubWorld[Npc[nLauncher].m_SubWorldIndex].Map2Mps(Npc[nLauncher].m_RegionIndex, Npc[nLauncher].m_MapX, Npc[nLauncher].m_MapY, Npc[nLauncher].m_OffX, Npc[nLauncher].m_OffY, &nSrcPX, &nSrcPY);
  761. nDirIndex = g_GetDirIndex(nSrcPX, nSrcPY, nDesPX, nDesPY);
  762. nDir = g_DirIndex2Dir(nDirIndex, MaxMissleDir);
  763. SkillParam.nLauncher = nLauncher;
  764. SkillParam.eLauncherType = eLauncherType;
  765. SkillParam.nTargetId = nTargetId;
  766. if (m_nValue1 == 0)
  767. CastCircle(&SkillParam, nDir, nSrcPX, nSrcPY);
  768. else
  769. CastCircle(&SkillParam, nDir, nDesPX, nDesPY);
  770. }break;
  771. case SKILL_SLT_Obj:
  772. {
  773. }break;
  774. case SKILL_SLT_Missle:
  775. {
  776. KMissle * pMissle = &Missle[nLauncher];
  777. if (!Npc[pMissle->m_nLauncher].IsMatch(pMissle->m_dwLauncherId)) return FALSE;
  778. SubWorld[pMissle->m_nSubWorldId].Map2Mps(pMissle->m_nRegionId, pMissle->m_nCurrentMapX, pMissle->m_nCurrentMapY , pMissle->m_nXOffset, pMissle->m_nYOffset, &nRefPX, &nRefPY);
  779. SkillParam.nLauncher = pMissle->m_nLauncher;
  780. SkillParam.nParent = nLauncher;
  781. SkillParam.eParentType = eLauncherType;
  782. SkillParam.nTargetId = pMissle->m_nFollowNpcIdx;
  783. CastCircle(&SkillParam, pMissle->m_nDir,  nRefPX, nRefPY);
  784. }break;
  785. }
  786. }break;
  787. case SKILL_MF_Random: //随机 多个子弹随机排放
  788. {
  789. switch(eLauncherType)
  790. {
  791. case SKILL_SLT_Npc:
  792. {
  793. }break;
  794. case SKILL_SLT_Obj:
  795. {
  796. }break;
  797. case SKILL_SLT_Missle:
  798. {
  799. }break;
  800. }
  801. }
  802. break;
  803. case SKILL_MF_AtTarget: //定点 多个子弹根据
  804. {
  805. if (nParam1 == SKILL_SPT_Direction) return FALSE;
  806. switch(eLauncherType)
  807. {
  808. case SKILL_SLT_Npc:
  809. {
  810. nTargetId = Param2PCoordinate(nLauncher,nParam1, nParam2, &nDesPX, &nDesPY);
  811. nDirIndex = g_GetDirIndex(nSrcPX, nSrcPY, nDesPX, nDesPY);
  812. nDir = g_DirIndex2Dir(nDirIndex, MaxMissleDir);
  813. SkillParam.nLauncher = nLauncher;
  814. SkillParam.eLauncherType = eLauncherType;
  815. SkillParam.nTargetId = nTargetId;
  816. CastZone(&SkillParam, nDir, nDesPX, nDesPY);
  817. }break;
  818. case SKILL_SLT_Obj:
  819. {
  820. }break;
  821. case SKILL_SLT_Missle:
  822. {
  823. KMissle * pMissle = &Missle[nLauncher];
  824. if (!Npc[pMissle->m_nLauncher].IsMatch(pMissle->m_dwLauncherId)) return FALSE;
  825. SubWorld[pMissle->m_nSubWorldId].Map2Mps(pMissle->m_nRegionId, pMissle->m_nCurrentMapX, pMissle->m_nCurrentMapY , pMissle->m_nXOffset, pMissle->m_nYOffset, &nRefPX, &nRefPY);
  826. SkillParam.nLauncher = pMissle->m_nLauncher;
  827. SkillParam.nParent = nLauncher;
  828. SkillParam.eParentType = eLauncherType;
  829. SkillParam.nTargetId = pMissle->m_nFollowNpcIdx;
  830. CastZone(&SkillParam, pMissle->m_nDir, nRefPX, nRefPY);
  831. }break;
  832. }
  833. }break;
  834. case SKILL_MF_AtFirer: //本身 多个子弹停在玩家当前位置
  835. {
  836. if (nParam1 == SKILL_SPT_Direction) return FALSE;
  837. switch(eLauncherType)
  838. {
  839. case SKILL_SLT_Npc:
  840. {
  841. SubWorld[Npc[nLauncher].m_SubWorldIndex].Map2Mps(Npc[nLauncher].m_RegionIndex, Npc[nLauncher].m_MapX, Npc[nLauncher].m_MapY, Npc[nLauncher].m_OffX, Npc[nLauncher].m_OffY, &nSrcPX, &nSrcPY);
  842. nDirIndex = g_GetDirIndex(nSrcPX, nSrcPY, nDesPX, nDesPY);
  843. nDir = g_DirIndex2Dir(nDirIndex, MaxMissleDir);
  844. SkillParam.nLauncher = nLauncher;
  845. SkillParam.eLauncherType = eLauncherType;
  846. SkillParam.nTargetId = nTargetId;
  847. CastZone(&SkillParam,  nDir, nSrcPX, nSrcPY);
  848. }break;
  849. case SKILL_SLT_Obj:
  850. {
  851. }break;
  852. case SKILL_SLT_Missle:
  853. {
  854. KMissle * pMissle = &Missle[nLauncher];
  855. if (!Npc[pMissle->m_nLauncher].IsMatch(pMissle->m_dwLauncherId)) return FALSE;
  856. SubWorld[pMissle->m_nSubWorldId].Map2Mps(pMissle->m_nRegionId, pMissle->m_nCurrentMapX, pMissle->m_nCurrentMapY , pMissle->m_nXOffset, pMissle->m_nYOffset, &nRefPX, &nRefPY);
  857. SkillParam.nLauncher = pMissle->m_nLauncher;
  858. SkillParam.nParent = nLauncher;
  859. SkillParam.eParentType = eLauncherType;
  860. SkillParam.nTargetId = pMissle->m_nFollowNpcIdx;
  861. CastZone(&SkillParam , pMissle->m_nDir, nRefPX, nRefPY);
  862. }break;
  863. }
  864. }break;
  865. case SKILL_MF_Zone:
  866. {
  867. if (nParam1 == SKILL_SPT_Direction) return FALSE;
  868. switch(eLauncherType)
  869. {
  870. case SKILL_SLT_Npc:
  871. {
  872. nTargetId = Param2PCoordinate(nLauncher,nParam1, nParam2,  &nDesPX, &nDesPY);
  873. SubWorld[Npc[nLauncher].m_SubWorldIndex].Map2Mps(Npc[nLauncher].m_RegionIndex, Npc[nLauncher].m_MapX, Npc[nLauncher].m_MapY, Npc[nLauncher].m_OffX, Npc[nLauncher].m_OffY, &nSrcPX, &nSrcPY);
  874. nDirIndex = g_GetDirIndex(nSrcPX, nSrcPY, nDesPX, nDesPY);
  875. nDir = g_DirIndex2Dir(nDirIndex, MaxMissleDir);
  876. SkillParam.nLauncher = nLauncher;
  877. SkillParam.eLauncherType = eLauncherType;
  878. SkillParam.nTargetId = nTargetId;
  879. CastZone(&SkillParam, nDir, nSrcPX, nSrcPY);
  880. }break;
  881. case SKILL_SLT_Obj:
  882. {
  883. }break;
  884. case SKILL_SLT_Missle:
  885. {
  886. KMissle * pMissle = &Missle[nLauncher];
  887. if (!Npc[pMissle->m_nLauncher].IsMatch(pMissle->m_dwLauncherId)) return FALSE;
  888. SubWorld[pMissle->m_nSubWorldId].Map2Mps(pMissle->m_nRegionId, pMissle->m_nCurrentMapX, pMissle->m_nCurrentMapY , pMissle->m_nXOffset, pMissle->m_nYOffset, &nRefPX, &nRefPY);
  889. SkillParam.nLauncher = pMissle->m_nLauncher;
  890. SkillParam.nParent = nLauncher;
  891. SkillParam.eParentType = eLauncherType;
  892. SkillParam.nTargetId = pMissle->m_nFollowNpcIdx;
  893. CastZone(&SkillParam, pMissle->m_nDir, nRefPX, nRefPY);
  894. }break;
  895. }
  896. }break;
  897. }
  898. return TRUE;
  899. }
  900. /*!*****************************************************************************
  901. // Function : KSkill::CastZone
  902. // Purpose : 
  903. // Return : int 
  904. // Argumant : int nLauncher
  905. // Argumant : eSkillLauncherType eLauncherType
  906. // Argumant : int nDir
  907. // Argumant : int nRefPX
  908. // Argumant : int nRefPY
  909. // Argumant : int nWaitTime
  910. // Argumant : int nTargetId
  911. // Comments :
  912. // Author : RomanDou
  913. *****************************************************************************/
  914. //nValue1 = 0 表示矩形区域  nValue1 = 1 表示圆形区域
  915. //nValue2 = 0 
  916. int KSkill::CastZone(TOrdinSkillParam * pSkillParam , int nDir, int nRefPX, int nRefPY)  const 
  917. {
  918. int nLauncher = pSkillParam->nLauncher;
  919. eSkillLauncherType eLauncherType = pSkillParam->eLauncherType;
  920. if (eLauncherType != SKILL_SLT_Npc) return 0;
  921. int nCastMissleNum = 0;
  922. int nBeginPX ;
  923. int nBeginPY ;
  924. if (m_nChildSkillNum == 1)
  925. {
  926. nBeginPX = nRefPX;
  927. nBeginPY = nRefPY;
  928. }
  929. else 
  930. {
  931. nBeginPX = nRefPX - m_nChildSkillNum * SubWorld[Npc[nLauncher].m_SubWorldIndex].m_nCellWidth / 2;
  932. nBeginPY = nRefPY - m_nChildSkillNum * SubWorld[Npc[nLauncher].m_SubWorldIndex].m_nCellHeight / 2;
  933. }
  934. #ifdef _SERVER
  935. KMissleMagicAttribsData * pNewMagicAttribsData = CreateMissleMagicAttribsData(nLauncher);
  936. #endif //_SERVER
  937. for (int i = 0; i < m_nChildSkillNum; i ++)
  938. for (int j = 0; j < m_nChildSkillNum; j ++)
  939. {
  940. if (m_bBaseSkill)
  941. {
  942. int nMissleIndex ;
  943. int nSubWorldId ; 
  944. nSubWorldId = Npc[nLauncher].m_SubWorldIndex;
  945. if (m_nValue1 == 1)
  946. if ( ((i - m_nChildSkillNum / 2) * (i - m_nChildSkillNum / 2) + (j - m_nChildSkillNum / 2) * (j - m_nChildSkillNum / 2)) > (m_nChildSkillNum * m_nChildSkillNum / 4)) continue;
  947. if (nSubWorldId < 0) goto exit;
  948. int nDesSubX = nBeginPX + j * SubWorld[nSubWorldId].m_nCellWidth;
  949. int nDesSubY = nBeginPY +  i * SubWorld[nSubWorldId].m_nCellHeight;
  950. nMissleIndex = MissleSet.Add(nSubWorldId, nDesSubX , nDesSubY);
  951. if (nMissleIndex < 0) continue;
  952. Missle[nMissleIndex].m_nDir = nDir;
  953. Missle[nMissleIndex].m_nDirIndex = g_Dir2DirIndex(nDir, MaxMissleDir);
  954. CreateMissle(nLauncher, m_nChildSkillId, nMissleIndex);
  955. Missle[nMissleIndex].m_nFollowNpcIdx = pSkillParam->nTargetId;
  956. Missle[nMissleIndex].m_dwBornTime = SubWorld[nSubWorldId].m_dwCurrentTime;
  957. Missle[nMissleIndex].m_nSubWorldId = nSubWorldId;
  958. Missle[nMissleIndex].m_nLauncher = nLauncher;
  959. Missle[nMissleIndex].m_dwLauncherId = Npc[nLauncher].m_dwID;
  960. if (pSkillParam->nParent)
  961. Missle[nMissleIndex].m_nParentMissleIndex = pSkillParam->nParent;
  962. else 
  963. Missle[nMissleIndex].m_nParentMissleIndex = 0;
  964. Missle[nMissleIndex].m_nSkillId = m_nId;
  965. Missle[nMissleIndex].m_nStartLifeTime = pSkillParam->nWaitTime + GetMissleGenerateTime(i * m_nChildSkillNum + j);
  966. Missle[nMissleIndex].m_nLifeTime += Missle[nMissleIndex].m_nStartLifeTime;
  967. Missle[nMissleIndex].m_nRefPX = nDesSubX;
  968. Missle[nMissleIndex].m_nRefPY = nDesSubY;
  969. if (Missle[nMissleIndex].m_eMoveKind == MISSLE_MMK_Line|| Missle[nMissleIndex].m_eMoveKind == MISSLE_MMK_RollBack)
  970. {
  971. Missle[nMissleIndex].m_nXFactor = g_DirCos(nDir, MaxMissleDir);
  972. Missle[nMissleIndex].m_nYFactor = g_DirSin(nDir, MaxMissleDir);
  973. }
  974. #ifdef _SERVER
  975. Missle[nMissleIndex].SetMagicAttribsData(pNewMagicAttribsData);
  976. #endif //_SERVER
  977. nCastMissleNum ++;
  978. }
  979. else
  980. {
  981. _ASSERT(m_nChildSkillId > 0 && m_nChildSkillLevel > 0) ;
  982. KSkill * pOrdinSkill = (KSkill *) g_SkillManager.GetSkill(m_nChildSkillId, m_nChildSkillLevel);
  983. if (pOrdinSkill) 
  984. {
  985. if (!pSkillParam->nParent)
  986. nCastMissleNum += pOrdinSkill->Cast(nLauncher, nBeginPX + j * SubWorld[Npc[nLauncher].m_SubWorldIndex].m_nCellWidth , nBeginPY +  i * SubWorld[Npc[nLauncher].m_SubWorldIndex].m_nCellHeight, pSkillParam->nWaitTime + GetMissleGenerateTime(i * m_nChildSkillNum + j ), eLauncherType);
  987. else 
  988. nCastMissleNum += pOrdinSkill->Cast(pSkillParam->nLauncher, nBeginPX + j * SubWorld[Npc[nLauncher].m_SubWorldIndex].m_nCellWidth , nBeginPY +  i * SubWorld[Npc[nLauncher].m_SubWorldIndex].m_nCellHeight, pSkillParam->nWaitTime + GetMissleGenerateTime(i * m_nChildSkillNum + j ), pSkillParam->eLauncherType);
  989. }
  990. }
  991. }
  992. exit:
  993. #ifdef _SERVER
  994. if (pNewMagicAttribsData)
  995. if (pNewMagicAttribsData->GetRef() == 0)
  996. delete pNewMagicAttribsData;
  997. #endif
  998. return nCastMissleNum;
  999. }
  1000. /*!*****************************************************************************
  1001. // Function : KSkill::CastLine
  1002. // Purpose : 
  1003. // Return : 
  1004. // Argumant : int nLauncher
  1005. // Argumant : eSkillLauncherType eLauncherType
  1006. // Argumant : int nDir
  1007. // Argumant : int nRefPX
  1008. // Argumant : int nRefPY
  1009. // Argumant : int nWaitTime
  1010. // Argumant : int nTargetId
  1011. // Comments :
  1012. // Author : RomanDou
  1013. *****************************************************************************/
  1014. // Value1 子弹之间的间距
  1015. // Value2 
  1016. int KSkill::CastLine(TOrdinSkillParam *pSkillParam, int nDir, int nRefPX, int nRefPY)  const 
  1017. {
  1018. int nLauncher = pSkillParam->nLauncher;
  1019. eSkillLauncherType eLauncherType = pSkillParam->eLauncherType;
  1020. if (eLauncherType != SKILL_SLT_Npc) return 0;
  1021. int nDirIndex = g_Dir2DirIndex(nDir, MaxMissleDir);
  1022. int nDesSubX = 0;
  1023. int nDesSubY = 0;
  1024. int nCastMissleNum = 0;
  1025. //子弹之间的间距
  1026. int nMSDistanceEach = m_nValue1;
  1027. #ifdef _SERVER
  1028. KMissleMagicAttribsData * pNewMagicAttribsData = CreateMissleMagicAttribsData(nLauncher);
  1029. #endif //_SERVER
  1030. //分别生成多少子弹
  1031. for(int i = 0; i < m_nChildSkillNum; i++)
  1032. {
  1033. nDesSubX = nRefPX + ((nMSDistanceEach * (i + 1) * g_DirCos(nDirIndex, MaxMissleDir) )>>10);
  1034. nDesSubY = nRefPY + ((nMSDistanceEach * (i + 1) * g_DirSin(nDirIndex, MaxMissleDir) )>>10);
  1035. if (nDesSubX < 0 || nDesSubY < 0)  continue;
  1036. if (m_bBaseSkill)
  1037. {
  1038. int nMissleIndex ;
  1039. int nSubWorldId ; 
  1040. nSubWorldId = Npc[nLauncher].m_SubWorldIndex;
  1041. if (nSubWorldId < 0) goto exit;
  1042. nMissleIndex = MissleSet.Add(nSubWorldId, nDesSubX, nDesSubY);
  1043. if (nMissleIndex < 0) continue;
  1044. Missle[nMissleIndex].m_nDir = nDir;
  1045. Missle[nMissleIndex].m_nDirIndex = nDirIndex;
  1046. CreateMissle(nLauncher, m_nChildSkillId, nMissleIndex);
  1047. Missle[nMissleIndex].m_nFollowNpcIdx = pSkillParam->nTargetId;
  1048. Missle[nMissleIndex].m_dwBornTime = SubWorld[nSubWorldId].m_dwCurrentTime;
  1049. Missle[nMissleIndex].m_nSubWorldId = nSubWorldId;
  1050. Missle[nMissleIndex].m_nLauncher = nLauncher;
  1051. Missle[nMissleIndex].m_dwLauncherId = Npc[nLauncher].m_dwID;
  1052. if (pSkillParam->nParent)
  1053. Missle[nMissleIndex].m_nParentMissleIndex = pSkillParam->nParent;
  1054. else 
  1055. Missle[nMissleIndex].m_nParentMissleIndex = 0;
  1056. Missle[nMissleIndex].m_nSkillId = m_nId;
  1057. Missle[nMissleIndex].m_nStartLifeTime = pSkillParam->nWaitTime + GetMissleGenerateTime(i);
  1058. Missle[nMissleIndex].m_nLifeTime += Missle[nMissleIndex].m_nStartLifeTime;
  1059. Missle[nMissleIndex].m_nRefPX = nDesSubX;
  1060. Missle[nMissleIndex].m_nRefPY = nDesSubY;
  1061. if (Missle[nMissleIndex].m_eMoveKind == MISSLE_MMK_Line || Missle[nMissleIndex].m_eMoveKind == MISSLE_MMK_RollBack)
  1062. {
  1063. Missle[nMissleIndex].m_nXFactor = g_DirCos(nDir, MaxMissleDir);
  1064. Missle[nMissleIndex].m_nYFactor = g_DirSin(nDir, MaxMissleDir);
  1065. }
  1066. #ifdef _SERVER
  1067. Missle[nMissleIndex].SetMagicAttribsData(pNewMagicAttribsData);
  1068. #endif //_SERVER
  1069. nCastMissleNum ++;
  1070. }
  1071. else
  1072. {
  1073. _ASSERT(m_nChildSkillId > 0 && m_nChildSkillLevel > 0) ;
  1074. KSkill * pOrdinSkill = (KSkill *) g_SkillManager.GetSkill(m_nChildSkillId, m_nChildSkillLevel);
  1075. if (pOrdinSkill) 
  1076. {
  1077. if (!pSkillParam->nParent)
  1078. nCastMissleNum += pOrdinSkill->Cast(nLauncher, nDesSubX, nDesSubY, pSkillParam->nWaitTime + GetMissleGenerateTime(i), eLauncherType);
  1079. else
  1080. nCastMissleNum += pOrdinSkill->Cast(pSkillParam->nParent, nDesSubX, nDesSubY, pSkillParam->nWaitTime + GetMissleGenerateTime(i), pSkillParam->eParentType);
  1081. }
  1082. }
  1083. }
  1084. exit:
  1085. #ifdef _SERVER
  1086. if (pNewMagicAttribsData)
  1087. if (pNewMagicAttribsData->GetRef() == 0)
  1088. delete pNewMagicAttribsData;
  1089. #endif
  1090. return nCastMissleNum;
  1091. }
  1092. int KSkill::CastExtractiveLineMissle(TOrdinSkillParam* pSkillParam,  int nDir,int nSrcX, int nSrcY, int nXOffset, int nYOffset, int nDesX, int nDesY)  const 
  1093. {
  1094. _ASSERT(pSkillParam);
  1095. int nLauncher = pSkillParam->nLauncher;
  1096. if (pSkillParam->eLauncherType != SKILL_SLT_Npc) return 0;
  1097. int nDirIndex = g_Dir2DirIndex(nDir, MaxMissleDir);
  1098. int nDesSubX = 0;
  1099. int nDesSubY = 0;
  1100. int nCastMissleNum = 0;
  1101. //子弹之间的间距
  1102. #ifdef _SERVER
  1103. KMissleMagicAttribsData * pNewMagicAttribsData = CreateMissleMagicAttribsData(nLauncher);
  1104. #endif //_SERVER
  1105. //分别生成多少子弹
  1106. {
  1107. if (m_bBaseSkill)
  1108. {
  1109. int nMissleIndex ;
  1110. int nSubWorldId ; 
  1111. nSubWorldId = Npc[nLauncher].m_SubWorldIndex;
  1112. if (nSubWorldId < 0) goto exit;
  1113. nMissleIndex = MissleSet.Add(nSubWorldId, nSrcX, nSrcY);
  1114. if (nMissleIndex < 0) goto exit;
  1115. Missle[nMissleIndex].m_nDir = nDir;
  1116. Missle[nMissleIndex].m_nDirIndex = nDirIndex;
  1117. CreateMissle(nLauncher, m_nChildSkillId, nMissleIndex);
  1118. if (Missle[nMissleIndex].m_eMoveKind == MISSLE_MMK_Parabola)
  1119. {
  1120. int nLength = g_GetDistance(nSrcX, nSrcY, nDesX, nDesY);
  1121. int nTime = nLength / Missle[nMissleIndex].m_nSpeed;
  1122. Missle[nMissleIndex].m_nHeightSpeed = Missle[nMissleIndex].m_nZAcceleration * (nTime - 1) / 2;
  1123. }
  1124. Missle[nMissleIndex].m_nFollowNpcIdx = pSkillParam->nTargetId;
  1125. Missle[nMissleIndex].m_dwBornTime = SubWorld[nSubWorldId].m_dwCurrentTime;
  1126. Missle[nMissleIndex].m_nSubWorldId = nSubWorldId;
  1127. Missle[nMissleIndex].m_nLauncher = nLauncher;
  1128. Missle[nMissleIndex].m_dwLauncherId = Npc[nLauncher].m_dwID;
  1129. if (pSkillParam->nParent)
  1130. Missle[nMissleIndex].m_nParentMissleIndex = pSkillParam->nParent;
  1131. else 
  1132. Missle[nMissleIndex].m_nParentMissleIndex = 0;
  1133. Missle[nMissleIndex].m_nSkillId = m_nId;
  1134. Missle[nMissleIndex].m_nStartLifeTime = pSkillParam->nWaitTime + GetMissleGenerateTime(0);
  1135. Missle[nMissleIndex].m_nLifeTime += Missle[nMissleIndex].m_nStartLifeTime;
  1136. Missle[nMissleIndex].m_nRefPX = nSrcX;
  1137. Missle[nMissleIndex].m_nRefPY = nSrcY;
  1138. int nTempR = 0;
  1139. int nTempMapX = 0;
  1140. int nTempMapY = 0;
  1141. int nTempOffsetX = 0;
  1142. int nTempOffsetY = 0;
  1143. Missle[nMissleIndex].m_bNeedReclaim = TRUE;
  1144. int nLength = g_GetDistance(nSrcX, nSrcY, nDesX, nDesY);
  1145. Missle[nMissleIndex].m_nFirstReclaimTime = nLength / Missle[nMissleIndex].m_nSpeed + Missle[nMissleIndex].m_nStartLifeTime;
  1146. Missle[nMissleIndex].m_nEndReclaimTime = Missle[nMissleIndex].m_nFirstReclaimTime + SubWorld[nSubWorldId].m_nCellWidth / Missle[nMissleIndex].m_nSpeed + 2;
  1147. if (Missle[nMissleIndex].m_eMoveKind == MISSLE_MMK_Line || Missle[nMissleIndex].m_eMoveKind == MISSLE_MMK_Parabola)
  1148. {
  1149. Missle[nMissleIndex].m_nXFactor = nXOffset;
  1150. Missle[nMissleIndex].m_nYFactor = nYOffset;
  1151. }
  1152. #ifdef _SERVER
  1153. Missle[nMissleIndex].SetMagicAttribsData(pNewMagicAttribsData);
  1154. #endif //_SERVER
  1155. nCastMissleNum ++;
  1156. }
  1157. else
  1158. {
  1159. KSkill * pOrdinSkill = (KSkill *) g_SkillManager.GetSkill(m_nChildSkillId, m_nChildSkillLevel);
  1160. if (pOrdinSkill) 
  1161. {
  1162. if (!pSkillParam->nParent)
  1163. nCastMissleNum += pOrdinSkill->Cast(nLauncher, nDesSubX, nDesSubY, pSkillParam->nWaitTime + GetMissleGenerateTime(0), pSkillParam->eLauncherType);
  1164. else
  1165. nCastMissleNum += pOrdinSkill->Cast(pSkillParam->nParent, nDesSubX, nDesSubY, pSkillParam->nWaitTime + GetMissleGenerateTime(0), pSkillParam->eParentType);
  1166. }
  1167. }
  1168. }
  1169. exit:
  1170. #ifdef _SERVER
  1171. if (pNewMagicAttribsData)
  1172. if (pNewMagicAttribsData->GetRef() == 0)
  1173. delete pNewMagicAttribsData;
  1174. #endif
  1175. return nCastMissleNum;
  1176. }
  1177. /*!*****************************************************************************
  1178. // Function : KSkill::CastWall
  1179. // Purpose : Wall Magic 
  1180. // Return : int 
  1181. // Argumant : int nLauncher
  1182. // Argumant : eSkillLauncherType eLauncherType
  1183. // Argumant : int nDir
  1184. // Argumant : int nRefPX
  1185. // Argumant : int nRefPY
  1186. // Argumant : int nWaitTime
  1187. // Argumant : int nTargetId
  1188. // Comments :
  1189. // Author : RomanDou
  1190. *****************************************************************************/
  1191. /*
  1192. m_nValue1 表示子弹之间的距离,单位像素点
  1193. */
  1194. int KSkill::CastWall(TOrdinSkillParam * pSkillParam,  int nDir , int nRefPX , int nRefPY)  const 
  1195. {
  1196. int nLauncher = pSkillParam->nLauncher;
  1197. eSkillLauncherType eLauncherType = pSkillParam->eLauncherType;
  1198. if (eLauncherType != SKILL_SLT_Npc) return 0;
  1199. int nDirIndex = g_Dir2DirIndex(nDir, MaxMissleDir);
  1200. int nDesSubX = 0;
  1201. int nDesSubY = 0;
  1202. int nCastMissleNum = 0;
  1203. //子弹之间的间距
  1204. int nMSDistanceEach = m_nValue1;
  1205. int nCurMSDistance = -1 * nMSDistanceEach * m_nChildSkillNum / 2;
  1206. #ifdef _SERVER
  1207. KMissleMagicAttribsData * pNewMagicAttribsData = CreateMissleMagicAttribsData(nLauncher);
  1208. #endif //_SERVER
  1209. //分别生成多少子弹
  1210. for(int i = 0; i < m_nChildSkillNum; i++)
  1211. {
  1212. nDesSubX = nRefPX + ((nCurMSDistance * g_DirCos(nDirIndex, MaxMissleDir)) >>10);
  1213. nDesSubY = nRefPY + ((nCurMSDistance * g_DirSin(nDirIndex, MaxMissleDir)) >>10);
  1214. if (nDesSubX < 0 || nDesSubY < 0)  continue;
  1215. if (m_bBaseSkill)
  1216. {
  1217. int nMissleIndex ;
  1218. int nSubWorldId ; 
  1219. nSubWorldId = Npc[nLauncher].m_SubWorldIndex;
  1220. if (nSubWorldId < 0)
  1221. {
  1222. goto exit;
  1223. }
  1224. nMissleIndex = MissleSet.Add(nSubWorldId, nDesSubX, nDesSubY);
  1225. if (nMissleIndex < 0)
  1226. {
  1227. continue;
  1228. }
  1229. if (m_nValue2)
  1230. {
  1231. int nDirTemp = nDir - MaxMissleDir / 4;
  1232. if (nDirTemp < 0) nDirTemp += MaxMissleDir;
  1233. Missle[nMissleIndex].m_nDir = nDirTemp;
  1234. Missle[nMissleIndex].m_nDirIndex = g_Dir2DirIndex(nDirTemp, 64);
  1235. }
  1236. else
  1237. {
  1238. Missle[nMissleIndex].m_nDir = nDir;
  1239. Missle[nMissleIndex].m_nDirIndex = nDirIndex;
  1240. }
  1241. Missle[nMissleIndex].m_nSubWorldId = nSubWorldId;
  1242. CreateMissle(nLauncher, m_nChildSkillId, nMissleIndex);
  1243. Missle[nMissleIndex].m_nFollowNpcIdx = pSkillParam->nTargetId;
  1244. if (pSkillParam->nTargetId)
  1245. Missle[nMissleIndex].m_dwFollowNpcID = Npc[pSkillParam->nTargetId].m_dwID;
  1246. Missle[nMissleIndex].m_dwBornTime = SubWorld[nSubWorldId].m_dwCurrentTime;
  1247. Missle[nMissleIndex].m_nLauncher = nLauncher;
  1248. Missle[nMissleIndex].m_dwLauncherId = Npc[nLauncher].m_dwID;
  1249. if (pSkillParam->nParent)
  1250. Missle[nMissleIndex].m_nParentMissleIndex = pSkillParam->nParent;
  1251. else 
  1252. Missle[nMissleIndex].m_nParentMissleIndex = 0;
  1253. Missle[nMissleIndex].m_nSkillId = m_nId;
  1254. Missle[nMissleIndex].m_nStartLifeTime = pSkillParam->nWaitTime + GetMissleGenerateTime(i);
  1255. Missle[nMissleIndex].m_nLifeTime += Missle[nMissleIndex].m_nStartLifeTime;
  1256. Missle[nMissleIndex].m_nRefPX = nDesSubX;
  1257. Missle[nMissleIndex].m_nRefPY = nDesSubY;
  1258. if (Missle[nMissleIndex].m_eMoveKind == MISSLE_MMK_Line|| Missle[nMissleIndex].m_eMoveKind == MISSLE_MMK_RollBack)
  1259. {
  1260. Missle[nMissleIndex].m_nXFactor = g_DirCos(Missle[nMissleIndex].m_nDir, MaxMissleDir);
  1261. Missle[nMissleIndex].m_nYFactor = g_DirSin(Missle[nMissleIndex].m_nDir, MaxMissleDir);
  1262. }
  1263. #ifdef _SERVER
  1264. Missle[nMissleIndex].SetMagicAttribsData(pNewMagicAttribsData);
  1265. #endif //_SERVER
  1266. nCastMissleNum ++;
  1267. }
  1268. else
  1269. {
  1270. _ASSERT(m_nChildSkillId > 0 && m_nChildSkillLevel > 0) ;
  1271. KSkill * pOrdinSkill = (KSkill *) g_SkillManager.GetSkill(m_nChildSkillId, m_nChildSkillLevel);
  1272. if (pOrdinSkill) 
  1273. {
  1274. if (!pSkillParam->nParent)
  1275. nCastMissleNum += pOrdinSkill->Cast(nLauncher, nDesSubX, nDesSubY, pSkillParam->nWaitTime + GetMissleGenerateTime(i), eLauncherType);
  1276. else
  1277. nCastMissleNum += pOrdinSkill->Cast(pSkillParam->nParent, nDesSubX, nDesSubY, pSkillParam->nWaitTime +  GetMissleGenerateTime(i), pSkillParam->eParentType);
  1278. }
  1279. }
  1280. nCurMSDistance += nMSDistanceEach;
  1281. }
  1282. exit:
  1283. #ifdef _SERVER
  1284. if (pNewMagicAttribsData)
  1285. if (pNewMagicAttribsData->GetRef() == 0)
  1286. delete pNewMagicAttribsData;
  1287. #endif
  1288. return nCastMissleNum;
  1289. }
  1290. /*!*****************************************************************************
  1291. // Function : KSkill::CastCircle
  1292. // Purpose : 
  1293. // Return : 
  1294. // Argumant : int nLauncher
  1295. // Argumant : eSkillLauncherType  eLauncherType
  1296. // Argumant : int nDir
  1297. // Argumant : int nRefPX
  1298. // Argumant : int nRefPY
  1299. // Argumant : int nWaitTime
  1300. // Argumant : int nTargetId
  1301. // Comments :
  1302. // Author : RomanDou
  1303. *****************************************************************************/
  1304. // Value1  == 0 表示发送者为圆心产生圆,否则以目标点为圆心产生圆
  1305. int KSkill::CastCircle(TOrdinSkillParam * pSkillParam, int nDir, int nRefPX, int nRefPY)  const 
  1306. {
  1307. int nLauncher = pSkillParam->nLauncher;
  1308. eSkillLauncherType  eLauncherType = pSkillParam->eLauncherType;
  1309. if (eLauncherType != SKILL_SLT_Npc) return 0;
  1310. int nDesSubPX = 0;
  1311. int nDesSubPY = 0;
  1312. int nFirstStep = m_nValue2; //第一步的长度,子弹在刚发出去时离玩家的距离
  1313. int nCurSubDir = 0;
  1314. int nDirPerNum  =  MaxMissleDir / m_nChildSkillNum  ;
  1315. int nCastMissleNum = 0;
  1316. #ifdef _SERVER
  1317. KMissleMagicAttribsData * pNewMagicAttribsData = CreateMissleMagicAttribsData(nLauncher);
  1318. #endif //_SERVER
  1319. //分别生成多个子弹
  1320. for(int i = 0; i < m_nChildSkillNum; i++)
  1321. {
  1322. int nCurSubDir = nDir + nDirPerNum * i ;
  1323. if (nCurSubDir < 0)
  1324. nCurSubDir = MaxMissleDir + nCurSubDir;
  1325. if (nCurSubDir >= MaxMissleDir)
  1326. nCurSubDir -= MaxMissleDir;
  1327. int nSinAB = g_DirSin(nCurSubDir, MaxMissleDir);
  1328. int nCosAB = g_DirCos(nCurSubDir, MaxMissleDir);
  1329. nDesSubPX = nRefPX + ((nCosAB * nFirstStep) >> 10);
  1330. nDesSubPY = nRefPY + ((nSinAB * nFirstStep) >> 10);
  1331. if (nDesSubPX < 0 || nDesSubPY < 0)  continue;
  1332. if (m_bBaseSkill)
  1333. {
  1334. int nMissleIndex ;
  1335. int nSubWorldId ; 
  1336. nSubWorldId = Npc[nLauncher].m_SubWorldIndex;
  1337. if (nSubWorldId < 0) goto exit;
  1338. nMissleIndex = MissleSet.Add(nSubWorldId, nDesSubPX, nDesSubPY);
  1339. if (nMissleIndex < 0)
  1340. {
  1341. continue;
  1342. }
  1343. Missle[nMissleIndex].m_nDir = nCurSubDir;
  1344. Missle[nMissleIndex].m_nDirIndex = g_Dir2DirIndex(nCurSubDir, MaxMissleDir);
  1345. CreateMissle(nLauncher, m_nChildSkillId, nMissleIndex);
  1346. Missle[nMissleIndex].m_nFollowNpcIdx = pSkillParam->nTargetId;
  1347. Missle[nMissleIndex].m_dwBornTime = SubWorld[nSubWorldId].m_dwCurrentTime;
  1348. Missle[nMissleIndex].m_nSubWorldId = nSubWorldId;
  1349. Missle[nMissleIndex].m_nLauncher = nLauncher;
  1350. Missle[nMissleIndex].m_dwLauncherId = Npc[nLauncher].m_dwID;
  1351. if (pSkillParam->nParent)
  1352. Missle[nMissleIndex].m_nParentMissleIndex = pSkillParam->nParent;
  1353. else 
  1354. Missle[nMissleIndex].m_nParentMissleIndex = 0;
  1355. Missle[nMissleIndex].m_nSkillId = m_nId;
  1356. Missle[nMissleIndex].m_nStartLifeTime = pSkillParam->nWaitTime + GetMissleGenerateTime(i);
  1357. Missle[nMissleIndex].m_nLifeTime += Missle[nMissleIndex].m_nStartLifeTime;
  1358. Missle[nMissleIndex].m_nRefPX = nDesSubPX;
  1359. Missle[nMissleIndex].m_nRefPY = nDesSubPY;
  1360. if (Missle[nMissleIndex].m_eMoveKind == MISSLE_MMK_Line || Missle[nMissleIndex].m_eMoveKind == MISSLE_MMK_RollBack)
  1361. {
  1362. Missle[nMissleIndex].m_nXFactor = g_DirCos(nCurSubDir, MaxMissleDir);
  1363. Missle[nMissleIndex].m_nYFactor = g_DirSin(nCurSubDir, MaxMissleDir);
  1364. }
  1365. #ifdef _SERVER
  1366. Missle[nMissleIndex].SetMagicAttribsData(pNewMagicAttribsData);
  1367. #endif //_SERVER
  1368. nCastMissleNum ++;
  1369. }
  1370. else
  1371. {
  1372. _ASSERT(m_nChildSkillId > 0 && m_nChildSkillLevel > 0) ;
  1373. KSkill * pOrdinSkill = (KSkill *) g_SkillManager.GetSkill(m_nChildSkillId, m_nChildSkillLevel);
  1374. if (pOrdinSkill) 
  1375. {
  1376. if (!pSkillParam->nParent)
  1377. nCastMissleNum += pOrdinSkill->Cast(nLauncher, nDesSubPX, nDesSubPY, pSkillParam->nWaitTime + GetMissleGenerateTime(i), eLauncherType);
  1378. else
  1379. nCastMissleNum += pOrdinSkill->Cast(pSkillParam->nParent, nDesSubPX, nDesSubPY, pSkillParam->nWaitTime + GetMissleGenerateTime(i), pSkillParam->eParentType);
  1380. }
  1381. }
  1382. }
  1383. exit:
  1384. #ifdef _SERVER
  1385. if (pNewMagicAttribsData)
  1386. if (pNewMagicAttribsData->GetRef() == 0)
  1387. delete pNewMagicAttribsData;
  1388. #endif
  1389. return nCastMissleNum;
  1390. }
  1391. /*!*****************************************************************************
  1392. // Function : KSkill::CastSpread
  1393. // Purpose : 
  1394. // Return : 
  1395. // Argumant : int nLauncher
  1396. // Argumant : eSkillLauncherType eLauncherType
  1397. // Argumant : int nDir
  1398. // Argumant : int nRefPX
  1399. // Argumant : int nRefPY
  1400. // Argumant : int nWaitTime
  1401. // Argumant : int nTargetId
  1402. // Comments :
  1403. // Author : RomanDou
  1404. *****************************************************************************/
  1405. /*
  1406. Value1 每个子弹相差的角度单位
  1407. Value2 每一步的长度,第一步的长度,子弹在刚发出去时离玩家的距离
  1408. */
  1409. int KSkill::CastSpread(TOrdinSkillParam * pSkillParam, int nDir, int nRefPX, int nRefPY)  const 
  1410. {
  1411. int nLauncher = pSkillParam->nLauncher;
  1412. eSkillLauncherType eLauncherType = pSkillParam->eLauncherType;
  1413. if (eLauncherType != SKILL_SLT_Npc) return 0;
  1414. int nDesSubMapX = 0;
  1415. int nDesSubMapY = 0;
  1416. int nFirstStep = m_nValue2; //第一步的长度,子弹在刚发出去时离玩家的距离
  1417. int nCurMSRadius = m_nChildSkillNum / 2 ; 
  1418. int nCurSubDir = 0;
  1419. int nCastMissleNum  = 0; //实际发送的Missle的数量
  1420. // Sin A+B = SinA*CosB + CosA*SinB
  1421. // Cos A+B = CosA*CosB - SinA*SinB
  1422. // Sin A = nYFactor
  1423. // Cos A = nXFactor
  1424. #ifdef _SERVER
  1425. KMissleMagicAttribsData * pNewMagicAttribsData = CreateMissleMagicAttribsData(nLauncher);
  1426. #endif
  1427. int nDesSubX = 0;
  1428. int nDesSubY = 0;
  1429. int nXFactor = 0;
  1430. int nYFactor = 0;
  1431. if (pSkillParam->nTargetId > 0)
  1432. {
  1433. int nTargetId = pSkillParam->nTargetId;
  1434. int nDistance = 0;
  1435. int nDesX, nDesY;
  1436. if (Npc[nTargetId].m_Index > 0 && Npc[nTargetId].m_SubWorldIndex >= 0) 
  1437. SubWorld[Npc[nTargetId].m_SubWorldIndex].Map2Mps(Npc[nTargetId].m_RegionIndex, Npc[nTargetId].m_MapX, Npc[nTargetId].m_MapY, Npc[nTargetId].m_OffX, Npc[nTargetId].m_OffY, &nDesX, &nDesY);
  1438. nDistance = (int)sqrt((nDesX - nRefPX)*(nDesX - nRefPX) + (nDesY - nRefPY)*(nDesY - nRefPY));
  1439. nXFactor = ((nDesX - nRefPX)<<10) / nDistance;
  1440. nYFactor = ((nDesY - nRefPY)<<10) / nDistance;
  1441. nDesSubX = nRefPX + ((nXFactor * nFirstStep)>>10);
  1442. nDesSubY = nRefPY + ((nYFactor * nFirstStep)>>10);
  1443. if (nDesSubX < 0  || nDesSubY < 0 ) return 0;
  1444. }
  1445. int nTargetId = pSkillParam->nTargetId;
  1446. //分别生成多个子弹
  1447. for(int i = 0; i < m_nChildSkillNum; i++)
  1448. {
  1449. int nDSubDir = m_nValue1 * nCurMSRadius; 
  1450. nCurSubDir = nDir - m_nValue1 * nCurMSRadius;
  1451. if (nCurSubDir < 0)
  1452. nCurSubDir = MaxMissleDir + nCurSubDir;
  1453. if (nCurSubDir >= MaxMissleDir)
  1454. nCurSubDir -= MaxMissleDir;
  1455. int nSinAB ;
  1456. int nCosAB ;
  1457. if (nTargetId > 0)
  1458. {
  1459. nDSubDir += 48;
  1460. if (nDSubDir >= MaxMissleDir)
  1461. nDSubDir -= MaxMissleDir;
  1462. //sin(a - b) = sinacosb - cosa*sinb
  1463. //cos(a - b) = cosacoab + sinasinb
  1464. nSinAB = (nYFactor * g_DirCos(nDSubDir, MaxMissleDir) - nXFactor * g_DirSin(nDSubDir, MaxMissleDir)) >> 10;
  1465. nCosAB = (nXFactor * g_DirCos(nDSubDir, MaxMissleDir) + nYFactor * g_DirSin(nDSubDir , MaxMissleDir)) >> 10;
  1466. }
  1467. else
  1468. {
  1469. nSinAB = g_DirSin(nCurSubDir, MaxMissleDir);
  1470. nCosAB = g_DirCos(nCurSubDir, MaxMissleDir);
  1471. }
  1472. nDesSubX = nRefPX + ((nCosAB * nFirstStep) >> 10);
  1473. nDesSubY = nRefPY + ((nSinAB * nFirstStep) >> 10);
  1474. if (nDesSubX < 0 || nDesSubY < 0)  continue;
  1475. if (m_bBaseSkill)
  1476. {
  1477. int nMissleIndex ;
  1478. int nSubWorldId ; 
  1479. nSubWorldId = Npc[nLauncher].m_SubWorldIndex;
  1480. if (nSubWorldId < 0) goto exit;
  1481. nMissleIndex = MissleSet.Add(nSubWorldId, nDesSubX, nDesSubY);
  1482. if (nMissleIndex < 0) continue;
  1483. Missle[nMissleIndex].m_nDir = nCurSubDir;
  1484. Missle[nMissleIndex].m_nDirIndex = g_Dir2DirIndex(nCurSubDir, MaxMissleDir);
  1485. CreateMissle(nLauncher, m_nChildSkillId, nMissleIndex);
  1486. Missle[nMissleIndex].m_nFollowNpcIdx = nTargetId;
  1487. Missle[nMissleIndex].m_dwBornTime = SubWorld[nSubWorldId].m_dwCurrentTime;
  1488. Missle[nMissleIndex].m_nSubWorldId = nSubWorldId;
  1489. Missle[nMissleIndex].m_nLauncher = nLauncher;
  1490. Missle[nMissleIndex].m_dwLauncherId = Npc[nLauncher].m_dwID;
  1491. if (pSkillParam->nParent)
  1492. Missle[nMissleIndex].m_nParentMissleIndex = pSkillParam->nParent;
  1493. else 
  1494. Missle[nMissleIndex].m_nParentMissleIndex = 0;
  1495. Missle[nMissleIndex].m_nSkillId = m_nId;
  1496. Missle[nMissleIndex].m_nStartLifeTime = pSkillParam->nWaitTime + GetMissleGenerateTime(i);
  1497. Missle[nMissleIndex].m_nLifeTime += Missle[nMissleIndex].m_nStartLifeTime;
  1498. Missle[nMissleIndex].m_nXFactor = nCosAB;
  1499. Missle[nMissleIndex].m_nYFactor = nSinAB;
  1500. Missle[nMissleIndex].m_nRefPX = nDesSubX;
  1501. Missle[nMissleIndex].m_nRefPY = nDesSubY;
  1502. #ifdef _SERVER
  1503. Missle[nMissleIndex].SetMagicAttribsData(pNewMagicAttribsData);
  1504. #endif //_SERVER
  1505. nCastMissleNum ++;
  1506. }
  1507. else
  1508. {
  1509. _ASSERT(m_nChildSkillId > 0 && m_nChildSkillLevel > 0) ;
  1510. KSkill * pOrdinSkill = (KSkill *) g_SkillManager.GetSkill(m_nChildSkillId, m_nChildSkillLevel);
  1511. if (pOrdinSkill) 
  1512. {
  1513. if (!pSkillParam->nParent)
  1514. nCastMissleNum +=  pOrdinSkill->Cast(nLauncher,  nRefPX, nRefPY , pSkillParam->nWaitTime + GetMissleGenerateTime(i), eLauncherType);
  1515. else
  1516. nCastMissleNum +=  pOrdinSkill->Cast(pSkillParam->nParent,  nRefPX, nRefPY , pSkillParam->nWaitTime + GetMissleGenerateTime(i), pSkillParam->eParentType); 
  1517. }
  1518. }
  1519. nCurMSRadius -- ;
  1520. }
  1521. exit:
  1522. #ifdef _SERVER
  1523. if (pNewMagicAttribsData)
  1524. if (pNewMagicAttribsData->GetRef() == 0)
  1525. delete pNewMagicAttribsData;
  1526. #endif
  1527. return nCastMissleNum;
  1528. }
  1529. /*!*****************************************************************************
  1530. // Function : KSkill::GetChildSkillNum
  1531. // Purpose : 由于可能某些技能中,随着技能等级的升级,子弹的数目也会因此增加,所以通过该函数获得实际的子技能数目
  1532. // Return : 
  1533. // Argumant : int nLevel
  1534. // Comments :
  1535. // Author : RomanDou
  1536. *****************************************************************************/
  1537. int  KSkill::GetChildSkillNum(int nLevel)  const 
  1538. {
  1539. return m_nChildSkillNum;
  1540. };
  1541. /*!*****************************************************************************
  1542. // Function : KSkill::CreateMissle
  1543. // Purpose : 设置子弹的基本数据,以及该技能该等级下的对子弹信息的变动数据
  1544. // 设置用于数值计算的指针
  1545. // Return : 
  1546. // Argumant : int nChildSkillId
  1547. // Argumant : int nMissleIndex
  1548. // Comments :
  1549. // Author : RomanDou
  1550. *****************************************************************************/
  1551. void KSkill::CreateMissle(int nLauncher, int nChildSkillId, int nMissleIndex)  const 
  1552. {
  1553. _ASSERT(nChildSkillId > 0 && nChildSkillId < MAX_MISSLESTYLE && nMissleIndex > 0);
  1554. if (nLauncher <= 0) 
  1555. {
  1556. return ;
  1557. }
  1558. KMissle * pMissle = &Missle[nMissleIndex];
  1559. g_MisslesLib[nChildSkillId] = *pMissle;//复制拷贝对象
  1560. pMissle->m_nLevel = m_ulLevel;
  1561. pMissle->m_bCollideEvent = m_bCollideEvent;
  1562. pMissle->m_bVanishedEvent   = m_bVanishedEvent;
  1563. pMissle->m_bStartEvent = m_bStartEvent;
  1564. pMissle->m_bFlyEvent = m_bFlyingEvent;
  1565. pMissle->m_nFlyEventTime = m_nFlyEventTime;
  1566. pMissle->m_nMissleId = nMissleIndex;
  1567. pMissle->m_bClientSend      = m_bClientSend;
  1568. pMissle->m_bMustBeHit = m_bMustBeHit;
  1569. pMissle->m_bIsMelee = m_bIsMelee;
  1570. pMissle->m_bByMissle = m_bByMissle;
  1571. pMissle->m_bTargetSelf = (m_bTargetSelf == 1);
  1572. pMissle->m_nInteruptTypeWhenMove = m_nInteruptTypeWhenMove;
  1573. pMissle->m_bHeelAtParent = m_bHeelAtParent;
  1574. pMissle->m_bUseAttackRating = m_bUseAttackRate;
  1575. pMissle->m_bDoHurt = m_bDoHurt;
  1576. if (pMissle->m_nInteruptTypeWhenMove)
  1577. {
  1578. Npc[nLauncher].GetMpsPos(&pMissle->m_nLauncherSrcPX, &pMissle->m_nLauncherSrcPY);
  1579. }
  1580. pMissle->m_eRelation = m_eRelation;
  1581. #ifndef _SERVER
  1582. pMissle->m_MissleRes.m_bNeedShadow   = m_bNeedShadow;
  1583. pMissle->m_MissleRes.m_nMaxShadowNum = m_nMaxShadowNum;
  1584. pMissle->m_MissleRes.m_nMissleId  = nMissleIndex;
  1585. if (!pMissle->m_MissleRes.Init()) g_DebugLog("创建子弹贴图失败!!!%s", __FILE__) ;
  1586. #endif
  1587. pMissle->DoWait();
  1588. for (int i = 0  ; i < m_nMissleAttribsNum; i ++)
  1589. {
  1590. switch (m_MissleAttribs[i].nAttribType)
  1591. {
  1592. case magic_missle_movekind_v:
  1593. {
  1594. pMissle->m_eMoveKind = (eMissleMoveKind) m_MissleAttribs[i].nValue[0];
  1595. }break;
  1596. case magic_missle_speed_v:
  1597. {
  1598. pMissle->m_nSpeed = m_MissleAttribs[i].nValue[0];
  1599. }break;
  1600. case magic_missle_lifetime_v:
  1601. {
  1602. pMissle->m_nLifeTime = m_MissleAttribs[i].nValue[0];
  1603. }break;
  1604. case magic_missle_height_v:
  1605. {
  1606. pMissle->m_nHeight = m_MissleAttribs[i].nValue[0];
  1607. }break;
  1608. case magic_missle_damagerange_v:
  1609. {
  1610. pMissle->m_nDamageRange = m_MissleAttribs[i].nValue[0];
  1611. }break;
  1612. case magic_missle_radius_v:
  1613. {
  1614. }break;
  1615. }
  1616. }
  1617. if (m_bIsMelee)
  1618. pMissle->m_nLifeTime = Npc[nLauncher].ModifyMissleLifeTime(pMissle->m_nLifeTime);
  1619. else
  1620. {
  1621. pMissle->m_nSpeed = Npc[nLauncher].ModifyMissleSpeed(pMissle->m_nSpeed);
  1622. pMissle->m_bCollideVanish = Npc[nLauncher].ModifyMissleCollsion(pMissle->m_bCollideVanish);
  1623. }
  1624. }
  1625. /*!*****************************************************************************
  1626. // Function : KSkill::GetInfoFromTabFile
  1627. // Purpose : 从TabFile中获得该技能的常规属性
  1628. // Return : 
  1629. // Argumant : int nCol
  1630. // Comments :
  1631. // Author : RomanDou
  1632. *****************************************************************************/
  1633. BOOL KSkill::GetInfoFromTabFile(int nRow)
  1634. {
  1635. KITabFile * pITabFile = &g_OrdinSkillsSetting;
  1636. return GetInfoFromTabFile(&g_OrdinSkillsSetting, nRow);
  1637. }
  1638. BOOL KSkill::GetInfoFromTabFile(KITabFile *pSkillsSettingFile, int nRow)
  1639. {
  1640. if (!pSkillsSettingFile || nRow < 0) return FALSE;
  1641. //
  1642. pSkillsSettingFile->GetString(nRow, "SkillName", "", m_szName, sizeof(m_szName) ,TRUE);
  1643. pSkillsSettingFile->GetInteger(nRow, "SkillId", 0, (int *)&m_nId,TRUE);
  1644. int nReqLevel = 0;
  1645. pSkillsSettingFile->GetInteger(nRow, "ReqLevel", 0, (int *)&nReqLevel, TRUE);
  1646. m_usReqLevel = (unsigned short)nReqLevel;
  1647. pSkillsSettingFile->GetInteger(nRow, "EqtLimit", -2, (int *)&m_nEquiptLimited, TRUE);
  1648. pSkillsSettingFile->GetInteger(nRow, "HorseLimit", 0, (int *)&m_nHorseLimited, TRUE);
  1649. pSkillsSettingFile->GetInteger(nRow, "DoHurt", 1, (int *)&m_bDoHurt);
  1650. pSkillsSettingFile->GetInteger(nRow, "ChildSkillNum", 0, &m_nChildSkillNum,TRUE);
  1651. pSkillsSettingFile->GetInteger(nRow, "MisslesForm", 0, (int *)&m_eMisslesForm, TRUE);
  1652. pSkillsSettingFile->GetInteger(nRow, "CharClass", 0, &m_nCharClass, TRUE);
  1653. pSkillsSettingFile->GetInteger(nRow, "SkillStyle", 0, (int *)&m_eSkillStyle, TRUE);
  1654. pSkillsSettingFile->GetInteger(nRow, "CharAnimId", 0, (int *)&m_nCharActionId, TRUE);
  1655. pSkillsSettingFile->GetInteger(nRow, "IsPhysical", 0, &m_bIsPhysical, TRUE);
  1656. pSkillsSettingFile->GetInteger(nRow, "IsAura", 0, &m_bIsAura, TRUE);
  1657. pSkillsSettingFile->GetInteger(nRow, "IsUseAR", 0, &m_bUseAttackRate, TRUE);
  1658. pSkillsSettingFile->GetInteger(nRow, "TargetOnly", 0, &m_bTargetOnly, TRUE);
  1659. pSkillsSettingFile->GetInteger(nRow, "TargetEnemy", 0, &m_bTargetEnemy, TRUE);
  1660. pSkillsSettingFile->GetInteger(nRow, "TargetAlly", 0, &m_bTargetAlly, TRUE);
  1661. pSkillsSettingFile->GetInteger(nRow, "TargetObj", 0, &m_bTargetObj, TRUE);
  1662. pSkillsSettingFile->GetInteger(nRow, "BaseSkill", 0, &m_bBaseSkill, TRUE);
  1663. pSkillsSettingFile->GetInteger(nRow, "ByMissle", 0, &m_bByMissle, TRUE);
  1664. pSkillsSettingFile->GetInteger(nRow, "ChildSkillId", 0, &m_nChildSkillId, TRUE);
  1665. pSkillsSettingFile->GetInteger(nRow, "FlyEvent", 0, &m_bFlyingEvent, TRUE);
  1666. pSkillsSettingFile->GetInteger(nRow, "StartEvent", 0, &m_bStartEvent, TRUE);
  1667. pSkillsSettingFile->GetInteger(nRow, "CollideEvent", 0, &m_bCollideEvent, TRUE);
  1668. pSkillsSettingFile->GetInteger(nRow, "VanishedEvent", 0, &m_bVanishedEvent, TRUE);
  1669. pSkillsSettingFile->GetInteger(nRow, "FlySkillId", 0, &m_nFlySkillId, TRUE);
  1670. pSkillsSettingFile->GetInteger(nRow, "StartSkillId", 0, &m_nStartSkillId, TRUE);
  1671. pSkillsSettingFile->GetInteger(nRow, "VanishedSkillId", 0, &m_nVanishedSkillId, TRUE);
  1672. pSkillsSettingFile->GetInteger(nRow, "CollidSkillId", 0, &m_nCollideSkillId, TRUE);
  1673. pSkillsSettingFile->GetInteger(nRow, "SkillCostType", 0, (int *)&m_nSkillCostType, TRUE);
  1674. pSkillsSettingFile->GetInteger(nRow, "CostValue", 0, &m_nCost, TRUE);
  1675. pSkillsSettingFile->GetInteger(nRow, "TimePerCast", 0, &m_nMinTimePerCast, TRUE);
  1676. pSkillsSettingFile->GetInteger(nRow, "Param1", 0, &m_nValue1, TRUE);
  1677. pSkillsSettingFile->GetInteger(nRow, "Param2", 0, &m_nValue2, TRUE);
  1678. pSkillsSettingFile->GetInteger(nRow, "ChildSkillLevel", 0, &m_nChildSkillLevel, TRUE);
  1679. pSkillsSettingFile->GetInteger(nRow, "EventSkillLevel", 0, &m_nEventSkillLevel, TRUE);
  1680. pSkillsSettingFile->GetInteger(nRow, "IsMelee", 0, &m_bIsMelee, TRUE);
  1681. pSkillsSettingFile->GetInteger(nRow, "FlyEventTime", 0, &m_nFlyEventTime, TRUE);
  1682. pSkillsSettingFile->GetInteger(nRow, "MslsGenerate", 0, (int *)&m_eMisslesGenerateStyle, TRUE);
  1683. pSkillsSettingFile->GetInteger(nRow, "MslsGenerateData",0, &m_nMisslesGenerateData, TRUE);
  1684. pSkillsSettingFile->GetInteger(nRow, "MaxShadowNum", 0, &m_nMaxShadowNum, TRUE);
  1685. pSkillsSettingFile->GetInteger(nRow, "AttackRadius", 50, &m_nAttackRadius, TRUE);
  1686. pSkillsSettingFile->GetInteger(nRow, "WaitTime", 0, &m_nWaitTime, TRUE);
  1687. pSkillsSettingFile->GetInteger(nRow, "ClientSend", 0, &m_bClientSend, TRUE);
  1688. pSkillsSettingFile->GetInteger(nRow, "TargetSelf", 0, &m_bTargetSelf, TRUE);
  1689. pSkillsSettingFile->GetInteger(nRow, "StopWhenMove", 0, &m_nInteruptTypeWhenMove, TRUE);
  1690. pSkillsSettingFile->GetInteger(nRow, "HeelAtParent",  0, (int *)&m_bHeelAtParent, TRUE );
  1691. //服务器端需要获得并通知客户端
  1692. pSkillsSettingFile->GetInteger(nRow, "StateSpecialId",  0, &m_nStateSpecialId, TRUE);
  1693. m_eRelation = 0;
  1694. if (m_bTargetEnemy)
  1695. m_eRelation |= relation_enemy;
  1696. if (m_bTargetAlly)
  1697. m_eRelation |= relation_ally;
  1698. if (m_bTargetSelf)
  1699. m_eRelation |= relation_self;
  1700. #ifndef _SERVER
  1701. pSkillsSettingFile->GetString(nRow, "SkillDesc", "", m_szSkillDesc, 100);
  1702. pSkillsSettingFile->GetInteger(nRow, "NeedShadow", 0, &m_bNeedShadow, TRUE);
  1703. pSkillsSettingFile->GetString(nRow, "SkillIcon","\spr\skill\图标\通用.spr", m_szSkillIcon, 80);
  1704. if (!m_szSkillIcon[0]) strcpy(m_szSkillIcon, "\spr\skill\图标\通用.spr");
  1705. pSkillsSettingFile->GetInteger(nRow, "LRSkill", 0, (int*)&m_eLRSkillInfo);
  1706. pSkillsSettingFile->GetString(nRow, "PreCastSpr", "", m_szPreCastEffectFile, 100);
  1707. pSkillsSettingFile->GetString(nRow, "ManCastSnd","", m_szManPreCastSoundFile, 100);
  1708. pSkillsSettingFile->GetString(nRow, "FMCastSnd", "", m_szFMPreCastSoundFile, 100);
  1709. #else
  1710. char szLevelScript[MAX_PATH];
  1711. //读取设定脚本1,记录每一级技能的属性变化,数值设定的
  1712. pSkillsSettingFile->GetString(nRow, "LvlSetScript", "", szLevelScript, MAX_PATH);
  1713. if (szLevelScript[0])
  1714. {
  1715. strlwr(szLevelScript);
  1716. m_dwSkillLevelDataScriptId = g_FileName2Id(szLevelScript);
  1717. }
  1718. //读取设定脚本2,记录技能限制信息
  1719. pSkillsSettingFile->GetString(nRow, "LevelUpScript","",szLevelScript, MAX_PATH);
  1720. if (szLevelScript[0])
  1721. {
  1722. strlwr(szLevelScript);
  1723. m_dwSkillLevelUpScriptID = g_FileName2Id(szLevelScript);
  1724. }
  1725. #endif
  1726. return TRUE;
  1727. }
  1728. /*!*****************************************************************************
  1729. // Function : KSkill::LoadSkillLevelData
  1730. // Purpose : 读表获得当前等级下当前技能的技能、子弹、碰撞数值影响
  1731. // Return : 
  1732. // Argumant : int nLevel
  1733. // Comments :
  1734. // Author : Romandou
  1735. ****************************************************************************/
  1736. void KSkill::LoadSkillLevelData(unsigned long  nLevel /* =0*/, int nParam)
  1737. {
  1738. m_nMissleAttribsNum = 0;
  1739. m_nDamageAttribsNum = 0;
  1740. m_nImmediateAttribsNum = 0;
  1741. m_nStateAttribsNum = 0; //个数,最大10
  1742. char szSettingScriptName[MAX_PATH];
  1743. char szSettingNameValue[100];
  1744. char szSettingDataValue[100];
  1745. char szResult[300];
  1746. int nRowId = nParam;
  1747. if (nRowId < 2) return ;
  1748. //Question 必须顺序一至才行
  1749. KLuaScript * pScript = NULL;
  1750. #ifndef _SERVER
  1751. g_OrdinSkillsSetting.GetString(nRowId,  "LvlSetScript", "", szSettingScriptName, MAX_PATH );
  1752. if (!szSettingScriptName[0]) return;
  1753. g_SetFilePath("\");
  1754. //加载Lua脚本
  1755. KLuaScript Script;
  1756. Script.Init();
  1757. if (!Script.Load(szSettingScriptName)) 
  1758. {
  1759. g_DebugLog("无法读取技能设定脚本文件%s,请确认是否文件存在或脚本语法有误!", szSettingScriptName);
  1760. return;
  1761. }
  1762. pScript  = &Script;
  1763. #else
  1764. if (!m_dwSkillLevelDataScriptId) 
  1765. {
  1766. printf("致命错误!无法获得技能[%s]的设定脚本,请检查是否存在或语法有误!n", GetSkillName());
  1767. return ;
  1768. }
  1769. pScript = (KLuaScript*)g_GetScript(m_dwSkillLevelDataScriptId);
  1770. if (!pScript)
  1771. {
  1772. printf("致命错误!无法获得技能[%s]的设定脚本,请检查是否存在或语法有误!n", GetSkillName());
  1773. return ;
  1774. }
  1775. #endif
  1776. int nSafeIndex = 1;
  1777. pScript->SafeCallBegin(&nSafeIndex);
  1778. for(int i = 0 ;  i  < MAXSKILLLEVELSETTINGNUM ; i ++)
  1779. {
  1780. char szSettingName[40];
  1781. char szSettingData[40];
  1782. sprintf(szSettingName, "LvlSetting%d", i + 1);
  1783. sprintf(szSettingData, "LvlData%d", i + 1);
  1784. g_OrdinSkillsSetting.GetString(nRowId, szSettingName, "", szSettingNameValue, 100);
  1785. g_OrdinSkillsSetting.GetString(nRowId, szSettingData, "", szSettingDataValue, 100);
  1786. if (szSettingNameValue[0] == 0  || szSettingDataValue[0] == '0' )
  1787. {
  1788. continue;
  1789. }
  1790. pScript->CallFunction("GetSkillLevelData", 1, "ssd", szSettingNameValue, szSettingDataValue, nLevel);
  1791. const char * szType = lua_typename(pScript->m_LuaState, Lua_GetTopIndex(pScript->m_LuaState));
  1792. if (Lua_IsNumber(pScript->m_LuaState, Lua_GetTopIndex(pScript->m_LuaState)) == 1)
  1793. {
  1794. int nResult = (int)Lua_ValueToNumber(pScript->m_LuaState, Lua_GetTopIndex(pScript->m_LuaState));
  1795. sprintf(szResult, "%d", nResult);
  1796. }
  1797. else if (Lua_IsString(pScript->m_LuaState, Lua_GetTopIndex(pScript->m_LuaState)) == 1)
  1798. {
  1799. strcpy(szResult , (char *)Lua_ValueToString(pScript->m_LuaState, Lua_GetTopIndex(pScript->m_LuaState)));
  1800. }
  1801. else
  1802. {
  1803. char szMsg[300];
  1804. sprintf(szMsg, "当获得该技能等级为%d(%s,%s)时,出错,请检查脚本!,",nLevel, szSettingNameValue, szSettingDataValue);
  1805. g_DebugLog(szMsg);
  1806. break;
  1807. }
  1808. ParseString2MagicAttrib(nLevel, szSettingNameValue, szResult);
  1809. }
  1810. pScript->SafeCallEnd(nSafeIndex);
  1811. }
  1812. #ifdef _SERVER
  1813. //When nLauncher == 0 , means neednt  AppendSkillEffect;
  1814. KMissleMagicAttribsData* KSkill::CreateMissleMagicAttribsData(int nLauncher)  const 
  1815. {
  1816. if (nLauncher < 0 || m_bClientSend) return NULL; 
  1817. KMissleMagicAttribsData* pMissleMagicAttribsData = new KMissleMagicAttribsData;
  1818. pMissleMagicAttribsData->m_pStateMagicAttribs = (KMagicAttrib *)m_StateAttribs;
  1819. pMissleMagicAttribsData->m_nStateMagicAttribsNum = m_nStateAttribsNum;
  1820. pMissleMagicAttribsData->m_pImmediateAttribs = (KMagicAttrib *)m_ImmediateAttribs;
  1821. pMissleMagicAttribsData->m_nImmediateMagicAttribsNum = m_nImmediateAttribsNum;
  1822. KMagicAttrib * pDamageAttribs =  new KMagicAttrib[MAX_MISSLE_DAMAGEATTRIB];
  1823. pMissleMagicAttribsData->m_nDamageMagicAttribsNum = m_nDamageAttribsNum;
  1824. //根据玩家的基本属性,确定子弹的伤害
  1825. if (nLauncher)
  1826. {
  1827. Npc[nLauncher].AppendSkillEffect(m_bIsPhysical, m_bIsMelee, (KMagicAttrib *)m_DamageAttribs, pDamageAttribs);
  1828. }
  1829. else
  1830. {
  1831. memcpy(pDamageAttribs, (KMagicAttrib *)m_DamageAttribs, sizeof(m_DamageAttribs));
  1832. }
  1833. pMissleMagicAttribsData->m_pDamageMagicAttribs = pDamageAttribs;
  1834. return pMissleMagicAttribsData;
  1835. }
  1836. #endif
  1837. /*!*****************************************************************************
  1838. // Function : KSkill::SetMissleGenerateTime
  1839. // Purpose : 获得当前的子弹的实际产生时间
  1840. // Return : void 
  1841. // Argumant : Missle * pMissle
  1842. // Argumant : int nNo
  1843. // Comments :
  1844. // Author : RomanDou
  1845. *****************************************************************************/
  1846. unsigned int KSkill::GetMissleGenerateTime(int nNo) const 
  1847. {
  1848. switch(m_eMisslesGenerateStyle)
  1849. {
  1850. case SKILL_MGS_NULL:
  1851. {
  1852. return m_nWaitTime;
  1853. }break;
  1854. case SKILL_MGS_SAMETIME:
  1855. {
  1856. return  m_nWaitTime + m_nMisslesGenerateData;
  1857. }break;
  1858. case SKILL_MGS_ORDER:
  1859. {
  1860. return  m_nWaitTime + nNo * m_nMisslesGenerateData;
  1861. }break;
  1862. case SKILL_MGS_RANDONORDER:
  1863. {
  1864. if (g_Random(2) == 1) 
  1865. return m_nWaitTime + nNo * m_nMisslesGenerateData + g_Random(m_nMisslesGenerateData);
  1866. else 
  1867. return m_nWaitTime + nNo * m_nMisslesGenerateData  - g_Random(m_nMisslesGenerateData / 2);
  1868. }break;
  1869. case SKILL_MGS_RANDONSAME:
  1870. {
  1871. return  m_nWaitTime + g_Random(m_nMisslesGenerateData);
  1872. }break;
  1873. case SKILL_MGS_CENTEREXTENDLINE:
  1874. {
  1875. if (m_nChildSkillNum <= 1) return m_nWaitTime;
  1876. int nCenter = m_nChildSkillNum / 2 ;
  1877. return m_nWaitTime + abs(nNo - nCenter) * m_nMisslesGenerateData ;
  1878. }
  1879. }
  1880. return m_nWaitTime;
  1881. }
  1882. int KSkill::GetSkillIdFromName(char * szSkillName)  
  1883. {
  1884. //
  1885. if (!szSkillName || !szSkillName[0]) 
  1886.         return -1;
  1887. for (int i = 0; i < MAX_SKILL; i ++)
  1888. {
  1889. KSkill * pOrdinSkill = (KSkill *) g_SkillManager.GetSkill(i, 1);
  1890. if (pOrdinSkill) 
  1891. {
  1892. if (!strcmp(pOrdinSkill->m_szName, szSkillName))
  1893.             {
  1894.                 return i;
  1895.             }
  1896. }
  1897. }
  1898. return -1;
  1899. }
  1900. /*!*****************************************************************************
  1901. // Function : KSkill::CastInitiativeSkill
  1902. // Purpose : 主动辅助技能
  1903. // Return : BOOL 
  1904. // Argumant : int nLauncher
  1905. // Argumant : int nParam1
  1906. // Argumant : int nParam2
  1907. // Argumant : int nWaitTime
  1908. // Comments :
  1909. // Author : RomanDou
  1910. *****************************************************************************/
  1911. BOOL KSkill::CastInitiativeSkill(int nLauncher, int nParam1, int nParam2, int nWaitTime)  const 
  1912. {
  1913. #ifdef _SERVER
  1914. //对自已的主动辅助技能
  1915. if (nParam1 != -1 && m_bTargetSelf) 
  1916. {
  1917. nParam1 = -1;
  1918. nParam2 = nLauncher;
  1919. }
  1920. else
  1921. {
  1922. if (nParam1 != -1 || nParam2 <= 0 || nParam2 >= MAX_NPC) return FALSE;
  1923. NPC_RELATION  Relation = NpcSet.GetRelation(nLauncher, nParam2);
  1924. if (m_bTargetEnemy)
  1925. {
  1926. if (Relation & relation_enemy) 
  1927. goto lab_processdamage;
  1928. }
  1929. if (m_bTargetAlly)
  1930. {
  1931. if (Relation & relation_ally) 
  1932. goto lab_processdamage;
  1933. }
  1934. if (m_bTargetSelf)
  1935. {
  1936. if (Relation & relation_self) 
  1937. goto lab_processdamage;
  1938. }
  1939. return FALSE;
  1940. }
  1941. lab_processdamage:
  1942. KMissleMagicAttribsData * pAttribsData = CreateMissleMagicAttribsData(nLauncher);
  1943. if (pAttribsData) 
  1944. {
  1945. if (Npc[nParam2].ReceiveDamage(nLauncher, m_bIsMelee, pAttribsData->m_pDamageMagicAttribs, m_bUseAttackRate, m_bDoHurt))
  1946. {
  1947. if (pAttribsData->m_nStateMagicAttribsNum > 0)
  1948. Npc[nParam2].SetStateSkillEffect(nLauncher, m_nId, m_ulLevel, pAttribsData->m_pStateMagicAttribs, pAttribsData->m_nStateMagicAttribsNum, pAttribsData->m_pStateMagicAttribs[0].nValue[1]);
  1949. if (pAttribsData->m_nImmediateMagicAttribsNum > 0)
  1950. Npc[nParam2].SetImmediatelySkillEffect(nLauncher, pAttribsData->m_pImmediateAttribs, pAttribsData->m_nImmediateMagicAttribsNum);
  1951. }
  1952. return TRUE;
  1953. }
  1954. if (pAttribsData->DelRef() == 0)
  1955. delete pAttribsData;
  1956. #endif //_SERVER
  1957. return TRUE;
  1958. }
  1959. /*!*****************************************************************************
  1960. // Function : KSkill::CastPassivitySkill
  1961. // Purpose : 被动
  1962. // Return : BOOL 
  1963. // Argumant : int nLauncher
  1964. // Argumant : int nParam1
  1965. // Argumant : int nParam2
  1966. // Argumant : int nWaitTime
  1967. // Comments :
  1968. // Author : RomanDou
  1969. *****************************************************************************/
  1970. BOOL KSkill::CastPassivitySkill(int nLauncher, int nParam1, int nParam2, int nWaitTime)  const 
  1971. {
  1972. #ifdef _SERVER
  1973. //是被动技能时,是否还需要生成MissleMagicAttribs?
  1974. KMissleMagicAttribsData * pAttribsData = (KMissleMagicAttribsData*)m_StateAttribs;//CreateMissleMagicAttribsData(nLauncher);
  1975. if (m_nStateAttribsNum > 0)
  1976. {
  1977. Npc[nLauncher].SetStateSkillEffect(nLauncher, m_nId, m_ulLevel, (KMagicAttrib *)m_StateAttribs, m_nStateAttribsNum, -1);
  1978. }
  1979. #endif
  1980. return TRUE;
  1981. }
  1982. /*!*****************************************************************************
  1983. // Function : KSkill::ParseString2MagicAttrib
  1984. // Purpose : 解析通过脚本运算获得的技能数据
  1985. // Return : 
  1986. // Argumant : char * szMagicAttribName
  1987. // Argumant : char * szValue
  1988. // Comments :
  1989. // Author : RomanDou
  1990. *****************************************************************************/
  1991. BOOL KSkill::ParseString2MagicAttrib(unsigned long ulLevel, char * szMagicAttribName, char * szValue)  
  1992. {
  1993. int nValue1 = 0;
  1994. int nValue2 = 0;
  1995. int nValue3 = 0;
  1996.     const char *pcszTemp = NULL;
  1997. if ((!szMagicAttribName) || (!szMagicAttribName[0])) return FALSE;
  1998. //nValue2 当值为-1时为永久性状态,0为非状态,其它值为有时效性状态魔法效果
  1999. //需要将状态数据与非状态数据分离出来,放入相应的数组内,并记录总数量
  2000. for (int i  = 0 ; i <= magic_normal_end; i ++)
  2001. {
  2002. if (!strcmp(szMagicAttribName, MagicAttrib2String(i)))
  2003. {
  2004.             pcszTemp = szValue;
  2005.             nValue1 = KSG_StringGetInt(&pcszTemp, 0);
  2006.             KSG_StringSkipSymbol(&pcszTemp, ',');
  2007.             nValue2 = KSG_StringGetInt(&pcszTemp, 0);
  2008.             KSG_StringSkipSymbol(&pcszTemp, ',');
  2009.             nValue3 = KSG_StringGetInt(&pcszTemp, 0);
  2010. //sscanf(szValue, "%d,%d,%d", &nValue1, &nValue2, &nValue3);
  2011. if (i > magic_missle_begin && i < magic_missle_end)
  2012. {
  2013. m_MissleAttribs[m_nMissleAttribsNum].nAttribType = i;
  2014. m_MissleAttribs[m_nMissleAttribsNum].nValue[0] = nValue1;
  2015. m_MissleAttribs[m_nMissleAttribsNum].nValue[1] = nValue2;
  2016. m_MissleAttribs[m_nMissleAttribsNum].nValue[2] = nValue3;
  2017. m_nMissleAttribsNum ++;
  2018. return TRUE;
  2019. }
  2020. if (i > magic_skill_begin && i < magic_skill_end)
  2021. {
  2022. switch(i)
  2023. {
  2024. case magic_skill_cost_v: // 消耗MANA
  2025. {
  2026. m_nCost = nValue1;
  2027. }
  2028. break;
  2029. case magic_skill_costtype_v:
  2030. {
  2031. m_nSkillCostType = (NPCATTRIB)nValue1;
  2032. }break;
  2033. case magic_skill_mintimepercast_v:  // 每次发魔法的间隔时间
  2034. {
  2035. m_nMinTimePerCast = nValue1;
  2036. }break;
  2037. case magic_skill_misslenum_v:
  2038. {
  2039. m_nChildSkillNum = nValue1;
  2040. }break;
  2041. case magic_skill_misslesform_v:
  2042. {
  2043. m_eMisslesForm = (eMisslesForm) nValue1;
  2044. }break;
  2045. case magic_skill_param1_v:
  2046. {
  2047. m_nValue1 = nValue1;
  2048. }
  2049. break;
  2050. case magic_skill_param2_v:
  2051. {
  2052. m_nValue2 = nValue2;
  2053. }break;
  2054. case magic_skill_eventskilllevel:
  2055. {
  2056. m_nEventSkillLevel = nValue1;
  2057. }
  2058. }
  2059. return TRUE;
  2060. }
  2061. if (i > magic_damage_begin && i < magic_damage_end)
  2062. {
  2063. switch(i)
  2064. {
  2065. case magic_attackrating_v:
  2066. case magic_attackrating_p:
  2067. m_DamageAttribs[0].nAttribType = i;
  2068. m_DamageAttribs[0].nValue[0] = nValue1;
  2069. m_DamageAttribs[0].nValue[1] = nValue2;
  2070. m_DamageAttribs[0].nValue[2] = nValue3;
  2071. m_nDamageAttribsNum ++;
  2072. break;
  2073. case magic_ignoredefense_p:
  2074. m_DamageAttribs[1].nAttribType = i;
  2075. m_DamageAttribs[1].nValue[0] = nValue1;
  2076. m_DamageAttribs[1].nValue[1] = nValue2;
  2077. m_DamageAttribs[1].nValue[2] = nValue3;
  2078. m_nDamageAttribsNum ++;
  2079. break;
  2080. case magic_physicsdamage_v:
  2081. case magic_physicsenhance_p:
  2082. m_DamageAttribs[2].nAttribType = i;
  2083. m_DamageAttribs[2].nValue[0] = nValue1;
  2084. m_DamageAttribs[2].nValue[1] = nValue2;
  2085. m_DamageAttribs[2].nValue[2] = nValue3;
  2086. m_nDamageAttribsNum ++;
  2087. break;
  2088. case magic_colddamage_v:
  2089. case magic_coldenhance_p:
  2090. m_DamageAttribs[3].nAttribType = i;
  2091. m_DamageAttribs[3].nValue[0] = nValue1;
  2092. m_DamageAttribs[3].nValue[1] = nValue2;
  2093. m_DamageAttribs[3].nValue[2] = nValue3;
  2094. m_nDamageAttribsNum ++;
  2095. break;
  2096. case magic_firedamage_v:
  2097. case magic_fireenhance_p:
  2098. m_DamageAttribs[4].nAttribType = i;
  2099. m_DamageAttribs[4].nValue[0] = nValue1;
  2100. m_DamageAttribs[4].nValue[1] = nValue2;
  2101. m_DamageAttribs[4].nValue[2] = nValue3;
  2102. m_nDamageAttribsNum ++;
  2103. break;
  2104. case magic_lightingdamage_v:
  2105. case magic_lightingenhance_p:
  2106. m_DamageAttribs[5].nAttribType = i;
  2107. m_DamageAttribs[5].nValue[0] = nValue1;
  2108. m_DamageAttribs[5].nValue[1] = nValue2;
  2109. m_DamageAttribs[5].nValue[2] = nValue3;
  2110. m_nDamageAttribsNum ++;
  2111. break;
  2112. case magic_poisondamage_v:
  2113. case magic_poisonenhance_p:
  2114. m_DamageAttribs[6].nAttribType = i;
  2115. m_DamageAttribs[6].nValue[0] = nValue1;
  2116. m_DamageAttribs[6].nValue[1] = nValue2;
  2117. m_DamageAttribs[6].nValue[2] = nValue3;
  2118. m_nDamageAttribsNum ++;
  2119. break;
  2120. case magic_magicdamage_v:
  2121. case magic_magicenhance_p:
  2122. m_DamageAttribs[7].nAttribType = i;
  2123. m_DamageAttribs[7].nValue[0] = nValue1;
  2124. m_DamageAttribs[7].nValue[1] = nValue2;
  2125. m_DamageAttribs[7].nValue[2] = nValue3;
  2126. m_nDamageAttribsNum ++;
  2127. break;
  2128. }
  2129. return TRUE;
  2130. }
  2131. //剩下的为数据计算时的数据参数
  2132. //根据nValue2值决定状态参数还是非状态参数
  2133. if (nValue2 == 0) 
  2134. {
  2135. m_ImmediateAttribs[m_nImmediateAttribsNum].nAttribType = i;
  2136. m_ImmediateAttribs[m_nImmediateAttribsNum].nValue[0] = nValue1;
  2137. m_ImmediateAttribs[m_nImmediateAttribsNum].nValue[1] = nValue2;
  2138. m_ImmediateAttribs[m_nImmediateAttribsNum].nValue[2] = nValue3;
  2139. m_nImmediateAttribsNum ++;
  2140. return TRUE;
  2141. }
  2142. else
  2143. {
  2144. m_StateAttribs[m_nStateAttribsNum].nAttribType = i;
  2145. m_StateAttribs[m_nStateAttribsNum].nValue[0] = nValue1;
  2146. m_StateAttribs[m_nStateAttribsNum].nValue[1] = nValue2;
  2147. m_StateAttribs[m_nStateAttribsNum].nValue[2] = nValue3;
  2148. m_nStateAttribsNum ++;
  2149. return TRUE;
  2150. }
  2151. }
  2152. }
  2153. return FALSE;
  2154. }
  2155. const char * KSkill::MagicAttrib2String(int MagicAttrib)  const 
  2156. {
  2157. return  g_MagicID2String(MagicAttrib);
  2158. }
  2159. #ifndef _SERVER
  2160. void KSkill::DrawSkillIcon(int x, int y, int Width, int Height)  
  2161. {
  2162. if (!m_szSkillIcon[0]) return ;
  2163. m_RUIconImage.nType = ISI_T_SPR;
  2164. m_RUIconImage.Color.Color_b.a = 255;
  2165. m_RUIconImage.bRenderStyle = IMAGE_RENDER_STYLE_ALPHA;
  2166. m_RUIconImage.uImage = 0;
  2167. m_RUIconImage.nISPosition = IMAGE_IS_POSITION_INIT;
  2168. m_RUIconImage.bRenderFlag = 0;
  2169. strcpy(m_RUIconImage.szImage, m_szSkillIcon);
  2170. m_RUIconImage.oPosition.nX = x;
  2171. m_RUIconImage.oPosition.nY = y;
  2172. m_RUIconImage.oPosition.nZ = 0;
  2173. m_RUIconImage.nFrame = 0;
  2174. g_pRepresent->DrawPrimitives(1, &m_RUIconImage, RU_T_IMAGE, 1);
  2175. }
  2176. void KSkill::GetDesc(unsigned long ulSkillId, unsigned long ulCurLevel, char * pszMsg, int nOwnerIndex,  bool bGetNextLevelDesc)
  2177. {
  2178. if (!pszMsg) return;
  2179. if (nOwnerIndex <= 0 ) return ;
  2180. strcpy(pszMsg,"");
  2181. char szTemp[300];
  2182. KSkill * pTempSkill = NULL;
  2183. KSkill * pCurSkill = NULL;
  2184. KSkill * pNextSkill = NULL;
  2185. if(ulCurLevel == 0)
  2186. {
  2187. pNextSkill = (KSkill *)g_SkillManager.GetSkill(ulSkillId, 1);
  2188. pTempSkill = pNextSkill;
  2189. }
  2190. else
  2191. {
  2192. pCurSkill = (KSkill *) g_SkillManager.GetSkill(ulSkillId, ulCurLevel);
  2193. pNextSkill = (KSkill *) g_SkillManager.GetSkill(ulSkillId, ulCurLevel + 1);
  2194. pTempSkill = pCurSkill;
  2195. }
  2196. if (pTempSkill == NULL)
  2197. {
  2198. return;
  2199. }
  2200. strcat(pszMsg, "<color=Yellow>");
  2201. strcat(pszMsg, pTempSkill->m_szName);
  2202. strcat(pszMsg, "n<bclr=Black><color>");
  2203. #ifdef SHOW_SKILL_MORE_INFO
  2204. switch(pTempSkill->m_eSkillStyle)
  2205. {
  2206. case SKILL_SS_Missles:
  2207. {
  2208. strcat(pszMsg, "子弹技n");
  2209. szTemp[0] = 0;
  2210. switch(pTempSkill->m_eMisslesForm)
  2211. {
  2212. case SKILL_MF_Wall:
  2213. {
  2214. sprintf(szTemp, "墙形 数量%dn", pTempSkill->m_nChildSkillNum);
  2215. }break; //墙形 多个子弹呈垂直方向排列,类式火墙状
  2216. case SKILL_MF_Line:
  2217. {
  2218. sprintf(szTemp, "线形 数量%dn", pTempSkill->m_nChildSkillNum);
  2219. }break; //线形 多个子弹呈平行于玩家方向排列
  2220. case SKILL_MF_Spread:
  2221. {
  2222. sprintf(szTemp, "散形 数量%dn", pTempSkill->m_nChildSkillNum);
  2223. }break; //散形 多个子弹呈一定的角度的发散状
  2224. case SKILL_MF_Circle:
  2225. {
  2226. sprintf(szTemp, "圆形发散 数量%dn", pTempSkill->m_nChildSkillNum);
  2227. }break; //圆形 多个子弹围成一个圈
  2228. case SKILL_MF_Random:{}break; //随机 多个子弹随机排放
  2229. case SKILL_MF_Zone:
  2230. {
  2231. if (pTempSkill->m_nValue1)
  2232. sprintf(szTemp, "圆形区域 数量%dn", pTempSkill->m_nChildSkillNum);
  2233. else 
  2234. sprintf(szTemp, "方形区域 数量%dn", pTempSkill->m_nChildSkillNum);
  2235. }break; //区域 多个子弹放至在某个范围内
  2236. case SKILL_MF_AtTarget:
  2237. {
  2238. if (pTempSkill->m_nValue1)
  2239. sprintf(szTemp, "定点圆形区域 数量%dn", pTempSkill->m_nChildSkillNum);
  2240. else 
  2241. sprintf(szTemp, "定点方形区域 数量%dn", pTempSkill->m_nChildSkillNum);
  2242. }break; //定点 多个子弹根据
  2243. case SKILL_MF_AtFirer:
  2244. {
  2245. if (pTempSkill->m_nValue1)
  2246. sprintf(szTemp, "定点圆形区域 数量%dn", pTempSkill->m_nChildSkillNum);
  2247. else 
  2248. sprintf(szTemp, "定点方形区域 数量%dn", pTempSkill->m_nChildSkillNum);
  2249. }break; //本身 多个子弹停在玩家当前位置
  2250. }
  2251. strcat(pszMsg, szTemp);
  2252. }break; // 子弹类 本技能用于发送子弹类
  2253. case SKILL_SS_Melee:
  2254. {
  2255. strcat(pszMsg, "格斗技n");
  2256. }break;
  2257. case SKILL_SS_InitiativeNpcState:
  2258. {
  2259. strcat(pszMsg, "主动辅助武功n");
  2260. if (pTempSkill->m_StateAttribs[0].nValue[1] > 0)
  2261. {
  2262. sprintf (szTemp, "状态持续时间:%dn" ,pTempSkill->m_StateAttribs[0].nValue[1]);
  2263. strcat(pszMsg,szTemp);
  2264. }
  2265. }break; // 主动类 本技能用于改变当前Npc的主动状态
  2266. case SKILL_SS_PassivityNpcState:
  2267. {
  2268. strcat(pszMsg, "被动辅助武功n");
  2269. }break; // 被动类 本技能用于改变Npc的被动状态
  2270. case SKILL_SS_CreateNpc:{}break; // 产生Npc类 本技能用于生成一个新的Npc
  2271. case SKILL_SS_BuildPoison:{}break; // 炼毒类 本技能用于炼毒
  2272. case SKILL_SS_AddPoison:{}break; // 加毒类 本技能用于给武器加毒性
  2273. case SKILL_SS_GetObjDirectly:{}break; // 取物类 本技能用于隔空取物
  2274. case SKILL_SS_StrideObstacle :{}break; // 跨越类 本技能用于跨越障碍
  2275. case SKILL_SS_BodyToObject:{}break; // 变物类 本技能用于将尸体变成宝箱
  2276. case SKILL_SS_Mining:{}break; // 采矿类 本技能用于采矿随机生成矿石
  2277. case SKILL_SS_RepairWeapon:{}break; // 修复类 本技能用于修复装备
  2278. case SKILL_SS_Capture:{}break; // 捕捉类 本技能用于捕捉动物Npc
  2279. }
  2280. if (g_MisslesLib[pTempSkill->m_nChildSkillId].m_bRangeDamage) strcat(pszMsg, "区域伤害 ");
  2281. switch(g_MisslesLib[pTempSkill->m_nChildSkillId].m_eMoveKind)
  2282. {
  2283. case MISSLE_MMK_Stand:
  2284. {
  2285. strcat(pszMsg, "原地 ");
  2286. }break; // 原地
  2287. case MISSLE_MMK_Line:
  2288. {
  2289. strcat(pszMsg, "直线飞行 ");
  2290. }break; // 直线飞行
  2291. case MISSLE_MMK_Random:{}break; // 随机飞行(暗黑二女巫的Charged Bolt)
  2292. case MISSLE_MMK_Circle:
  2293. {
  2294. strcat(pszMsg, "环形飞行 ");
  2295. }break; // 环行飞行(围绕在身边,暗黑二刺客的集气)
  2296. case MISSLE_MMK_Helix:
  2297. {
  2298. strcat(pszMsg, "环形飞行 ");
  2299. }break; // 阿基米德螺旋线(暗黑二游侠的Bless Hammer)
  2300. case MISSLE_MMK_Follow:{}break; // 跟踪目标飞行
  2301. case MISSLE_MMK_Motion:{}break; // 玩家动作类
  2302. case MISSLE_MMK_Parabola:
  2303. {
  2304. strcat(pszMsg, "抛物飞行 ");
  2305. }break; // 抛物线
  2306. case MISSLE_MMK_SingleLine:{}break; // 必中的单一直线飞行魔法
  2307. }
  2308. if (!g_MisslesLib[pTempSkill->m_nChildSkillId].m_bCollideVanish)
  2309. strcat(pszMsg, "穿透 ");
  2310. if (g_MisslesLib[pTempSkill->m_nChildSkillId].m_nDamageRange > 1) 
  2311. {
  2312. sprintf(szTemp, "伤害范围:%d ", g_MisslesLib[pTempSkill->m_nChildSkillId].m_nDamageRange);
  2313. strcat(pszMsg, szTemp);
  2314. }
  2315. if (g_MisslesLib[pTempSkill->m_nChildSkillId].m_nKnockBack)
  2316. {
  2317. sprintf(szTemp, "震退距离:%d ", g_MisslesLib[pTempSkill->m_nChildSkillId].m_nKnockBack);
  2318. strcat(pszMsg, szTemp);
  2319. }
  2320. if (g_MisslesLib[pTempSkill->m_nChildSkillId].m_bAutoExplode)
  2321. {
  2322. strcat(pszMsg, "消亡自爆 ");
  2323. }
  2324. if (pTempSkill->m_bIsAura) strcat(pszMsg, "光环 ");
  2325. if (pTempSkill->m_bIsPhysical) strcat(pszMsg, "物理 ");
  2326. if (pTempSkill->m_bIsMelee) strcat(pszMsg, "近身 ");
  2327. if (pTempSkill->m_bTargetOnly) strcat(pszMsg, "必中 ");
  2328. if (pTempSkill->m_bTargetAlly) strcat(pszMsg, "对友 ");
  2329. if (pTempSkill->m_bTargetEnemy) strcat(pszMsg, "对敌 ");
  2330. if (pTempSkill->m_bTargetObj)   strcat(pszMsg, "对物 ");
  2331. if (pTempSkill->m_bTargetSelf) strcat(pszMsg, "对已 ");
  2332. if (pTempSkill->m_bUseAttackRate) strcat(pszMsg, "考虑命中率 ");
  2333. #endif
  2334. strcat (pszMsg, "n");
  2335. strcat(pszMsg, pTempSkill->m_szSkillDesc);
  2336. strcat(pszMsg, "nn");
  2337. if (!pTempSkill->IsPhysical())
  2338. {
  2339. sprintf(szTemp, "当前等级:%d", ulCurLevel);
  2340. strcat(pszMsg, szTemp);
  2341. strcat(pszMsg, "n");
  2342. }
  2343. int i = 0;
  2344. if (pCurSkill)
  2345. {
  2346. pCurSkill->GetDescAboutLevel(pszMsg);
  2347. }
  2348. if (pTempSkill->m_nHorseLimited)
  2349. {
  2350. switch(pTempSkill->m_nHorseLimited)
  2351. {
  2352. case 1:
  2353. {
  2354. strcat(pszMsg, "骑马中不能施展n");
  2355. }
  2356. break;
  2357. case 2:
  2358. {
  2359. strcat(pszMsg, "必须骑马施展n");
  2360. }
  2361. break;
  2362. default:
  2363. return ;
  2364. }
  2365. }
  2366. if (!pTempSkill->IsPhysical())
  2367. {
  2368. if (bGetNextLevelDesc)
  2369. {
  2370. if (pNextSkill)
  2371. {
  2372. strcat(pszMsg, "n<color=Red>下一级n");
  2373. pNextSkill->GetDescAboutLevel(pszMsg);
  2374. }
  2375. else
  2376. {
  2377. }
  2378. }
  2379. }
  2380. }
  2381. void KSkill::GetDescAboutLevel(char * pszMsg)
  2382. {
  2383. char szTemp[100];
  2384. int nGetCost = GetSkillCost(NULL);
  2385. if (nGetCost)
  2386. {
  2387. switch(m_nSkillCostType)
  2388. {
  2389. case attrib_mana:
  2390. sprintf(szTemp, "内力消耗:%dn", nGetCost);
  2391. strcat(pszMsg,szTemp);
  2392. break;
  2393. case attrib_stamina:
  2394. sprintf(szTemp, "体力消耗:%dn", nGetCost);
  2395. strcat(pszMsg,szTemp);
  2396. break;
  2397. case attrib_life:
  2398. sprintf(szTemp, "生命消耗:%dn", nGetCost);
  2399. strcat(pszMsg,szTemp);
  2400. break;
  2401. }
  2402. }
  2403. int nGetAttackRadius = GetAttackRadius();
  2404. if (nGetAttackRadius)
  2405. {
  2406. sprintf(szTemp,"有效距离:%dn", nGetAttackRadius);
  2407. strcat(pszMsg,szTemp);
  2408. }
  2409. //不随等级变化的立即伤害
  2410. for (int i  = 0; i < m_nImmediateAttribsNum; i ++)
  2411. {
  2412. if (!m_ImmediateAttribs[i].nAttribType) continue;
  2413. char * pszInfo = (char *)g_MagicDesc.GetDesc(&m_ImmediateAttribs[i]);
  2414. if (!pszInfo) continue;
  2415. strcat(pszMsg, pszInfo);
  2416. strcat(pszMsg, "n");
  2417. }
  2418. //子弹随玩家属性计算而成的伤害
  2419. //KMagicAttrib *DamageAttribs[MAX_MISSLE_DAMAGEATTRIB];
  2420. KMagicAttrib *DamageAttribs = m_DamageAttribs;
  2421. //根据玩家的基本属性,确定子弹的伤害
  2422. //Npc[nOwnerIndex].AppendSkillEffect(m_DamageAttribs, DamageAttribs);
  2423. for (i  = 0; i < MAX_MISSLE_DAMAGEATTRIB; i ++)
  2424. {
  2425. if (!(DamageAttribs + i)->nAttribType) continue;
  2426. char * pszInfo = (char *)g_MagicDesc.GetDesc((DamageAttribs + i));
  2427. if (!pszInfo) continue;
  2428. strcat(pszMsg, pszInfo);
  2429. strcat(pszMsg, "n");
  2430. }
  2431. //状态技能效果
  2432. for (i  = 0; i < m_nStateAttribsNum; i ++)
  2433. {
  2434. if (!m_StateAttribs[i].nAttribType) continue;
  2435. char * pszInfo = (char *)g_MagicDesc.GetDesc(&m_StateAttribs[i]);
  2436. if (!pszInfo) continue;
  2437. strcat(pszMsg, pszInfo);
  2438. strcat(pszMsg, "n");
  2439. }
  2440. }
  2441. void KSkill::PlayPreCastSound(BOOL bIsFeMale, int nX, int nY)  const 
  2442. {
  2443. char * pSoundFile = NULL;
  2444. if (!bIsFeMale)
  2445. pSoundFile = (char *)m_szManPreCastSoundFile;
  2446. else 
  2447. pSoundFile = (char *)m_szFMPreCastSoundFile;
  2448. int nCenterX = 0, nCenterY = 0, nCenterZ = 0;
  2449. // 获得屏幕中心点的地图坐标 not end
  2450. g_ScenePlace.GetFocusPosition(nCenterX, nCenterY, nCenterZ);
  2451. KCacheNode * pSoundNode = NULL;
  2452. pSoundNode = (KCacheNode*) g_SoundCache.GetNode(pSoundFile, (KCacheNode*)pSoundNode);
  2453. KWavSound * pWave = (KWavSound*)pSoundNode->m_lpData;
  2454. if (pWave)
  2455. {
  2456. pWave->Play((nX - nCenterX) * 5, (10000 - (abs(nX - nCenterX) + abs(nY - nCenterY))) * Option.GetSndVolume() / 100 - 10000, 0);
  2457. }
  2458. }
  2459. #endif