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

模拟服务器

开发平台:

C/C++

  1. // -------------------------------------------------------------------------
  2. // 文件名 : UiSkillTree.cpp
  3. // 创建者 : 吕桂华
  4. // 创建时间 : 2002-9-16 9:47:24
  5. // 功能描述 :
  6. // -------------------------------------------------------------------------
  7. #include "KWin32.h"
  8. #include "KIniFile.h"
  9. #include "../Elem/WndMessage.h"
  10. #include "../elem/wnds.h"
  11. #include "../Elem/MouseHover.h"
  12. #include "uiskilltree.h"
  13. #include "../UiBase.h"
  14. #include "../ShortcutKey.h"
  15. #include "../UiSoundSetting.h"
  16. #include "../../../core/src/coreshell.h"
  17. #include "../../../core/src/CoreObjGenreDef.h"
  18. #include "../../../Represent/iRepresent/iRepresentShell.h"
  19. extern iCoreShell* g_pCoreShell;
  20. extern iRepresentShell* g_pRepresentShell;
  21. #define SCHEME_INI "技能选择树.ini"
  22. #define SKILLTREE_SHORTCUT_SKILL_SAVE "ShortSkill"
  23. #define IS_LEFT_SKILL nLevel
  24. KUiSkillTree* KUiSkillTree::m_pSelf = NULL;
  25. KUiSkillData KUiSkillTree::ms_ShortcutSkills[SKILLTREE_SHORTCUT_SKILL_COUNT];
  26. KUiSkillTree::KUiSkillTree()
  27. {
  28. m_nNumSkills = 0;
  29. m_bLeft = true;
  30. m_nFont = 12;
  31. }
  32. //--------------------------------------------------------------------------
  33. // 功能:如果窗口正被显示,则返回实例指针
  34. //--------------------------------------------------------------------------
  35. KUiSkillTree* KUiSkillTree::GetIfVisible()
  36. {
  37. if (m_pSelf && m_pSelf->IsVisible())
  38. return m_pSelf;
  39. return NULL;
  40. }
  41. //--------------------------------------------------------------------------
  42. // 功能:打开窗口,返回唯一的一个类对象实例
  43. //--------------------------------------------------------------------------
  44. KUiSkillTree* KUiSkillTree::OpenWindow(int bLeft)
  45. {
  46. if (m_pSelf == NULL)
  47. {
  48. m_pSelf = new KUiSkillTree;
  49. if (m_pSelf)
  50. m_pSelf->Initialize();
  51. }
  52. if (m_pSelf)
  53. {
  54. Wnd_SetCapture(m_pSelf);
  55. UiSoundPlay(UI_SI_WND_OPENCLOSE);
  56. m_pSelf->m_bLeft = !!bLeft;
  57. m_pSelf->UpdateData();
  58. m_pSelf->Show();
  59. m_pSelf->BringToTop();
  60. }
  61. return m_pSelf;
  62. }
  63. //--------------------------------------------------------------------------
  64. // 功能:关闭窗口,同时可以选则是否删除对象实例
  65. //--------------------------------------------------------------------------
  66. void KUiSkillTree::CloseWindow(bool bDestroy)
  67. {
  68. if (m_pSelf)
  69. {
  70. m_pSelf->Hide();
  71. if (bDestroy)
  72. {
  73. m_pSelf->Destroy();
  74. m_pSelf = NULL;
  75. }
  76. }
  77. }
  78. //隐藏窗口
  79. void KUiSkillTree::Hide()
  80. {
  81. Wnd_ReleaseCapture();
  82. KWndWindow::Hide();
  83. }
  84. void KUiSkillTree::LoadConfig(KIniFile* pIni)
  85. {
  86. memset(&ms_ShortcutSkills, 0, sizeof(ms_ShortcutSkills));
  87. if (pIni == NULL)
  88. return;
  89. int i, j;
  90. bool bEncounter = false;
  91. char szShortcutName[32];
  92. for (i = 0; i < SKILLTREE_SHORTCUT_SKILL_COUNT; i++)
  93. {
  94. sprintf(szShortcutName, "ShortcutSkill_%d", i);
  95. pIni->GetStruct(SKILLTREE_SHORTCUT_SKILL_SAVE, szShortcutName,
  96. &ms_ShortcutSkills[i], sizeof(KUiSkillData));
  97. if (ms_ShortcutSkills[i].uGenre != CGOG_NOTHING)
  98. {
  99. ms_ShortcutSkills[i].IS_LEFT_SKILL = !!ms_ShortcutSkills[i].IS_LEFT_SKILL;
  100. for (j = 0; j < i; j++)
  101. {
  102. if (ms_ShortcutSkills[i].uId == ms_ShortcutSkills[j].uId &&
  103. ms_ShortcutSkills[i].uGenre == ms_ShortcutSkills[j].uGenre &&
  104. ms_ShortcutSkills[i].IS_LEFT_SKILL == ms_ShortcutSkills[j].IS_LEFT_SKILL)
  105. {
  106. ms_ShortcutSkills[i].uGenre = CGOG_NOTHING;
  107. ms_ShortcutSkills[i].uId = 0;
  108. }
  109. }
  110. bEncounter = true;
  111. }
  112. }
  113. bool bLeft = false;
  114. do
  115. {
  116. bLeft = !bLeft;
  117. KUiSkillData Skills[SKILLTREE_MAX_SKILL_COUNT];
  118. int nNum = g_pCoreShell->GetGameData(
  119. bLeft ? GDI_LEFT_ENABLE_SKILLS : GDI_RIGHT_ENABLE_SKILLS, (unsigned int)&Skills, 0);
  120. if (bEncounter)
  121. {
  122. for (i = 0; i < SKILLTREE_SHORTCUT_SKILL_COUNT; i++)
  123. {
  124. if (ms_ShortcutSkills[i].uGenre == CGOG_NOTHING ||
  125. (!bLeft) != (!ms_ShortcutSkills[i].IS_LEFT_SKILL))
  126. continue;
  127. for (j = 0; j < nNum; j++)
  128. {
  129. if (ms_ShortcutSkills[i].uId == Skills[j].uId &&
  130. ms_ShortcutSkills[i].uGenre == Skills[j].uGenre)
  131. {
  132. break;
  133. }
  134. }
  135. if (j >= nNum)
  136. ms_ShortcutSkills[i].uGenre = CGOG_NOTHING;
  137. }
  138. }
  139. KUiGameObject Skill;
  140. memset(&Skill, 0, sizeof(Skill));
  141. pIni->GetStruct("Player", bLeft ? "LeftSkill" : "RightSkill",
  142. &Skill, sizeof(KUiGameObject));
  143. if (Skill.uGenre != CGOG_NOTHING && g_pCoreShell)
  144. {
  145. for (i = 0; i < nNum; i++)
  146. {
  147. if (Skills[i].uId == Skill.uId &&
  148. Skills[i].uGenre == Skill.uGenre)
  149. {
  150. g_pCoreShell->OperationRequest(GOI_SET_IMMDIA_SKILL,
  151. (unsigned int)&Skill, bLeft ? 0 : 1);
  152. break;
  153. }
  154. }
  155. }
  156. }while(bLeft);
  157. }
  158. //保存自定义配置
  159. void KUiSkillTree::SaveConfig(KIniFile* pIni)
  160. {
  161. if (pIni == NULL)
  162. return;
  163. char szShortcutName[32];
  164. for (int i = 0; i < SKILLTREE_SHORTCUT_SKILL_COUNT; i++)
  165. {
  166. sprintf(szShortcutName, "ShortcutSkill_%d", i);
  167. if (ms_ShortcutSkills[i].uGenre != CGOG_NOTHING)
  168. {
  169. pIni->WriteStruct(SKILLTREE_SHORTCUT_SKILL_SAVE, szShortcutName,
  170. &ms_ShortcutSkills[i], sizeof(KUiSkillData));
  171. }
  172. else
  173. {
  174. pIni->EraseKey(SKILLTREE_SHORTCUT_SKILL_SAVE, szShortcutName);
  175. }
  176. }
  177. if(g_pCoreShell)
  178. {
  179. //记录玩家左右键技能
  180.     KUiPlayerImmedItemSkill Skill;
  181. g_pCoreShell->GetGameData(GDI_PLAYER_IMMED_ITEMSKILL, (unsigned int)&Skill, 0);
  182. if (Skill.IMmediaSkill[0].uGenre != CGOG_NOTHING)
  183. pIni->WriteStruct("Player", "LeftSkill", &Skill.IMmediaSkill[0], sizeof(KUiGameObject));
  184. else
  185. pIni->EraseKey("Player", "LeftSkill");
  186. if (Skill.IMmediaSkill[1].uGenre != CGOG_NOTHING)
  187. pIni->WriteStruct("Player", "RightSkill", &Skill.IMmediaSkill[1], sizeof(KUiGameObject));
  188. else
  189. pIni->EraseKey("Player", "RightSkill");
  190. }
  191. }
  192. // -------------------------------------------------------------------------
  193. // 功能 : 初始化
  194. // -------------------------------------------------------------------------
  195. void KUiSkillTree::Initialize()
  196. {
  197. char Scheme[256];
  198. g_UiBase.GetCurSchemePath(Scheme, 256);
  199. LoadScheme(Scheme);
  200. Wnd_AddWindow(this, WL_TOPMOST);
  201. }
  202. void KUiSkillTree::UpdateWndRect()
  203. {
  204. int nNumRow = 0, nNumColu = 0, nMaxColu = 0;
  205. int nCurRowIndex = -1;
  206. for (int i = 0; i < m_nNumSkills; i++)
  207. {
  208. if (m_Skills[i].nLevel == nCurRowIndex)
  209. nNumColu ++;
  210. else
  211. {
  212. nNumRow++;
  213. if (nNumColu > nMaxColu)
  214. nMaxColu = nNumColu;
  215. nNumColu = 1;
  216. nCurRowIndex = m_Skills[i].nLevel;
  217. }
  218. }
  219. if (nNumColu > nMaxColu)
  220. nMaxColu = nNumColu;
  221. int nWidth = m_nWidthPerSkill * nMaxColu;
  222. int nHeight = m_nHeightPerSkill * nNumRow;
  223. int nLeft, nTop;
  224. // if (m_bLeft)
  225. // {
  226. // nLeft = m_nLeftLeft;
  227. // nTop = m_nLeftTop + m_nHeightPerSkill - nHeight;
  228. // }
  229. // else
  230. {
  231. nLeft = m_nRightLeft + m_nWidthPerSkill - nWidth;
  232. nTop = m_nRightTop + m_nHeightPerSkill - nHeight;
  233. }
  234. SetPosition(nLeft, nTop);
  235. SetSize(nWidth, nHeight);
  236. }
  237. // -------------------------------------------------------------------------
  238. // 功能 : 更新数据
  239. // -------------------------------------------------------------------------
  240. void KUiSkillTree::UpdateData()
  241. {
  242. m_nNumSkills = g_pCoreShell->GetGameData(
  243. m_bLeft ? GDI_LEFT_ENABLE_SKILLS : GDI_RIGHT_ENABLE_SKILLS, (unsigned int)&m_Skills, 0);
  244. for (int i = 0; i < SKILLTREE_SHORTCUT_SKILL_COUNT; i++)
  245. {
  246. if (ms_ShortcutSkills[i].uGenre == CGOG_NOTHING ||
  247. (!m_bLeft) != (!ms_ShortcutSkills[i].IS_LEFT_SKILL))
  248. continue;
  249. for (int j = 0; j < m_nNumSkills; j++)
  250. {
  251. if (ms_ShortcutSkills[i].uId == m_Skills[j].uId &&
  252. ms_ShortcutSkills[i].uGenre == m_Skills[j].uGenre)
  253. {
  254. break;
  255. }
  256. }
  257. if (j >= m_nNumSkills)
  258. ms_ShortcutSkills[i].uGenre = CGOG_NOTHING;
  259. }
  260. UpdateWndRect();
  261. }
  262. int KUiSkillTree::PtInWindow(int x, int y)
  263. {
  264. if (KWndWindow::PtInWindow(x, y))
  265. return (GetSkillAtPos(x, y) >= 0);
  266. return 0;
  267. }
  268. //得到指定位置的技能的索引,返回小于0的值表示指定的位置上没有技能
  269. int KUiSkillTree::GetSkillAtPos(int x, int y)
  270. {
  271. int nMaxColu = m_Width / m_nWidthPerSkill;
  272. int nRow = (y - m_nAbsoluteTop) / m_nHeightPerSkill;
  273. int nColu, nIndex;
  274. // if (m_bLeft)
  275. // nColu = (x - m_nAbsoluteLeft) / m_nWidthPerSkill;
  276. // else
  277. nColu = nMaxColu - 1 - (x - m_nAbsoluteLeft) / m_nWidthPerSkill;
  278. nIndex = 0;
  279. while (nIndex < m_nNumSkills && m_Skills[nIndex].nLevel < nRow)
  280. nIndex ++;
  281. int nNumColu = 0;
  282. while(nIndex < m_nNumSkills && m_Skills[nIndex].nLevel == nRow)
  283. {
  284. if (nNumColu == nColu)
  285. return nIndex;
  286. nIndex++;
  287. nNumColu ++;
  288. }
  289. return -1;
  290. }
  291. // -------------------------------------------------------------------------
  292. // 功能 : 载入界面方案
  293. // -------------------------------------------------------------------------
  294. void KUiSkillTree::LoadScheme(const char* pScheme)
  295. {
  296. char Buff[128];
  297. KIniFile Ini;
  298. sprintf(Buff, "%s\%s", pScheme, SCHEME_INI);
  299. if (m_pSelf && Ini.Load(Buff))
  300. {
  301. Ini.GetInteger2("Main", "LeftBtnPos", &m_pSelf->m_nLeftLeft, &m_pSelf->m_nLeftTop);
  302. Ini.GetInteger2("Main", "RightBtnPos", &m_pSelf->m_nRightLeft, &m_pSelf->m_nRightTop);
  303. Ini.GetInteger2("Main", "BtnSize", &m_pSelf->m_nWidthPerSkill, &m_pSelf->m_nHeightPerSkill);
  304. if (m_pSelf->m_nWidthPerSkill < 0)
  305. m_pSelf->m_nWidthPerSkill = 1;
  306. if (m_pSelf->m_nHeightPerSkill <= 0)
  307. m_pSelf->m_nHeightPerSkill = 1;
  308. Ini.GetInteger("Main", "KeyFont", 12, &m_pSelf->m_nFont);
  309. Ini.GetString("Main", "KeyColor", "", Buff, sizeof(Buff));
  310. m_pSelf->m_uColor = GetColor(Buff);
  311. m_pSelf->UpdateWndRect();
  312. }
  313. }
  314. // -------------------------------------------------------------------------
  315. // 函数 : KUiSkillTree::WndProc
  316. // 功能 : 窗口函数
  317. // -------------------------------------------------------------------------
  318. int KUiSkillTree::WndProc(unsigned int uMsg, unsigned int uParam, int nParam)
  319. {
  320. int x, y, nIndex;
  321. int nRet = 0;
  322. switch(uMsg)
  323. {
  324. case WM_LBUTTONDOWN:
  325. x = LOWORD(nParam);
  326. y = HIWORD(nParam);
  327. if ((nIndex = GetSkillAtPos(x, y)) >= 0)
  328. {
  329. KUiGameObject Skill;
  330. Skill.uGenre = m_Skills[nIndex].uGenre;
  331. Skill.uId = m_Skills[nIndex].uId;
  332. g_pCoreShell->OperationRequest(GOI_SET_IMMDIA_SKILL,
  333. (unsigned int)&Skill, m_bLeft ? 0 : 1);
  334. }
  335. Hide();
  336. break;
  337. case WM_KEYDOWN:
  338. if (uParam == VK_ESCAPE)
  339. {
  340. Hide();
  341. nRet = 1;
  342. }
  343. case WM_MOUSEHOVER:
  344. {
  345. int x = LOWORD(nParam);
  346. int y = HIWORD(nParam);
  347. int nSkill = GetSkillAtPos(x, y);
  348. if (nSkill >= 0)
  349. {
  350. if (g_MouseOver.IsMoseHoverWndObj(this, nSkill) == 0)
  351. {
  352. SetMouseHoverObjectDesc(this, nSkill, m_Skills[nSkill].uGenre,
  353. m_Skills[nSkill].uId, UOC_SKILL_TREE, x, y);
  354. }
  355. }
  356. else
  357. g_MouseOver.CancelMouseHoverInfo();
  358. }
  359. break;
  360. case WM_RBUTTONDOWN:
  361. Hide();
  362. break;
  363. default:
  364. nRet = KWndWindow::WndProc(uMsg, uParam, nParam);
  365. }
  366. return nRet;
  367. }
  368. void KUiSkillTree::HandleShortcutKey(int nIndex)
  369. {
  370. if (m_pSelf == NULL || nIndex < 0 || nIndex >= SKILLTREE_SHORTCUT_SKILL_COUNT)
  371. return;
  372. if (GetIfVisible())
  373. {
  374. int x, y;
  375. Wnd_GetCursorPos(&x, &y);
  376. int nSkill = m_pSelf->GetSkillAtPos(x, y);
  377. if (nSkill < 0)
  378. return;
  379. ms_ShortcutSkills[nIndex].uGenre = m_pSelf->m_Skills[nSkill].uGenre;
  380. ms_ShortcutSkills[nIndex].uId = m_pSelf->m_Skills[nSkill].uId;
  381. ms_ShortcutSkills[nIndex].IS_LEFT_SKILL = m_pSelf->m_bLeft;
  382. for (int i = 0; i < SKILLTREE_SHORTCUT_SKILL_COUNT; i++)
  383. {
  384. if (i != nIndex)
  385. {
  386. if (ms_ShortcutSkills[nIndex].uId == ms_ShortcutSkills[i].uId &&
  387. ms_ShortcutSkills[nIndex].IS_LEFT_SKILL == ms_ShortcutSkills[i].IS_LEFT_SKILL &&
  388. ms_ShortcutSkills[nIndex].uGenre == ms_ShortcutSkills[i].uGenre)
  389. {
  390. ms_ShortcutSkills[i].uGenre = CGOG_NOTHING;
  391. ms_ShortcutSkills[i].uId = 0;
  392. }
  393. }
  394. }
  395. }
  396. else if (ms_ShortcutSkills[nIndex].uGenre != CGOG_NOTHING)
  397. {
  398. g_pCoreShell->OperationRequest(GOI_SET_IMMDIA_SKILL,
  399. (unsigned int)&ms_ShortcutSkills[nIndex],
  400. ms_ShortcutSkills[nIndex].IS_LEFT_SKILL ? 0 : 1);
  401. }
  402. }
  403. void KUiSkillTree::DirectHandleShortcutKey(int nIndex)
  404. {
  405. if (nIndex < 0 || nIndex >= SKILLTREE_SHORTCUT_SKILL_COUNT)
  406. return;
  407. int x, y;
  408. Wnd_GetCursorPos(&x, &y);
  409. if (GetIfVisible())
  410. {
  411. int nSkill = m_pSelf->GetSkillAtPos(x, y);
  412. if (nSkill < 0)
  413. return;
  414. ms_ShortcutSkills[nIndex].uGenre = m_pSelf->m_Skills[nSkill].uGenre;
  415. ms_ShortcutSkills[nIndex].uId = m_pSelf->m_Skills[nSkill].uId;
  416. ms_ShortcutSkills[nIndex].IS_LEFT_SKILL = m_pSelf->m_bLeft;
  417. for (int i = 0; i < SKILLTREE_SHORTCUT_SKILL_COUNT; i++)
  418. {
  419. if (i != nIndex)
  420. {
  421. if (ms_ShortcutSkills[nIndex].uId == ms_ShortcutSkills[i].uId &&
  422. ms_ShortcutSkills[nIndex].IS_LEFT_SKILL == ms_ShortcutSkills[i].IS_LEFT_SKILL &&
  423. ms_ShortcutSkills[nIndex].uGenre == ms_ShortcutSkills[i].uGenre)
  424. {
  425. ms_ShortcutSkills[i].uGenre = CGOG_NOTHING;
  426. ms_ShortcutSkills[i].uId = 0;
  427. }
  428. }
  429. }
  430. }
  431. else if (ms_ShortcutSkills[nIndex].uGenre != CGOG_NOTHING)
  432. {
  433. g_pCoreShell->UseSkill(x, y, ms_ShortcutSkills[nIndex].uId);
  434. }
  435. }
  436. // -------------------------------------------------------------------------
  437. // 功能 : 窗体绘制
  438. // -------------------------------------------------------------------------
  439. void KUiSkillTree::PaintWindow()
  440. {
  441. if (g_pRepresentShell == NULL)
  442. return;
  443. KWndWindow::PaintWindow();
  444. int nCurRowIndex = -1;
  445. int nLeft, nTop = m_nAbsoluteTop - m_nHeightPerSkill;
  446. int nDX = -m_nWidthPerSkill; //m_bLeft ? m_nWidthPerSkill : (-m_nWidthPerSkill);
  447. for (int i = 0; i < m_nNumSkills; i++)
  448. {
  449. if (m_Skills[i].nLevel == nCurRowIndex)
  450. {
  451. nLeft += nDX;
  452. }
  453. else
  454. {
  455. nTop += m_nHeightPerSkill;
  456. // if (m_bLeft)
  457. // nLeft = m_nAbsoluteLeft;
  458. // else
  459. nLeft = m_nAbsoluteLeft + m_Width - m_nWidthPerSkill;
  460. nCurRowIndex = m_Skills[i].nLevel;
  461. }
  462. g_pCoreShell->DrawGameObj(m_Skills[i].uGenre, m_Skills[i].uId,
  463. nLeft, nTop, m_nWidthPerSkill, m_nHeightPerSkill, 0);
  464. for (int j = 0; j < SKILLTREE_SHORTCUT_SKILL_COUNT; j++)
  465. {
  466. if (m_bLeft == (unsigned)ms_ShortcutSkills[j].IS_LEFT_SKILL &&
  467. m_Skills[i].uGenre == ms_ShortcutSkills[j].uGenre &&
  468. m_Skills[i].uId == ms_ShortcutSkills[j].uId)
  469. {
  470. char szScript[64];
  471. sprintf(szScript, SCK_SHORTCUTSKILL_FORMAT, j);
  472. int nIndexC = KShortcutKeyCentre::FindCommandByScript(szScript);
  473. char* pszKey = NULL;
  474. if (nIndexC >= 0)
  475. {
  476. pszKey = (char*)KShortcutKeyCentre::GetKeyName(KShortcutKeyCentre::GetCommandKey(nIndexC));
  477. }
  478. else
  479. {
  480. sprintf(szScript, SCK_DIRECTSHORTCUTSKILL_FORMAT, j);
  481. nIndexC = KShortcutKeyCentre::FindCommandByScript(szScript);
  482. if (nIndexC >= 0)
  483. {
  484. pszKey = (char*)KShortcutKeyCentre::GetKeyName(KShortcutKeyCentre::GetCommandKey(nIndexC));
  485. }
  486. }
  487. if (pszKey)
  488. {
  489. g_pRepresentShell->OutputText(m_nFont, pszKey, KRF_ZERO_END,
  490. nLeft + m_nWidthPerSkill - m_nFont, nTop + m_nHeightPerSkill - m_nFont - 1, m_uColor);
  491. break;
  492. }
  493. }
  494. }
  495. }
  496. }