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

模拟服务器

开发平台:

C/C++

  1. //---------------------------------------------------------------------------
  2. // Sword3 Core (c) 2002 by Kingsoft
  3. //
  4. // File: KItemGenerator.CPP
  5. // Date: 2002.08.26
  6. // Code: DongBo
  7. // Desc:    CPP file. 本文件实现的类用于生成道具
  8. //---------------------------------------------------------------------------
  9. #include "KEngine.h"
  10. #include "KCore.h"
  11. #include "MyAssert.H"
  12. #include "KItem.h"
  13. #include "KSubWorldSet.h"
  14. #include "KItemGenerator.h"
  15. KItemGenerator ItemGen; // 装备生成器
  16. KItemGenerator::KItemGenerator()
  17. {
  18. }
  19. KItemGenerator::~KItemGenerator()
  20. {
  21. }
  22. /******************************************************************************
  23. 功能: 数据初始化. 从tab file中读取数据
  24. ******************************************************************************/
  25. BOOL KItemGenerator::Init()
  26. {
  27. if (!m_BPTLib.Init()) // 此调用从若干的tab file中载入所有的初始属性
  28. return FALSE;
  29. for (int i = equip_meleeweapon; i < equip_detailnum - equip_meleeweapon; i++)
  30. {
  31. switch(i)
  32. {
  33. case equip_meleeweapon:
  34. m_EquipNumOfEntries[i] = m_BPTLib.GetMeleeWeaponRecordNumber();
  35. break;
  36. case equip_rangeweapon:
  37. m_EquipNumOfEntries[i] = m_BPTLib.GetRangeWeaponRecordNumber();
  38. break;
  39. case equip_armor:
  40. m_EquipNumOfEntries[i] = m_BPTLib.GetArmorRecordNumber();
  41. break;
  42. case equip_helm:
  43. m_EquipNumOfEntries[i] = m_BPTLib.GetHelmRecordNumber();
  44. break;
  45. case equip_boots:
  46. m_EquipNumOfEntries[i] = m_BPTLib.GetBootRecordNumber();
  47. break;
  48. case equip_belt:
  49. m_EquipNumOfEntries[i] = m_BPTLib.GetBeltRecordNumber();
  50. break;
  51. case equip_cuff:
  52. m_EquipNumOfEntries[i] = m_BPTLib.GetCuffRecordNumber();
  53. break;
  54. case equip_amulet:
  55. m_EquipNumOfEntries[i] = m_BPTLib.GetAmuletRecordNumber();
  56. break;
  57. case equip_ring:
  58. m_EquipNumOfEntries[i] = m_BPTLib.GetRingRecordNumber();
  59. break;
  60. case equip_pendant:
  61. m_EquipNumOfEntries[i] = m_BPTLib.GetPendantRecordNumber();
  62. break;
  63. case equip_horse:
  64. m_EquipNumOfEntries[i] = m_BPTLib.GetHorseRecordNumber();
  65. break;
  66. }
  67. }
  68. m_MedNumOfEntries = m_BPTLib.GetMedicineRecordNumber();
  69. return TRUE;
  70. /*
  71. m_BPTLib.Init();
  72. int naryMALevel[] = {1,2,3,4,5,6};
  73. KItem theItem;
  74. Gen_Equipment(1, 1, 0, 5, naryMALevel, 45, &theItem);
  75. return TRUE;
  76. */
  77. }
  78. /******************************************************************************
  79. 功能: 生成药品
  80. 入口: nDetailType: 药品类型
  81. nLevel: 等级
  82. nVersion: 版本号
  83. 出口: 成功时返回非零, 相关数据在 pItem 所指对象中给出
  84. 失败时返回零
  85. ******************************************************************************/
  86. BOOL KItemGenerator::Gen_Medicine(IN int nDetailType,
  87.   IN int nLevel,
  88.   IN int nVersion,
  89.   IN OUT KItem* pItem)
  90. {
  91. _ASSERT(this != NULL);
  92. _ASSERT(pItem != NULL);
  93. BOOL bEC = FALSE;
  94. #ifdef _SERVER // 服务器版本
  95. pItem->m_GeneratorParam.uRandomSeed = g_GetRandomSeed();
  96. pItem->m_GeneratorParam.nVersion = g_SubWorldSet.GetGameVersion();
  97. pItem->m_GeneratorParam.nLuck = 0;
  98. #else
  99. g_RandomSeed(pItem->m_GeneratorParam.uRandomSeed);
  100. int nGameVersion = pItem->m_GeneratorParam.nVersion;
  101. #endif
  102. const int i = nDetailType * 5 + nLevel - 1; // 本公式由策划定义
  103. // 等级数据从1开始,所以要减回来
  104. const KBASICPROP_MEDICINE* pMed = NULL;
  105. pMed = m_BPTLib.GetMedicineRecord(i);
  106. if (NULL == pMed)
  107. {
  108. _ASSERT(FALSE);
  109. return bEC;
  110. }
  111. *pItem = *pMed;
  112. return TRUE;
  113. }
  114. /******************************************************************************
  115. 功能: 生成随机装备
  116. 入口: nSeriesReq: 五行属性
  117. nLevel: 等级
  118. nLucky: 运气值
  119. nVersion: 版本号
  120. 出口: 成功时返回非零, 相关数据在 pItem 所指对象中给出
  121. 失败时返回零
  122. ******************************************************************************/
  123. BOOL KItemGenerator::Gen_Item(IN int nItemGenre,
  124.   IN int nSeriesReq,
  125.   IN int nLevel,
  126.   IN int nLucky,
  127.   IN OUT KItem* pItem)
  128. {
  129. _ASSERT(this != NULL);
  130. _ASSERT(pItem != NULL);
  131. switch (nItemGenre)
  132. {
  133. case item_equip:
  134. {
  135. int nDetailType, nParticularType, i;
  136. nDetailType = g_Random(equip_detailnum);
  137. nParticularType = g_Random(m_EquipNumOfEntries[nDetailType] + 1);
  138. int naryMALevel[6];
  139. ZeroMemory(naryMALevel, 6 * sizeof(int));
  140. for (i = 0; i < 6; i++)
  141. {
  142. naryMALevel[i] = g_Random(nLevel / 10 + 1);
  143. if (!naryMALevel[i])
  144. break;
  145. }
  146. Gen_Equipment(nDetailType, nParticularType, nSeriesReq, nLevel, naryMALevel, nLucky, g_SubWorldSet.GetGameVersion(), pItem);
  147. }
  148. break;
  149. case item_medicine:
  150. {
  151. int nDetailType;
  152. nDetailType = g_Random(medicine_detailnum);
  153. Gen_Medicine(nDetailType, nLevel, g_SubWorldSet.GetGameVersion(), pItem);
  154. }
  155. break;
  156. case item_task:
  157. {
  158. Gen_Quest(nSeriesReq, pItem);
  159. }
  160. break;
  161. case item_townportal:
  162. {
  163. Gen_TownPortal(pItem);
  164. }
  165. break;
  166. default:
  167. break;
  168. }
  169. return TRUE;
  170. }
  171. /******************************************************************************
  172. 功能: 生成随机装备
  173. 入口: nDetailType: 具体类别, 如近程武器、暗器、......
  174. nParticularType: 详细类别
  175. nSeriesReq: 五行属性
  176. nLevel: 等级
  177. pnaryMALevel: 魔法属性等级数组[6]
  178. nLucky: 运气值
  179. 出口: 成功时返回非零, 相关数据在 pItem 所指对象中给出
  180. 失败时返回零
  181. ******************************************************************************/
  182. BOOL KItemGenerator::Gen_Equipment(IN int nDetailType,
  183.    IN int nParticularType,
  184.    IN int nSeriesReq,
  185.    IN int nLevel,
  186.    IN const int* pnaryMALevel,
  187.    IN int nLucky,
  188.    IN int nVersion,
  189.    IN OUT KItem* pItem)
  190. {
  191. _ASSERT(this != NULL);
  192. _ASSERT(pItem != NULL);
  193. BOOL bEC = FALSE;
  194. #ifdef _SERVER // 服务器版本
  195. pItem->m_GeneratorParam.uRandomSeed = g_GetRandomSeed();
  196. if (pnaryMALevel)
  197. memcpy(pItem->m_GeneratorParam.nGeneratorLevel, pnaryMALevel, sizeof(int) * 6);
  198. else
  199. ZeroMemory(pItem->m_GeneratorParam.nGeneratorLevel, sizeof(int) * 6);
  200. pItem->m_GeneratorParam.nVersion = g_SubWorldSet.GetGameVersion();
  201. pItem->m_GeneratorParam.nLuck = nLucky;
  202. #else
  203. g_RandomSeed(pItem->m_GeneratorParam.uRandomSeed);
  204. if (pnaryMALevel)
  205. memcpy(pItem->m_GeneratorParam.nGeneratorLevel, pnaryMALevel, sizeof(int) * 6);
  206. #endif
  207. int nGameVersion = pItem->m_GeneratorParam.nVersion;
  208. // 根据入口参数, 确定装备的基本数据
  209. const int i = nParticularType * 10 + nLevel - 1;// 本公式由策划定义
  210. // 详见SPE 2002年8月31日7:40
  211. // email: 基础道具数值表
  212. // 等级数据从1开始,所以要减回来
  213. const KBASICPROP_EQUIPMENT* pEqu = NULL;
  214. switch(nDetailType)
  215. {
  216. case equip_meleeweapon:
  217. pEqu = m_BPTLib.GetMeleeWeaponRecord(i);
  218. break;
  219. case equip_rangeweapon:
  220. pEqu = m_BPTLib.GetRangeWeaponRecord(i);
  221. break;
  222. case equip_armor:
  223. pEqu = m_BPTLib.GetArmorRecord(i);
  224. break;
  225. case equip_helm:
  226. pEqu = m_BPTLib.GetHelmRecord(i);
  227. break;
  228. case equip_boots:
  229. pEqu = m_BPTLib.GetBootRecord(i);
  230. break;
  231. case equip_belt:
  232. pEqu = m_BPTLib.GetBeltRecord(i);
  233. break;
  234. case equip_amulet:
  235. pEqu = m_BPTLib.GetAmuletRecord(i);
  236. break;
  237. case equip_ring:
  238. pEqu = m_BPTLib.GetRingRecord(i);
  239. break;
  240. case equip_cuff:
  241. pEqu = m_BPTLib.GetCuffRecord(i);
  242. break;
  243. case equip_pendant:
  244. pEqu = m_BPTLib.GetPendantRecord(i);
  245. break;
  246. case equip_horse:
  247. pEqu = m_BPTLib.GetHorseRecord(i);
  248. break;
  249. default:
  250. break;
  251. }
  252. if (NULL == pEqu)
  253. { _ASSERT(FALSE); return bEC; }
  254. // 运行至此的直接原因: 只有n种装备, 而上面 i 的值在[0,n-1]之外
  255. // 检查3点: nParticularType 有误?
  256. // nLevel 有误?
  257. // 原始的tab file有误导致 m_BPTLib.m_BPTEquipment 所
  258. // 管理的数据有问题?
  259. pItem->SetAttrib_CBR(pEqu);
  260. pItem->SetSeries(nSeriesReq);
  261. if (NULL == pnaryMALevel)
  262. return TRUE;
  263. // 确定装备的魔法属性
  264. KItemNormalAttrib sMA[6]; // 道具的魔法属性
  265. bEC = Gen_MagicAttrib(nDetailType, pnaryMALevel, nSeriesReq, nLucky, sMA, nGameVersion);
  266. if (bEC)
  267. pItem->SetAttrib_MA(sMA);
  268. return bEC;
  269. }
  270. /******************************************************************************
  271. 功能: 生成魔法属性
  272. 入口: nType: 装备类型
  273. pnaryMALevel: 数组指针, 给出魔法的等级要求, 共6个
  274. nSeriesReq: 五行属性
  275. nLucky: 运气值
  276. 出口: 在 pnaryMA 所指数组中返回魔法的属性核心数据, 共6个
  277. ******************************************************************************/
  278. // Add by Freeway Chen in 2003.5.30
  279. BOOL KItemGenerator::Gen_MagicAttrib(
  280.     int nType, const int* pnaryMALevel, int nSeriesReq, int nLucky,
  281. KItemNormalAttrib* pnaryMA, int nGameVersion
  282. )
  283. {
  284.     int nResult = false;
  285.     KBPT_ClassMAIT  SelectedMagicTable;
  286. // 记录每一个记录选中的魔法属性,主要是为了最后将使用标志清除
  287.     KMAGICATTRIB_TABFILE *pMagicAttrTable[6] = { NULL, NULL, NULL, NULL, NULL, NULL };
  288.     int i = 0;
  289.     _ASSERT(pnaryMALevel);
  290.     _ASSERT(pnaryMA);
  291.     for (i = 0; i < 6; i++) 
  292.     {
  293.         // 如果发现级别为零,表示不需要继续处理了,退出
  294.         if (pnaryMALevel[i] == 0)
  295.          break;
  296.         SelectedMagicTable.Clear();
  297.         // 根据前缀后缀、物品类型、五行需求、需求级别将所有符合条件的魔法属性项取出来
  298.         const KBPT_ClassMAIT *pCMITItem = m_BPTLib.GetCMIT(
  299.             1 - (i & 1),        // 前缀后缀
  300.             nType,              // 物品类型
  301.             nSeriesReq,         // 五行需求 
  302.             pnaryMALevel[i]     // 需求级别
  303.         );
  304.         _ASSERT(pCMITItem);
  305.         if (!pCMITItem)
  306.         {
  307.             g_DebugLog(
  308.                 "[GenMagicAttrib] GetCMIT Error, nPrefixPostfix = %d, nType = %d, nSeries = %d, nLevel = %d", 
  309.                 1 - (i & 1), nType, nSeriesReq, pnaryMALevel[i]
  310.             );
  311.             break;
  312.         }
  313.         // 遍历符合条件的魔法属性,根据
  314.         // 1.是否已经使用,
  315.         // 2.运气值
  316.         // 3.是否有相同的“属性调整类别”
  317.         // 取出相应的项放在SelectedMagicTable中
  318.         int nCMITItemCount = pCMITItem->GetCount();
  319.         int j = 0;
  320.         int nDecide = GetRandomNumber(0, 100 - 1) / (1 + nLucky * 20 / 100);
  321.         for (j = 0; j < nCMITItemCount; j++)
  322.         {
  323.             // 根据索引值,取出相应的项
  324.             int nMAIndex = pCMITItem->Get(j);
  325.             KMAGICATTRIB_TABFILE *pMAItem = (KMAGICATTRIB_TABFILE *)m_BPTLib.GetMARecord(nMAIndex);
  326.             if (!pMAItem)
  327.             {
  328.                 _ASSERT(pMAItem);
  329.                 continue;
  330.             }
  331.             // 如果已经使用,跳过取下一个
  332.             if (pMAItem->m_nUseFlag)
  333.                 continue;
  334.             // 如果运气不足,取下一个
  335.             if ((pMAItem->m_DropRate[nType]) <= nDecide)
  336.                 continue;
  337.             
  338.             // 检查是否已经有相同的“属性调整类别”
  339.             int k = 0;
  340.             for (k = 0; k < i; k++)
  341.             {
  342.                 _ASSERT(pMagicAttrTable[k]);
  343.                 if ((pMagicAttrTable[k]->m_MagicAttrib.nPropKind) == (pMAItem->m_MagicAttrib.nPropKind))
  344.                     break;
  345.             }
  346.             // 如果发现 “属性调整类别”相同,说明已经有一个相同的值被选中,那么取下一个
  347.             if (k < i)
  348.                 continue;
  349.             SelectedMagicTable.Insert(nMAIndex);
  350.         }
  351.         int nSelectedCount = SelectedMagicTable.GetCount();
  352.         if (nSelectedCount == 0)
  353.         {   
  354.             // 如果没有满足条件的魔法属性,就退出
  355.             break;
  356.         }
  357.         
  358.         // 如果发现满足条件的魔法属性,就设置
  359.         int nLuckyItemIndex = GetRandomNumber(0, nSelectedCount - 1);
  360.         KMAGICATTRIB_TABFILE *pMAItem = (KMAGICATTRIB_TABFILE *)m_BPTLib.GetMARecord(
  361.              SelectedMagicTable.Get(nLuckyItemIndex)
  362.         );
  363.         // 保存满足条件的魔法属性,以便在最后的时候将使用标志清除
  364.         pMagicAttrTable[i] = pMAItem;
  365.         _ASSERT(pMAItem);
  366.         _ASSERT(!(pMAItem->m_nUseFlag));     // 确定还没有使用
  367.         // 设置使用标志
  368.         pMAItem->m_nUseFlag = true;
  369.         pnaryMA[i].nAttribType = pMAItem->m_MagicAttrib.nPropKind;
  370.         pnaryMA[i].nValue[0] = GetRandomNumber(
  371.             pMAItem->m_MagicAttrib.aryRange[0].nMin, 
  372.             pMAItem->m_MagicAttrib.aryRange[0].nMax
  373.         );
  374.         pnaryMA[i].nValue[1] = GetRandomNumber(
  375.             pMAItem->m_MagicAttrib.aryRange[1].nMin, 
  376.             pMAItem->m_MagicAttrib.aryRange[1].nMax
  377.         );
  378.         pnaryMA[i].nValue[2] = GetRandomNumber(
  379.             pMAItem->m_MagicAttrib.aryRange[2].nMin, 
  380.             pMAItem->m_MagicAttrib.aryRange[2].nMax
  381.         );
  382. g_DebugLog(
  383. "[GenMagicAttrib] pnaryMA[%d]: (%d:%s), nAttribType = %d, nValue[0] = %d, nValue[1] = %d, nValue[2] = %d,", 
  384. i,
  385. SelectedMagicTable.Get(nLuckyItemIndex),
  386. pMAItem->m_szName,
  387. pnaryMA[i].nAttribType,
  388. pnaryMA[i].nValue[0],
  389. pnaryMA[i].nValue[1],
  390. pnaryMA[i].nValue[2]
  391. );
  392.     } // for 遍历需要取回的魔法属性表
  393.     for (NULL; i < 6; i++)
  394.     {
  395.         // 清空剩下的项
  396.         pnaryMA[i].nAttribType = 0;
  397.         pnaryMA[i].nValue[0] = 0;
  398.         pnaryMA[i].nValue[1] = 0;
  399.         pnaryMA[i].nValue[2] = 0;
  400.     }
  401.     for (i = 0; i < 6; i++)
  402.     {
  403.         if (!pMagicAttrTable[i])
  404.             break;
  405.         _ASSERT(pMagicAttrTable[i]->m_nUseFlag);   // 确定已经使用
  406.         pMagicAttrTable[i]->m_nUseFlag = false;    // 设置为没用使用
  407.     }
  408.     nResult = true;
  409. //Exit0:
  410. return nResult;
  411. }
  412. // Following Code is implement by DongBo
  413. //BOOL KItemGenerator::Gen_MagicAttrib(int nType, const int* pnaryMALevel, int nSeriesReq, int nLucky,
  414. //  KItemNormalAttrib* pnaryMA)
  415. //{
  416. //
  417. //    // 确定适用于该装备的全部魔法属性及其数量
  418. // if (FALSE == GMA_GetAvaliableMA(nType))
  419. // { _ASSERT(FALSE); return FALSE; }
  420. //
  421. // // 确定上述各魔法属性的等级,出现概率
  422. // if (FALSE == GMA_GetLevelAndDropRate(nType))
  423. // { _ASSERT(FALSE); return FALSE; }
  424. //
  425. // // 从上述魔法属性中选出符合条件的. 策划要求选出6个
  426. // for (int i = 0; i < 6; i++) // 奇数: 前缀, 偶数: 后缀
  427. // {
  428. // GMA_ChooseMA((i&1), pnaryMALevel[i], nLucky, &(pnaryMA[i]));
  429. // if (pnaryMA[i].nAttribType == 0)
  430. // break;
  431. // }
  432. // return TRUE;
  433. //}
  434. /******************************************************************************
  435. 功能: 确定适用于指定装备的全部魔法属性及其数量
  436. 入口: nType: 指定装备
  437. 出口: 成功时返回非零. m_GMA_naryMA[0]给出适用于该装备的全部魔法属性前缀
  438. m_GMA_nCount[0]给出上述魔法属性的总数
  439. m_GMA_naryMA[1]给出适用于该装备的全部魔法属性后缀
  440. m_GMA_nCount[1]给出上述魔法属性的总数
  441. 失败时返回零
  442. ******************************************************************************/
  443. BOOL KItemGenerator::GMA_GetAvaliableMA(int nType)
  444. {
  445. //TODO: 可能需要对nType进行转换, 从装备类型值变成 m_BPTLib.m_CMAT 数组的索引
  446. for (int i = 0; i < 2; i++) // 0: 前缀, 1: 后缀
  447. {
  448. const KBPT_ClassifiedMAT* pCMAT;
  449. pCMAT = m_BPTLib.GetCMAT(i, nType);
  450. if (pCMAT == NULL)
  451. { _ASSERT(FALSE); return FALSE; }
  452. m_GMA_nCount[i] = NUMOFCMA;
  453. pCMAT->GetAll((int*)m_GMA_naryMA[i], &(m_GMA_nCount[i]));
  454. }
  455. return TRUE;
  456. }
  457. /******************************************************************************
  458. 功能: 确定各给定魔法属性的等级要求和出现概率
  459. 入口: nType: 指定装备
  460. m_GMA_naryMA数组: 给出全部魔法属性的索引值
  461. 出口: 成功时返回非零. m_GMA_naryLevel数组给出上述魔法属性的等级要求
  462. m_GMA_naryDropRate给出上述魔法属性的出现概率
  463. 失败时返回零
  464. ******************************************************************************/
  465. BOOL KItemGenerator::GMA_GetLevelAndDropRate(int nType)
  466. {
  467. //TODO: 可能需要对nType进行转换, 从装备类型值变成 m_BPTLib.m_CMAT 数组的索引
  468. for (int i = 0; i < 2; i++) // 0: 前缀, 1: 后缀
  469. {
  470. for (int n = 0; n < m_GMA_nCount[i]; n++)
  471. {
  472. const KMAGICATTRIB_TABFILE* pMATF;
  473. pMATF = GetMARecord(m_GMA_naryMA[i][n]);
  474. if (pMATF == NULL)
  475. { _ASSERT(FALSE); return FALSE; }
  476. m_GMA_naryLevel[i][n] = pMATF->m_nLevel;
  477. m_GMA_naryDropRate[i][n] = pMATF->m_DropRate[nType]; // 可优化
  478. }
  479. }
  480. return TRUE;
  481. }
  482. /******************************************************************************
  483. 功能: 从全部可用的魔法属性中选出符合条件的魔法
  484. 入口: nPos: 0: 选前缀, 1: 选后缀
  485. nLevel: 对魔法属性的等级要求
  486. nLucky: 运气值
  487. m_GMA_naryMA数组: 给出全部可用的魔法属性的索引值
  488. 出口: *pINA 给出所选魔法的核心参数
  489. ******************************************************************************/
  490. void KItemGenerator::GMA_ChooseMA(int nPos, int nLevel, int nLucky, KItemNormalAttrib* pINA)
  491. {
  492. _ASSERT(pINA != NULL);
  493. // 赋初值
  494. pINA->nAttribType = 0;
  495. pINA->nValue[0] = 0;
  496. pINA->nValue[1] = 0;
  497. pINA->nValue[2] = 0;
  498. // 筛选出全部可用的魔法属性
  499. int nDropRate = ::GetRandomNumber(0, 100) - nLucky;
  500. int nCount = GMA_GetCandidateMA(nPos, nLevel, nDropRate);
  501. if (nCount > 0)
  502. {
  503. int nFinal = ::GetRandomNumber(0, nCount);
  504. int nMAi = m_GMA_naryCandidateMA[nFinal];
  505. int nMA = m_GMA_naryMA[nPos][nMAi];
  506. if (nMA == -1) // 随机出重复的属性了
  507. {
  508. pINA->nAttribType = 0;
  509. return;
  510. }
  511. m_GMA_naryMA[nPos][nMAi] = -1; // 置为-1,表示该MA已用
  512. const KMAGICATTRIB_TABFILE* pMATF = GetMARecord(nMA);
  513. if (NULL != pMATF)
  514. {
  515. const KMACP* pMACP = &(pMATF->m_MagicAttrib);
  516. pINA->nAttribType = pMACP->nPropKind;
  517. pINA->nValue[0] = ::GetRandomNumber(pMACP->aryRange[0].nMin, pMACP->aryRange[0].nMax);
  518. pINA->nValue[1] = ::GetRandomNumber(pMACP->aryRange[1].nMin, pMACP->aryRange[1].nMax);
  519. pINA->nValue[2] = ::GetRandomNumber(pMACP->aryRange[2].nMin, pMACP->aryRange[2].nMax);
  520. }
  521. }
  522. }
  523. /******************************************************************************
  524. 功能: 获取指定的魔法属性记录
  525. 入口: i: 指定记录
  526. 出口: 成功时返回指向该记录的指针
  527. 失败时返回NULL
  528. ******************************************************************************/
  529. const KMAGICATTRIB_TABFILE* KItemGenerator::GetMARecord(int i) const
  530. {
  531. return m_BPTLib.GetMARecord(i);
  532. }
  533. /******************************************************************************
  534. 功能: 从全部可用的魔法属性中选出符合条件的魔法
  535. 入口: nPos: 0: 选前缀, 1: 选后缀
  536. nLevel: 对魔法属性的等级要求
  537. nDropRate: 选出出现概率大于此值的魔法属性
  538. m_GMA_naryMA数组: 给出全部可用的魔法属性的索引值
  539. m_GMA_naryLevel数组: 给出上述魔法属性的等级要求
  540. m_GMA_naryDropRate数组: 给出上述魔法属性的出现概率
  541. 出口: m_GMA_naryCandidateMA数组给出符合条件的魔法
  542. 说明: 若 n = m_GMA_naryMA[nPos][m_GMA_naryCandidateMA[i]]
  543. 则 GetMARecord(n) 返回指向魔法属性结构的指针
  544. ******************************************************************************/
  545. int KItemGenerator::GMA_GetCandidateMA(int nPos, int nLevel, int nDropRate)
  546. {
  547. int nCount = 0;
  548. for (int i = 0; i < m_GMA_nCount[nPos]; i++)
  549. {
  550. if (m_GMA_naryMA[nPos][i] != -1 && // -1表示该MA已用过
  551. m_GMA_naryLevel[nPos][i] == nLevel &&
  552. m_GMA_naryDropRate[nPos][i] >= nDropRate)
  553. {
  554. m_GMA_naryCandidateMA[nCount++] = i;
  555. }
  556. }
  557. return nCount;
  558. }
  559. BOOL KItemGenerator::GetMedicineCommonAttrib(IN int nDetailType, IN int nLevel, IN OUT KItem* pItem)
  560. {
  561. if (NULL == pItem)
  562. {
  563. KASSERT(FALSE);
  564. return FALSE;
  565. }
  566. const int i = nDetailType * 5 + nLevel - 1;
  567. const KBASICPROP_MEDICINE* pMed = NULL;
  568. pMed = m_BPTLib.GetMedicineRecord(i);
  569. if (NULL == pMed)
  570. {
  571. _ASSERT(FALSE);
  572. return FALSE;
  573. }
  574. *pItem = *pMed;
  575. return TRUE;
  576. }
  577. /******************************************************************************
  578. 功能: 随机生成黄金装备装备
  579. 入口: nCondition: 前提条件,(Emf+Pmf)*Level的运算结果
  580. pItem: 装备项目指针。
  581. 出口: 成功时返回真, 相关数据在 pItem 所指对象中给出
  582. 失败时返回假
  583. ******************************************************************************/
  584. // Add by flying on May.30.2003
  585. // Try to get a "Gold Item" if possible.
  586. BOOL KItemGenerator::GetGoldItemByRandom(IN int nCondition, OUT KItem * pItem)
  587. {
  588. BOOL bResult = FALSE;
  589. const KBASICPROP_EQUIPMENT_GOLD* pArray[MAX_ITEM];
  590. int i = 0;
  591. int j = 0;
  592. int nIndex = 0;
  593. ::memset(pArray, 0, sizeof(KBASICPROP_EQUIPMENT_GOLD *) * MAX_ITEM);
  594. for (i = 0; i < MAX_ITEM; i++)
  595. {
  596. const KBASICPROP_EQUIPMENT_GOLD* pTemp = m_BPTLib.GetGoldItemRecord(i);
  597. if (pTemp == 0)
  598. break;
  599. if (pTemp->m_nRarity < nCondition)
  600. pArray[j] = pTemp;
  601. }
  602. if (j == 0)
  603. goto Exit0;  
  604. nIndex = GetRandomNumber(0, j);
  605. *pItem = *pArray[nIndex];
  606. Exit0:
  607. return FALSE;
  608. }
  609. /******************************************************************************
  610. 功能: 生成指定黄金装备装备
  611. 入口: nCondition: 前提条件,(Emf+Pmf)*Level的运算结果
  612. pItem: 装备项目指针。
  613. 出口: 成功时返回真, 相关数据在 pItem 所指对象中给出
  614. 失败时返回假
  615. ******************************************************************************/
  616. // Add by flying on May.30.2003
  617. // Try to get a "Gold Item" if possible.
  618. BOOL KItemGenerator::GetGoldItemByIndex(IN int nIndex, OUT KItem * pItem)
  619. {
  620. BOOL bResult = FALSE;
  621. int i = 0;
  622. int j = 0;
  623. int nCount = 0;
  624. nCount = m_BPTLib.GetGoldItemNumber();
  625. const KBASICPROP_EQUIPMENT_GOLD* pTemp = m_BPTLib.GetGoldItemRecord(i);
  626. if (nIndex >= nCount)
  627. goto Exit0;
  628. if (pTemp == NULL)
  629. goto Exit0;
  630. *pItem = *pTemp;
  631. bResult = TRUE;
  632. Exit0:
  633. return bResult;
  634. }
  635. BOOL KItemGenerator::GetEquipmentCommonAttrib(IN int nDetailType, IN int nParticularType, IN int nLevel, IN int nSeries, IN OUT KItem* pItem)
  636. {
  637. if (NULL == pItem)
  638. {
  639. KASSERT(FALSE);
  640. return FALSE;
  641. }
  642. const int i = nParticularType * 10 + nLevel - 1;// 本公式由策划定义
  643. // 详见SPE 2002年8月31日7:40
  644. // email: 基础道具数值表
  645. const KBASICPROP_EQUIPMENT* pEqu = NULL;
  646. switch(nDetailType)
  647. {
  648. case equip_meleeweapon:
  649. pEqu = m_BPTLib.GetMeleeWeaponRecord(i);
  650. break;
  651. case equip_rangeweapon:
  652. pEqu = m_BPTLib.GetRangeWeaponRecord(i);
  653. break;
  654. case equip_armor:
  655. pEqu = m_BPTLib.GetArmorRecord(i);
  656. break;
  657. case equip_helm:
  658. pEqu = m_BPTLib.GetHelmRecord(i);
  659. break;
  660. case equip_boots:
  661. pEqu = m_BPTLib.GetBootRecord(i);
  662. break;
  663. case equip_belt:
  664. pEqu = m_BPTLib.GetBeltRecord(i);
  665. break;
  666. case equip_amulet:
  667. pEqu = m_BPTLib.GetAmuletRecord(i);
  668. break;
  669. case equip_ring:
  670. pEqu = m_BPTLib.GetRingRecord(i);
  671. break;
  672. case equip_cuff:
  673. pEqu = m_BPTLib.GetCuffRecord(i);
  674. break;
  675. case equip_pendant:
  676. pEqu = m_BPTLib.GetPendantRecord(i);
  677. break;
  678. case equip_horse:
  679. pEqu = m_BPTLib.GetHorseRecord(i);
  680. break;
  681. default:
  682. break;
  683. }
  684. if (NULL == pEqu)
  685. { _ASSERT(FALSE); return FALSE; }
  686. // 运行至此的直接原因: 只有n种装备, 而上面 i 的值在[0,n-1]之外
  687. // 检查3点: nParticularType 有误?
  688. // nLevel 有误?
  689. // 原始的tab file有误导致 m_BPTLib.m_BPTEquipment 所
  690. // 管理的数据有问题?
  691. pItem->SetAttrib_CBR(pEqu);
  692. pItem->SetSeries(nSeries);
  693. return TRUE;
  694. }
  695. /******************************************************************************
  696. 功能: 生成随机装备
  697. 入口: nDetailType: 具体类别, 如近程武器、暗器、......
  698. nParticularType: 详细类别
  699. nSeriesReq: 五行属性
  700. nLevel: 等级
  701. pnaryMALevel: 魔法属性等级数组[6]
  702. nLucky: 运气值
  703. 出口: 成功时返回非零, 相关数据在 pItem 所指对象中给出
  704. 失败时返回零
  705. ******************************************************************************/
  706. BOOL KItemGenerator::Gen_ExistEquipment(IN int nDetailType,
  707.    IN int nParticularType,
  708.    IN int nSeriesReq,
  709.    IN int nLevel,
  710.    IN const int* pnaryMALevel,
  711.    IN int nLucky,
  712.    IN int nVersion,
  713.    IN OUT KItem* pItem)
  714. {
  715. _ASSERT(this != NULL);
  716. _ASSERT(pItem != NULL);
  717. BOOL bEC = FALSE;
  718. g_RandomSeed(pItem->m_GeneratorParam.uRandomSeed);
  719. if (pnaryMALevel)
  720. memcpy(pItem->m_GeneratorParam.nGeneratorLevel, pnaryMALevel, sizeof(int) * 6);
  721. int nGameVersion = pItem->m_GeneratorParam.nVersion;
  722. // 根据入口参数, 确定装备的基本数据
  723. const int i = nParticularType * 10 + nLevel - 1;// 本公式由策划定义
  724. // 详见SPE 2002年8月31日7:40
  725. // email: 基础道具数值表
  726. // 等级数据从1开始,所以要减回来
  727. const KBASICPROP_EQUIPMENT* pEqu = NULL;
  728. switch(nDetailType)
  729. {
  730. case equip_meleeweapon:
  731. pEqu = m_BPTLib.GetMeleeWeaponRecord(i);
  732. break;
  733. case equip_rangeweapon:
  734. pEqu = m_BPTLib.GetRangeWeaponRecord(i);
  735. break;
  736. case equip_armor:
  737. pEqu = m_BPTLib.GetArmorRecord(i);
  738. break;
  739. case equip_helm:
  740. pEqu = m_BPTLib.GetHelmRecord(i);
  741. break;
  742. case equip_boots:
  743. pEqu = m_BPTLib.GetBootRecord(i);
  744. break;
  745. case equip_belt:
  746. pEqu = m_BPTLib.GetBeltRecord(i);
  747. break;
  748. case equip_amulet:
  749. pEqu = m_BPTLib.GetAmuletRecord(i);
  750. break;
  751. case equip_ring:
  752. pEqu = m_BPTLib.GetRingRecord(i);
  753. break;
  754. case equip_cuff:
  755. pEqu = m_BPTLib.GetCuffRecord(i);
  756. break;
  757. case equip_pendant:
  758. pEqu = m_BPTLib.GetPendantRecord(i);
  759. break;
  760. case equip_horse:
  761. pEqu = m_BPTLib.GetHorseRecord(i);
  762. break;
  763. default:
  764. break;
  765. }
  766. if (NULL == pEqu)
  767. { _ASSERT(FALSE); return bEC; }
  768. // 运行至此的直接原因: 只有n种装备, 而上面 i 的值在[0,n-1]之外
  769. // 检查3点: nParticularType 有误?
  770. // nLevel 有误?
  771. // 原始的tab file有误导致 m_BPTLib.m_BPTEquipment 所
  772. // 管理的数据有问题?
  773. pItem->SetAttrib_CBR(pEqu);
  774. pItem->SetSeries(nSeriesReq);
  775. if (NULL == pnaryMALevel)
  776. return TRUE;
  777. // 确定装备的魔法属性
  778. KItemNormalAttrib sMA[6]; // 道具的魔法属性
  779. bEC = Gen_MagicAttrib(nDetailType, pnaryMALevel, nSeriesReq, nLucky, sMA, nGameVersion);
  780. if (bEC)
  781. pItem->SetAttrib_MA(sMA);
  782. return bEC;
  783. }
  784. BOOL KItemGenerator::Gen_Quest(IN int nDetailType, IN OUT KItem* pItem)
  785. {
  786. _ASSERT(this != NULL);
  787. _ASSERT(pItem != NULL);
  788. BOOL bEC = FALSE;
  789. ZeroMemory(&pItem->m_GeneratorParam, sizeof(pItem->m_GeneratorParam));
  790. const KBASICPROP_QUEST* pQuest = NULL;
  791. pQuest = m_BPTLib.GetQuestRecord(nDetailType);
  792. if (NULL == pQuest)
  793. {
  794. _ASSERT(FALSE);
  795. return bEC;
  796. }
  797. *pItem = *pQuest;
  798. return TRUE;
  799. }
  800. BOOL KItemGenerator::Gen_TownPortal(IN OUT KItem* pItem)
  801. {
  802. _ASSERT(this != NULL);
  803. _ASSERT(pItem != NULL);
  804. BOOL bEC = FALSE;
  805. ZeroMemory(&pItem->m_GeneratorParam, sizeof(pItem->m_GeneratorParam));
  806. const KBASICPROP_TOWNPORTAL* pPortal = NULL;
  807. pPortal = m_BPTLib.GetTownPortalRecord(0);
  808. if (NULL == pPortal)
  809. {
  810. _ASSERT(FALSE);
  811. return bEC;
  812. }
  813. *pItem = *pPortal;
  814. return TRUE;
  815. }