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

模拟服务器

开发平台:

C/C++

  1. //---------------------------------------------------------------------------
  2. // Sword3 Engine (c) 1999-2000 by Kingsoft
  3. //
  4. // File: KObjSet.cpp
  5. // Date: 2002.01.06
  6. // Code: 边城浪子
  7. // Desc: Obj Class
  8. //---------------------------------------------------------------------------
  9. #include "KCore.h"
  10. #include "KSubWorld.h"
  11. #include "KObj.h"
  12. #ifndef _SERVER
  13. #include "../../Represent/iRepresent/iRepresentshell.h"
  14. #include "scene/KScenePlaceC.h"
  15. #endif
  16. #include "KObjSet.h"
  17. #include "CoreUseNameDef.h"
  18. #include "KItem.h"
  19. #include "Scene/SceneDataDef.h"
  20. #define OBJ_WORLD_ID_START 1000
  21. enum
  22. {
  23. ObjDataField_Name = 1,
  24. ObjDataField_DataID,
  25. ObjDataField_Kind,
  26. ObjDataField_ScriptName,
  27. ObjDataField_ImageName,
  28. ObjDataField_SoundName,
  29. ObjDataField_LifeTime,
  30. ObjDataField_Layer,
  31. ObjDataField_Height,
  32. ObjDataFiled_SkillKind,
  33. ObjDataFiled_SkillCamp,
  34. ObjDataFiled_SkillRange,
  35. ObjDataField_SkillCastTime,
  36. ObjDataField_SkillID,
  37. ObjDataField_SkillLevel,
  38. ObjDataField_LightRadius,
  39. ObjDataField_LightRed,
  40. ObjDataField_LightGreen,
  41. ObjDataField_LightBlue,
  42. ObjDataField_LightAlpha,
  43. ObjDataField_LightReflectType,
  44. ObjDataField_ImageTotalFrame,
  45. ObjDataField_ImageCurFrame,
  46. ObjDataField_ImageTotalDir,
  47. ObjDataField_ImageCurDir,
  48. ObjDataField_ImageInterval,
  49. ObjDataField_ImageCgXpos,
  50. ObjDataField_ImageCgYpos,
  51. ObjDataField_Bar0,
  52. ObjDataField_Bar1,
  53. ObjDataField_Bar2,
  54. ObjDataField_Bar3,
  55. ObjDataField_Bar4,
  56. ObjDataField_Bar5,
  57. ObjDataField_Bar6,
  58. ObjDataField_Bar7,
  59. ObjDataField_Bar8,
  60. ObjDataField_Bar9,
  61. ObjDataField_Bar10,
  62. ObjDataField_Bar11,
  63. ObjDataField_Bar12,
  64. ObjDataField_Bar13,
  65. ObjDataField_Bar14,
  66. ObjDataField_ImageDropName,
  67. ObjDataField_ImageDropTotalFrame,
  68. ObjDataField_ImageDropCurFrame,
  69. ObjDataField_ImageDropTotalDir,
  70. ObjDataField_ImageDropCurDir,
  71. ObjDataField_ImageDropInterval,
  72. ObjDataField_ImageDropCgXpos,
  73. ObjDataField_ImageDropCgYpos,
  74. ObjDataField_DrawFlag,
  75. ObjDataField_Num,
  76. };
  77. KObjSet ObjSet;
  78. char g_szObjKind[Obj_Kind_Num][32] = 
  79. {
  80. "MapObj",
  81. "Body",
  82. "Box",
  83. "Item",
  84. "Money",
  85. "LoopSound",
  86. "RandSound",
  87. "Light",
  88. "Door",
  89. "Trap",
  90. "Prop"
  91. };
  92. DWORD g_dwObjKindNum[Obj_Kind_Num] = 
  93. {
  94. 0x4f70614d,
  95. 0x79646f42,
  96. 0x00786f42,
  97. 0x6d657449,
  98. 0x656e6f4d,
  99. 0x706f6f4c,
  100. 0x646e6152,
  101. 0x6867694c,
  102. 0x726f6f44,
  103. 0x70617254,
  104. 0x706f7250
  105. };
  106. KObjSet::KObjSet()
  107. {
  108. m_nObjID = OBJ_WORLD_ID_START;
  109. }
  110. KObjSet::~KObjSet()
  111. {
  112. m_nObjID = 0;
  113. }
  114. //---------------------------------------------------------------------------
  115. // 功能:初始化,载入地图obj数据模板
  116. //---------------------------------------------------------------------------
  117. BOOL KObjSet::Init()
  118. {
  119. BOOL bRet = TRUE;
  120. int i;
  121. m_FreeIdx.Init(MAX_OBJECT);
  122. m_UseIdx.Init(MAX_OBJECT);
  123. // 开始时所有的数组元素都为空
  124. for (i = MAX_OBJECT - 1; i > 0; i--)
  125. {
  126. m_FreeIdx.Insert(i);
  127. }
  128. // g_SetFilePath("");
  129. if ( !m_cTabFile.Load(OBJ_DATA_FILE_NAME) )
  130. bRet = FALSE;
  131. // g_SetFilePath("");
  132. if ( !m_cMoneyFile.Load(MONEY_OBJ_FILE_NAME))
  133. bRet = FALSE;
  134. #ifndef _SERVER
  135. int nA, nR, nG, nB, nColorCount;
  136. char szTemp[32];
  137. KIniFile cColorIni;
  138. // g_SetFilePath("");
  139. if (!cColorIni.Load(OBJ_NAME_COLOR_FILE))
  140. {
  141. for (i = 0; i < MAX_OBJ_NAME_COLOR; i++)
  142. m_dwNameColor[i] = 0x00ffffff;
  143. }
  144. else
  145. {
  146. cColorIni.GetInteger("List", "Count", 0, &nColorCount);
  147. if (nColorCount > MAX_OBJ_NAME_COLOR)
  148. nColorCount = MAX_OBJ_NAME_COLOR;
  149. for (i = 0; i < nColorCount; i++)
  150. {
  151. sprintf(szTemp, "%d", i);
  152. cColorIni.GetInteger(szTemp, "A", 0, &nA);
  153. cColorIni.GetInteger(szTemp, "R", 0, &nR);
  154. cColorIni.GetInteger(szTemp, "G", 0, &nG);
  155. cColorIni.GetInteger(szTemp, "B", 0, &nB);
  156. m_dwNameColor[i] = (nA << 24) | (nR << 16) | (nG << 8) | nB;
  157. }
  158. for (i = nColorCount; i < MAX_OBJ_NAME_COLOR; i++)
  159. m_dwNameColor[i] = 0x00ffffff;
  160. }
  161. this->m_nShowNameFlag = 0;
  162. #endif
  163. return bRet;
  164. }
  165. #ifdef _SERVER
  166. int KObjSet::AddMoneyObj(KMapPos MapPos, int nMoneyNum)
  167. {
  168. if (nMoneyNum <= 0 || nMoneyNum >= 999999999)
  169. return -1;
  170. int nDataID = GetMoneyDataId(nMoneyNum);
  171. KObjItemInfo sInfo;
  172. sInfo.m_nItemID = 0;
  173. sInfo.m_nItemWidth = 0;
  174. sInfo.m_nItemHeight = 0;
  175. sInfo.m_nMoneyNum = nMoneyNum;
  176. sInfo.m_szName[0] = 0;
  177. sInfo.m_nColorID = 0;
  178. sInfo.m_nMovieFlag = 1;
  179. sInfo.m_nSoundFlag = 1;
  180. return Add(nDataID, MapPos, sInfo);
  181. }
  182. #endif
  183. #ifdef _SERVER
  184. int KObjSet::GetMoneyDataId(int nMoney)
  185. {
  186. int nMoneyLevel = 0;
  187. int nRet = 0;
  188. for (int i = 0; i < m_cMoneyFile.GetHeight() - 1; i++)
  189. {
  190. m_cMoneyFile.GetInteger(i + 2, 1, 0, &nMoneyLevel);
  191. if (nMoney < nMoneyLevel)
  192. {
  193. m_cMoneyFile.GetInteger(i + 2, 2, 0, &nRet);
  194. break;
  195. }
  196. }
  197. return nRet;
  198. }
  199. #endif
  200. #ifdef _SERVER
  201. //---------------------------------------------------------------------------
  202. // 功能:添加一个obj,返回在obj数组中的位置编号(如果 <= 0 ,失败)
  203. //---------------------------------------------------------------------------
  204. int KObjSet::Add(int nDataID, KMapPos MapPos, KObjItemInfo sItemInfo)
  205. {
  206. if (sItemInfo.m_nItemID > 0)
  207. {
  208. g_DebugLog("[ITEM]Object ItemIndex:%d, ID:%d", sItemInfo.m_nItemID, Item[sItemInfo.m_nItemID].GetID());
  209. }
  210. int nAddNo;
  211. nAddNo = AddData(nDataID, MapPos, sItemInfo.m_nMoneyNum, sItemInfo.m_nItemID, sItemInfo.m_nItemWidth, sItemInfo.m_nItemHeight);
  212. if (nAddNo < 0)
  213. return -1;
  214. Object[nAddNo].SetWorldID(GetID());
  215. Object[nAddNo].m_nColorID = sItemInfo.m_nColorID;
  216. if (sItemInfo.m_szName[0] && strlen(sItemInfo.m_szName) < 32)
  217. strcpy(Object[nAddNo].m_szName, sItemInfo.m_szName);
  218. OBJ_ADD_SYNC cObjAdd;
  219. int i, nTempX, nTempY;
  220. cObjAdd.ProtocolType = (BYTE)s2c_objadd;
  221. cObjAdd.m_nID = Object[nAddNo].m_nID;
  222. cObjAdd.m_nDataID = Object[nAddNo].m_nDataID;
  223. cObjAdd.m_btDir = Object[nAddNo].m_nDir;
  224. cObjAdd.m_wCurFrame = Object[nAddNo].m_cImage.m_nCurFrame;
  225. cObjAdd.m_btState = Object[nAddNo].m_nState;
  226. SubWorld[MapPos.nSubWorld].Map2Mps(MapPos.nRegion, MapPos.nMapX, MapPos.nMapY, MapPos.nOffX, MapPos.nOffY, &nTempX, &nTempY);
  227. cObjAdd.m_nXpos = nTempX;
  228. cObjAdd.m_nYpos = nTempY;
  229. cObjAdd.m_nMoneyNum = sItemInfo.m_nMoneyNum;
  230. cObjAdd.m_nItemID = sItemInfo.m_nItemID;
  231. cObjAdd.m_btItemWidth = sItemInfo.m_nItemWidth;
  232. cObjAdd.m_btItemHeight = sItemInfo.m_nItemHeight;
  233. cObjAdd.m_btColorID = sItemInfo.m_nColorID;
  234. cObjAdd.m_btFlag = 0;
  235. if (sItemInfo.m_nSoundFlag)
  236. cObjAdd.m_btFlag |= 0x01;
  237. if (sItemInfo.m_nMovieFlag)
  238. cObjAdd.m_btFlag |= 0x02;
  239. strcpy(cObjAdd.m_szName, Object[nAddNo].m_szName);
  240. cObjAdd.m_wLength = sizeof(OBJ_ADD_SYNC) - 1 - sizeof(cObjAdd.m_szName) + strlen(cObjAdd.m_szName);
  241. POINT POff[8] = 
  242. {
  243. {0, 32},
  244. {-16, 32},
  245. {-16, 0},
  246. {-16, -32},
  247. {0, -32},
  248. {16, -32},
  249. {16, 0},
  250. {16, 32},
  251. };
  252. int nMaxCount = MAX_BROADCAST_COUNT;
  253. SubWorld[MapPos.nSubWorld].m_Region[MapPos.nRegion].BroadCast((BYTE*)&cObjAdd, cObjAdd.m_wLength + 1, nMaxCount, Object[nAddNo].m_nMapX, Object[nAddNo].m_nMapY);
  254. int nConRegion;
  255. for (i = 0; i < 8; i++)
  256. {
  257. nConRegion = SubWorld[MapPos.nSubWorld].m_Region[MapPos.nRegion].m_nConnectRegion[i];
  258. if (nConRegion == -1)
  259. continue;
  260. SubWorld[MapPos.nSubWorld].m_Region[nConRegion].BroadCast((BYTE*)&cObjAdd, cObjAdd.m_wLength + 1, nMaxCount, Object[nAddNo].m_nMapX - POff[i].x, Object[nAddNo].m_nMapY - POff[i].y);
  261. }
  262. SubWorld[MapPos.nSubWorld].m_Region[MapPos.nRegion].AddObj(nAddNo);// m_WorldMessage.Send(GWM_OBJ_ADD, MapPos.nRegion, nAddNo);
  263. return nAddNo;
  264. }
  265. #endif
  266. #ifdef _SERVER
  267. //---------------------------------------------------------------------------
  268. // 功能:从obj数据文件中载入相应数据
  269. //---------------------------------------------------------------------------
  270. int KObjSet::AddData(int nDataID, KMapPos MapPos, int nMoneyNum, int nItemID, int nItemWidth, int nItemHeight)
  271. {
  272. if (nDataID <= 0 || nDataID >= m_cTabFile.GetHeight())
  273. return -1;
  274. if (MapPos.nSubWorld < 0 || MapPos.nSubWorld >= MAX_SUBWORLD)
  275. return -1;
  276. if (MapPos.nRegion < 0)
  277. return -1;
  278. int nFreeNo, i, nTemp;
  279. char szBuffer[80];
  280. nFreeNo = FindFree();
  281. if (nFreeNo <= 0)
  282. return -1;
  283. Object[nFreeNo].Release();
  284. Object[nFreeNo].m_nDataID = nDataID;
  285. m_cTabFile.GetString(nDataID + 1, ObjDataField_Kind, g_szObjKind[0], szBuffer, sizeof(szBuffer));
  286. for (i = 0; i < Obj_Kind_Num; i++)
  287. {
  288. if (*(DWORD*)(&szBuffer) == g_dwObjKindNum[i])
  289. // if (strcmp(szBuffer, g_szObjKind[i]) == 0)
  290. break;
  291. }
  292. if (i >= Obj_Kind_Num)
  293. i = 0;
  294. Object[nFreeNo].m_nKind = i;
  295. // 从 ObjData 文件中读取数据
  296. m_cTabFile.GetInteger(nDataID + 1, ObjDataField_LifeTime, 0, &Object[nFreeNo].m_nLifeTime);
  297. m_cTabFile.GetString(nDataID + 1, ObjDataField_Name, "", Object[nFreeNo].m_szName, sizeof(Object[nFreeNo].m_szName));
  298. m_cTabFile.GetString(nDataID + 1, ObjDataField_ScriptName, "", szBuffer, sizeof(szBuffer));
  299. Object[nFreeNo].SetScriptFile(szBuffer);
  300. int nTotalFrame, nTotalDir, nCurFrame, nCurDir;
  301. m_cTabFile.GetInteger(nDataID + 1, ObjDataField_ImageTotalFrame, 1, &nTotalFrame);
  302. m_cTabFile.GetInteger(nDataID + 1, ObjDataField_ImageTotalDir, 1, &nTotalDir);
  303. m_cTabFile.GetInteger(nDataID + 1, ObjDataField_ImageCurFrame, 0, &nCurFrame);
  304. m_cTabFile.GetInteger(nDataID + 1, ObjDataField_ImageCurDir, 0, &nCurDir);
  305. m_cTabFile.GetInteger(nDataID + 1, ObjDataField_ImageInterval, 0, (int *)(&Object[nFreeNo].m_cImage.m_dwInterval));
  306. Object[nFreeNo].m_cImage.SetTotalFrame(nTotalFrame);
  307. Object[nFreeNo].m_cImage.SetTotalDir(nTotalDir);
  308. Object[nFreeNo].m_cImage.SetCurFrame(nCurFrame);
  309. Object[nFreeNo].m_cImage.SetCurDir(nCurDir);
  310. Object[nFreeNo].m_nDir = (Object[nFreeNo].m_cImage.m_nCurDir * 64 / Object[nFreeNo].m_cImage.m_nTotalDir) % 64;
  311. for (i = 0; i < OBJ_BAR_SIZE; i++)
  312. {
  313. m_cTabFile.GetInteger(nDataID + 1, ObjDataField_Bar0 + i, 0, &nTemp);
  314. Object[nFreeNo].m_btBar[i] = (BYTE)nTemp;
  315. }
  316. Object[nFreeNo].m_nIndex = nFreeNo;
  317. Object[nFreeNo].m_nSubWorldID = MapPos.nSubWorld;
  318. Object[nFreeNo].m_nRegionIdx = MapPos.nRegion;
  319. Object[nFreeNo].m_nMapX = MapPos.nMapX;
  320. Object[nFreeNo].m_nMapY = MapPos.nMapY;
  321. Object[nFreeNo].m_nOffX = MapPos.nOffX;
  322. Object[nFreeNo].m_nOffY = MapPos.nOffY;
  323. Object[nFreeNo].m_nMoneyNum = nMoneyNum;
  324. Object[nFreeNo].m_nBelong = -1;
  325. Object[nFreeNo].m_nBelongTime = 0;
  326. SetObjItem(nFreeNo, nItemID, nItemWidth, nItemHeight);
  327. // if (有了物件障碍层) 设定物件障碍 (not end)
  328. m_UseIdx.Insert(nFreeNo);
  329. m_FreeIdx.Remove(nFreeNo);
  330. return nFreeNo;
  331. }
  332. #endif
  333. #ifdef _SERVER
  334. //---------------------------------------------------------------------------
  335. // 功能:设定obj所带的物件信息,包括物件id,物件在装备栏中的长、宽
  336. //---------------------------------------------------------------------------
  337. BOOL KObjSet::SetObjItem(int nObjIndex, int nItemID, int nItemWidth, int nItemHeight)
  338. {
  339. if (nObjIndex <= 0 || nObjIndex >= MAX_OBJECT)
  340. return FALSE;
  341. Object[nObjIndex].m_nItemDataID = nItemID;
  342. Object[nObjIndex].m_nItemWidth = nItemWidth;
  343. Object[nObjIndex].m_nItemHeight = nItemHeight;
  344. return TRUE;
  345. }
  346. #endif
  347. #ifdef _SERVER
  348. //---------------------------------------------------------------------------
  349. // 功能:服务器给某个客户端发送某个obj的数据信息
  350. //---------------------------------------------------------------------------
  351. BOOL KObjSet::SyncAdd(int nID, int nClient)
  352. {
  353. int nFindIndex;
  354. nFindIndex = FindID(nID);
  355. if (nFindIndex <= 0)
  356. return FALSE;
  357. return Object[nFindIndex].SyncAdd(nClient);
  358. }
  359. #endif
  360. #ifndef _SERVER
  361. //---------------------------------------------------------------------------
  362. // 功能:客户端添加一个obj
  363. //---------------------------------------------------------------------------
  364. int KObjSet::ClientAdd(int nID, int nDataID, int nState, int nDir, int nCurFrame, int nXpos, int nYpos, KObjItemInfo sInfo)
  365. {
  366. if (nDataID <= 0 || nDataID >= m_cTabFile.GetHeight())
  367. return -1;
  368. int nAddIndex;
  369. int nRegion, nMapX, nMapY, nOffX, nOffY;
  370. SubWorld[0].Mps2Map(nXpos, nYpos, &nRegion, &nMapX, &nMapY, &nOffX, &nOffY);
  371. if (nRegion < 0)
  372. return -1;
  373. nAddIndex = AddData(nDataID, 0, nRegion, nMapX, nMapY, nOffX, nOffY);
  374. if (nAddIndex < 0)
  375. return -1;
  376. Object[nAddIndex].SetWorldID(nID);
  377. if (nDir >= 0)
  378. {
  379. Object[nAddIndex].SetDir(nDir);
  380. }
  381. else
  382. {
  383. if (nCurFrame > 0)
  384. Object[nAddIndex].m_cImage.SetCurFrame(nCurFrame);
  385. }
  386. if (nState >= 0)
  387. {
  388. Object[nAddIndex].SetState(nState, sInfo.m_nSoundFlag);
  389. }
  390. if (Object[nAddIndex].m_nKind == Obj_Kind_Item && sInfo.m_nMovieFlag)
  391. {
  392. Object[nAddIndex].m_nDropState = 1; // 设为掉出动画
  393. if (nCurFrame > 0)
  394. Object[nAddIndex].m_cImageDrop.SetCurFrame(nCurFrame);
  395. }
  396. else
  397. {
  398. Object[nAddIndex].m_nDropState = 0;
  399. }
  400. Object[nAddIndex].m_nMoneyNum = sInfo.m_nMoneyNum;
  401. Object[nAddIndex].m_nItemDataID = sInfo.m_nItemID;
  402. Object[nAddIndex].m_nItemWidth = sInfo.m_nItemWidth;
  403. Object[nAddIndex].m_nItemHeight = sInfo.m_nItemHeight;
  404. Object[nAddIndex].m_nColorID = sInfo.m_nColorID;
  405. Object[nAddIndex].m_dwNameColor = this->GetNameColor(sInfo.m_nColorID);
  406. if (sInfo.m_szName[0])
  407. strcpy(Object[nAddIndex].m_szName, sInfo.m_szName);
  408. #ifdef _DEBUG
  409. g_DebugLog("Obj:%x, %d, %d", SubWorld[0].m_Region[nRegion].m_RegionID, nMapX, nMapY);
  410. #endif
  411. SubWorld[0].m_Region[nRegion].AddObj(nAddIndex);// m_WorldMessage.Send(GWM_OBJ_ADD, nRegion, nAddIndex);
  412. return nAddIndex;
  413. }
  414. #endif
  415. #ifndef _SERVER
  416. //---------------------------------------------------------------------------
  417. // 功能:客户端载入一个Region的所有Obj
  418. //---------------------------------------------------------------------------
  419. BOOL KObjSet::ClientLoadRegionObj(char *lpszMapPath, int nRegionX, int nRegionY, int nSubWorld, int nRegion)
  420. {
  421. if (!lpszMapPath || !lpszMapPath[0])
  422. return FALSE;
  423. char szFile[80];
  424. // sprintf(szPath, "%s\v_%03d", lpszMapPath, nRegionY);
  425. // g_SetFilePath(szPath);
  426. KPakFile cDataFile;
  427. KObjFileHead sHead;
  428. sprintf(szFile, "\%s\v_%03d\%03d_%s", lpszMapPath, nRegionY, nRegionX, REGION_OBJ_FILE_CLIENT);
  429. if (cDataFile.Open(szFile) != TRUE)
  430. return FALSE;
  431. if (cDataFile.Size() < sizeof(KObjFileHead))
  432. {
  433. cDataFile.Close();
  434. return FALSE;
  435. }
  436. cDataFile.Read(&sHead, sizeof(KObjFileHead));
  437. KSPObj sData;
  438. int nKind;
  439. KObjItemInfo sInfo;
  440. for (int i = 0; (DWORD)i < sHead.uNumObj; i++)
  441. {
  442. memset(sData.szScript, 0, sizeof(sData.szScript));
  443. cDataFile.Read(&sData, sizeof(KSPObj) - sizeof(sData.szScript));
  444. cDataFile.Read(sData.szScript, sData.nScriptNameLen);
  445. nKind = GetDataIDKind(sData.nTemplateID);
  446. if (CheckClientKind(nKind) != 1)
  447. continue;
  448. sInfo.m_nItemID = 0;
  449. sInfo.m_nItemWidth = 0;
  450. sInfo.m_nItemHeight = 0;
  451. sInfo.m_nMoneyNum = 0;
  452. sInfo.m_nColorID = 0;
  453. sInfo.m_szName[0] = 0;
  454. sInfo.m_nMovieFlag = 0;
  455. sInfo.m_nSoundFlag = 0;
  456. ClientAdd(0, sData.nTemplateID, sData.nState, sData.nDir, 0, sData.Pos.x, sData.Pos.y, sInfo);
  457. }
  458. cDataFile.Close();
  459. return TRUE;
  460. }
  461. #endif
  462. #ifndef _SERVER
  463. //---------------------------------------------------------------------------
  464. // 功能:客户端载入一个Region的所有Obj
  465. //---------------------------------------------------------------------------
  466. BOOL KObjSet::ClientLoadRegionObj(KPakFile *pFile, DWORD dwDataSize)
  467. {
  468. if (!pFile || dwDataSize < sizeof(sizeof(KObjFileHead)))
  469. return FALSE;
  470. KObjFileHead sHead;
  471. KSPObj sData;
  472. int nKind;
  473. KObjItemInfo sInfo;
  474. pFile->Read(&sHead, sizeof(sHead));
  475. for (int i = 0; (DWORD)i < sHead.uNumObj; i++)
  476. {
  477. pFile->Read(&sData, sizeof(KSPObj) - sizeof(sData.szScript));
  478. if (sData.nScriptNameLen < sizeof(sData.szScript))
  479. {
  480. pFile->Read(sData.szScript, sData.nScriptNameLen);
  481. sData.szScript[sData.nScriptNameLen] = 0;
  482. }
  483. else
  484. {
  485. sData.szScript[0] = 0;
  486. pFile->Seek(sData.nScriptNameLen, FILE_CURRENT);
  487. }
  488. nKind = GetDataIDKind(sData.nTemplateID);
  489. if (CheckClientKind(nKind) != 1)
  490. continue;
  491. sInfo.m_nItemID = 0;
  492. sInfo.m_nItemWidth = 0;
  493. sInfo.m_nItemHeight = 0;
  494. sInfo.m_nMoneyNum = 0;
  495. sInfo.m_nColorID = 0;
  496. sInfo.m_szName[0] = 0;
  497. sInfo.m_nMovieFlag = 0;
  498. sInfo.m_nSoundFlag = 0;
  499. ClientAdd(0, sData.nTemplateID, sData.nState, sData.nDir, 0, sData.Pos.x, sData.Pos.y, sInfo);
  500. }
  501. return TRUE;
  502. }
  503. #endif
  504. #ifdef _SERVER
  505. //---------------------------------------------------------------------------
  506. // 功能:服务器端载入一个Region的所有Obj
  507. //---------------------------------------------------------------------------
  508. BOOL KObjSet::ServerLoadRegionObj(char *lpszMapPath, int nRegionX, int nRegionY, int nSubWorld)
  509. {
  510. if (!lpszMapPath || !lpszMapPath[0])
  511. return FALSE;
  512. char szPath[80], szFile[80];
  513. // sprintf(szPath, "%s", lpszMapPath);
  514. // g_SetFilePath(szPath);
  515. KPakFile cDataFile;
  516. KObjFileHead sHead;
  517. sprintf(szFile, "\%s\%03d_%s", lpszMapPath, nRegionX, REGION_OBJ_FILE_SERVER);
  518. if (cDataFile.Open(szFile) != TRUE)
  519. return FALSE;
  520. if (cDataFile.Size() < sizeof(KObjFileHead))
  521. {
  522. cDataFile.Close();
  523. return FALSE;
  524. }
  525. cDataFile.Read(&sHead, sizeof(KObjFileHead));
  526. KSPObj sData;
  527. int nKind, nNo;
  528. for (int i = 0; i < sHead.uNumObj; i++)
  529. {
  530. memset(sData.szScript, 0, sizeof(sData.szScript));
  531. cDataFile.Read(&sData, sizeof(KSPObj) - sizeof(sData.szScript));
  532. cDataFile.Read(sData.szScript, sData.nScriptNameLen);
  533. nKind = GetDataIDKind(sData.nTemplateID);
  534. if (CheckClientKind(nKind) != 0)
  535. continue;
  536. KMapPos sPos;
  537. KObjItemInfo sInfo;
  538. sPos.nSubWorld = nSubWorld;
  539. SubWorld[nSubWorld].Mps2Map(sData.Pos.x, sData.Pos.y, &sPos.nRegion, &sPos.nMapX, &sPos.nMapY, &sPos.nOffX, &sPos.nOffY);
  540. sPos.nRegion = sPos.nRegion;
  541. sInfo.m_nItemID = 0;
  542. sInfo.m_nItemWidth = 0;
  543. sInfo.m_nItemHeight = 0;
  544. sInfo.m_nMoneyNum = 0;
  545. sInfo.m_szName[0] = 0;
  546. sInfo.m_nColorID = 0;
  547. sInfo.m_nMovieFlag = 0;
  548. sInfo.m_nSoundFlag = 0;
  549. nNo = Add(sData.nTemplateID, sPos, sInfo);
  550. if (nNo == -1)
  551. continue;
  552. if (sData.nDir >= 0)
  553. Object[nNo].SetDir(sData.nDir);
  554. if (sData.nState >= 0)
  555. Object[nNo].SetState(sData.nState);
  556. Object[nNo].SetScriptFile(sData.szScript);
  557. }
  558. cDataFile.Close();
  559. return TRUE;
  560. }
  561. #endif
  562. #ifdef _SERVER
  563. //---------------------------------------------------------------------------
  564. // 功能:服务器端载入一个Region的所有Obj
  565. //---------------------------------------------------------------------------
  566. BOOL KObjSet::ServerLoadRegionObj(int nSubWorld, KPakFile *pFile, DWORD dwDataSize)
  567. {
  568. if (!pFile || dwDataSize < sizeof(KObjFileHead))
  569. return FALSE;
  570. KObjFileHead sHead;
  571. KSPObj sData;
  572. int nKind, nNo;
  573. KMapPos sPos;
  574. KObjItemInfo sInfo;
  575. pFile->Read(&sHead, sizeof(KObjFileHead));
  576. for (int i = 0; i < sHead.uNumObj; i++)
  577. {
  578. pFile->Read(&sData, sizeof(KSPObj) - sizeof(sData.szScript));
  579. if (sData.nScriptNameLen < sizeof(sData.szScript))
  580. {
  581. pFile->Read(sData.szScript, sData.nScriptNameLen);
  582. sData.szScript[sData.nScriptNameLen] = 0;
  583. }
  584. else
  585. {
  586. sData.szScript[0] = 0;
  587. pFile->Seek(sData.nScriptNameLen, FILE_CURRENT);
  588. }
  589. nKind = GetDataIDKind(sData.nTemplateID);
  590. if (CheckClientKind(nKind) != 0)
  591. continue;
  592. sPos.nSubWorld = nSubWorld;
  593. SubWorld[nSubWorld].Mps2Map(sData.Pos.x, sData.Pos.y, &sPos.nRegion, &sPos.nMapX, &sPos.nMapY, &sPos.nOffX, &sPos.nOffY);
  594. sPos.nRegion = sPos.nRegion;
  595. sInfo.m_nItemID = 0;
  596. sInfo.m_nItemWidth = 0;
  597. sInfo.m_nItemHeight = 0;
  598. sInfo.m_nMoneyNum = 0;
  599. sInfo.m_szName[0] = 0;
  600. sInfo.m_nColorID = 0;
  601. sInfo.m_nMovieFlag = 0;
  602. sInfo.m_nSoundFlag = 0;
  603. nNo = Add(sData.nTemplateID, sPos, sInfo);
  604. if (nNo == -1)
  605. continue;
  606. if (sData.nDir >= 0)
  607. Object[nNo].SetImageDir(sData.nDir);
  608. if (sData.nState >= 0)
  609. Object[nNo].SetState(sData.nState);
  610. Object[nNo].SetScriptFile(sData.szScript);
  611. }
  612. return TRUE;
  613. }
  614. #endif
  615. #ifndef _SERVER
  616. //---------------------------------------------------------------------------
  617. // 功能:通过obj的dataid添加一个obj
  618. //---------------------------------------------------------------------------
  619. int KObjSet::AddData(int nDataID, int nSubWorld, int nRegion, int nMapX, int nMapY, int nOffX, int nOffY)
  620. {
  621. if (nDataID <= 0 || nDataID >= m_cTabFile.GetHeight())
  622. return -1;
  623. if (nSubWorld < 0 || nSubWorld >= MAX_SUBWORLD)
  624. return -1;
  625. if (nRegion < 0)
  626. return -1;
  627. int nFreeNo, i, nTemp;
  628. char szBuffer[80];
  629. nFreeNo = FindFree();
  630. if (nFreeNo <= 0)
  631. return -1;
  632. Object[nFreeNo].Release();
  633. Object[nFreeNo].m_nDataID = nDataID;
  634. m_cTabFile.GetString(nDataID + 1, ObjDataField_Kind, g_szObjKind[0], szBuffer, sizeof(szBuffer));
  635. for (i = 0; i < Obj_Kind_Num; i++)
  636. {
  637. if (*(DWORD*)(&szBuffer) == g_dwObjKindNum[i])
  638. break;
  639. }
  640. if (i >= Obj_Kind_Num)
  641. i = 0;
  642. Object[nFreeNo].m_nKind = i;
  643. // 从 ObjData 文件中读取数据
  644. m_cTabFile.GetInteger(nDataID + 1, ObjDataField_Layer, 1, &Object[nFreeNo].m_nLayer);
  645. m_cTabFile.GetInteger(nDataID + 1, ObjDataField_Height, 0, &Object[nFreeNo].m_nHeight);
  646. m_cTabFile.GetInteger(nDataID + 1, ObjDataField_LifeTime, 0, &Object[nFreeNo].m_nLifeTime);
  647. m_cTabFile.GetString(nDataID + 1, ObjDataField_Name, "", Object[nFreeNo].m_szName, sizeof(Object[nFreeNo].m_szName));
  648. m_cTabFile.GetString(nDataID + 1, ObjDataField_ScriptName, "", szBuffer, sizeof(szBuffer));
  649. Object[nFreeNo].SetScriptFile(szBuffer);
  650. m_cTabFile.GetString(nDataID + 1, ObjDataField_SoundName, "", Object[nFreeNo].m_szSoundName, sizeof(Object[nFreeNo].m_szSoundName));
  651. m_cTabFile.GetInteger(nDataID + 1, ObjDataField_LightRadius, 0, &Object[nFreeNo].m_sObjLight.m_nRadius);
  652. m_cTabFile.GetInteger(nDataID + 1, ObjDataField_LightRed, 255, &Object[nFreeNo].m_sObjLight.m_nRed);
  653. m_cTabFile.GetInteger(nDataID + 1, ObjDataField_LightGreen, 255, &Object[nFreeNo].m_sObjLight.m_nGreen);
  654. m_cTabFile.GetInteger(nDataID + 1, ObjDataField_LightBlue, 255, &Object[nFreeNo].m_sObjLight.m_nBlue);
  655. m_cTabFile.GetInteger(nDataID + 1, ObjDataField_LightAlpha, 255, &Object[nFreeNo].m_sObjLight.m_nAlpha);
  656. m_cTabFile.GetInteger(nDataID + 1, ObjDataField_LightReflectType, 0, &Object[nFreeNo].m_sObjLight.m_nReflectType);
  657. int nTotalFrame, nTotalDir, nCurFrame, nCurDir;
  658. m_cTabFile.GetString(nDataID + 1, ObjDataField_ImageName, "", Object[nFreeNo].m_szImageName, sizeof(Object[nFreeNo].m_szImageName));
  659. m_cTabFile.GetInteger(nDataID + 1, ObjDataField_ImageTotalFrame, 1, &nTotalFrame);
  660. m_cTabFile.GetInteger(nDataID + 1, ObjDataField_ImageTotalDir, 1, &nTotalDir);
  661. m_cTabFile.GetInteger(nDataID + 1, ObjDataField_ImageCurFrame, 0, &nCurFrame);
  662. m_cTabFile.GetInteger(nDataID + 1, ObjDataField_ImageCurDir, 0, &nCurDir);
  663. m_cTabFile.GetInteger(nDataID + 1, ObjDataField_ImageInterval, 0, (int *)(&Object[nFreeNo].m_cImage.m_dwInterval));
  664. m_cTabFile.GetInteger(nDataID + 1, ObjDataField_ImageCgXpos, 0, &Object[nFreeNo].m_cImage.m_nCgXpos);
  665. m_cTabFile.GetInteger(nDataID + 1, ObjDataField_ImageCgYpos, 0, &Object[nFreeNo].m_cImage.m_nCgYpos);
  666. Object[nFreeNo].m_cImage.SetFileName(Object[nFreeNo].m_szImageName);
  667. Object[nFreeNo].m_cImage.SetTotalFrame(nTotalFrame);
  668. Object[nFreeNo].m_cImage.SetTotalDir(nTotalDir);
  669. Object[nFreeNo].m_cImage.SetCurFrame(nCurFrame);
  670. Object[nFreeNo].m_cImage.SetCurDir(nCurDir);
  671. Object[nFreeNo].SetDir(Object[nFreeNo].m_cImage.m_nCurDir * 64 / Object[nFreeNo].m_cImage.m_nTotalDir);
  672. int nDropTotalFrame, nDropTotalDir, nDropCurFrame, nDropCurDir;
  673. m_cTabFile.GetString(
  674. nDataID + 1,
  675. ObjDataField_ImageDropName,
  676. Object[nFreeNo].m_szImageName,
  677. Object[nFreeNo].m_szImageDropName,
  678. sizeof(Object[nFreeNo].m_szImageDropName));
  679. m_cTabFile.GetInteger(
  680. nDataID + 1,
  681. ObjDataField_ImageDropTotalFrame,
  682. nTotalFrame,
  683. &nDropTotalFrame);
  684. m_cTabFile.GetInteger(
  685. nDataID + 1,
  686. ObjDataField_ImageDropTotalDir,
  687. nTotalDir,
  688. &nDropTotalDir);
  689. m_cTabFile.GetInteger(
  690. nDataID + 1,
  691. ObjDataField_ImageDropCurFrame,
  692. nCurFrame,
  693. &nDropCurFrame);
  694. m_cTabFile.GetInteger(
  695. nDataID + 1,
  696. ObjDataField_ImageDropCurDir,
  697. nCurDir,
  698. &nDropCurDir);
  699. m_cTabFile.GetInteger(
  700. nDataID + 1,
  701. ObjDataField_ImageDropInterval,
  702. Object[nFreeNo].m_cImage.m_dwInterval,
  703. (int *)(&Object[nFreeNo].m_cImageDrop.m_dwInterval));
  704. m_cTabFile.GetInteger(
  705. nDataID + 1,
  706. ObjDataField_ImageDropCgXpos,
  707. Object[nFreeNo].m_cImage.m_nCgXpos,
  708. &Object[nFreeNo].m_cImageDrop.m_nCgXpos);
  709. m_cTabFile.GetInteger(
  710. nDataID + 1,
  711. ObjDataField_ImageDropCgYpos,
  712. Object[nFreeNo].m_cImage.m_nCgYpos,
  713. &Object[nFreeNo].m_cImageDrop.m_nCgYpos);
  714. Object[nFreeNo].m_cImageDrop.SetFileName(Object[nFreeNo].m_szImageDropName);
  715. Object[nFreeNo].m_cImageDrop.SetTotalFrame(nDropTotalFrame);
  716. Object[nFreeNo].m_cImageDrop.SetTotalDir(nDropTotalDir);
  717. Object[nFreeNo].m_cImageDrop.SetCurFrame(nDropCurFrame);
  718. Object[nFreeNo].m_cImageDrop.SetCurDir(nDropCurDir);
  719. for (i = 0; i < OBJ_BAR_SIZE; i++)
  720. {
  721. m_cTabFile.GetInteger(nDataID + 1, ObjDataField_Bar0 + i, 0, &nTemp);
  722. Object[nFreeNo].m_btBar[i] = (BYTE)nTemp;
  723. }
  724. m_cTabFile.GetInteger(nDataID + 1, ObjDataField_DrawFlag, 0, &Object[nFreeNo].m_bDrawFlag);
  725. Object[nFreeNo].m_nIndex = nFreeNo;
  726. Object[nFreeNo].m_nSubWorldID = nSubWorld;
  727. Object[nFreeNo].m_nRegionIdx = nRegion;
  728. Object[nFreeNo].m_nMapX = nMapX;
  729. Object[nFreeNo].m_nMapY = nMapY;
  730. Object[nFreeNo].m_nOffX = nOffX;
  731. Object[nFreeNo].m_nOffY = nOffY;
  732. Object[nFreeNo].m_nBelongRegion = SubWorld[0].m_Region[nRegion].m_RegionID;
  733. // if (有了物件障碍层) 设定物件障碍
  734. m_UseIdx.Insert(nFreeNo);
  735. m_FreeIdx.Remove(nFreeNo);
  736. return nFreeNo;
  737. }
  738. #endif
  739. //---------------------------------------------------------------------------
  740. // 功能:找没有使用的空闲obj
  741. //---------------------------------------------------------------------------
  742. int KObjSet::FindFree()
  743. {
  744. return m_FreeIdx.GetNext(0);
  745. }
  746. //---------------------------------------------------------------------------
  747. // 功能:判断某个类型的obj是不是clientonly类型
  748. //---------------------------------------------------------------------------
  749. int  KObjSet::CheckClientKind(int nKind)
  750. {
  751. switch (nKind)
  752. {
  753. case Obj_Kind_MapObj:
  754. case Obj_Kind_Body:
  755. case Obj_Kind_LoopSound:
  756. case Obj_Kind_RandSound:
  757. case Obj_Kind_Light:
  758. return 1;
  759. case Obj_Kind_Door:
  760. case Obj_Kind_Trap:
  761. case Obj_Kind_Prop:
  762. case Obj_Kind_Box:
  763. case Obj_Kind_Item:
  764. case Obj_Kind_Money:
  765. return 0;
  766. default:
  767. return -1;
  768. }
  769. return -1;
  770. }
  771. //---------------------------------------------------------------------------
  772. // 功能:找某个id的obj
  773. //---------------------------------------------------------------------------
  774. int KObjSet::FindID(int nID)
  775. {
  776. if (nID < OBJ_WORLD_ID_START)
  777. return 0;
  778. /*
  779. for (int i = 1; i < MAX_OBJECT; i++)
  780. {
  781. if ( Object[i].m_nIndex > 0 && Object[i].m_nID == nID)
  782. return i;
  783. }*/
  784. int i = m_UseIdx.GetNext(0);
  785. while (i != 0)
  786. {
  787. if (Object[i].m_nIndex > 0 && Object[i].m_nID == nID)
  788. return i;
  789. i = m_UseIdx.GetNext(i);
  790. }
  791. return 0;
  792. }
  793. //---------------------------------------------------------------------------
  794. // 功能:找某个名字的obj
  795. //---------------------------------------------------------------------------
  796. int KObjSet::FindName(char *lpszObjName)
  797. {
  798. if (!lpszObjName || !lpszObjName[0])
  799. return 0;
  800. //for (int i = 1; i < MAX_OBJECT; i++)
  801. int i = m_UseIdx.GetNext(0);
  802. while(i != 0)
  803. {
  804. if (Object[i].m_nIndex > 0 && strcmp(Object[i].m_szName, lpszObjName) == 0)
  805. return i;
  806. i = m_UseIdx.GetNext(i);
  807. }
  808. return 0;
  809. }
  810. //---------------------------------------------------------------------------
  811. // 功能:只能在Obj 的 SetWorldID 的时候调用,其他时候都直接使用m_nObjID
  812. //---------------------------------------------------------------------------
  813. int KObjSet::GetID()
  814. {
  815. m_nObjID++;
  816. return (m_nObjID - 1);
  817. }
  818. void KObjSet::Remove(int nIdx)
  819. {
  820. Object[nIdx].Release();
  821. m_FreeIdx.Insert(nIdx);
  822. m_UseIdx.Remove(nIdx);
  823. }
  824. #ifndef _SERVER
  825. void KObjSet::RemoveIfClientOnly(int nIdx)
  826. {
  827. if (CheckClientKind(Object[nIdx].GetKind()) != 1)
  828. return;
  829. Object[nIdx].Release();
  830. m_FreeIdx.Insert(nIdx);
  831. m_UseIdx.Remove(nIdx);
  832. }
  833. #endif
  834. int KObjSet::GetDataIDKind(int nDataID)
  835. {
  836. if (nDataID <= 0 || nDataID >= m_cTabFile.GetHeight())
  837. return -1;
  838. char szBuffer[80];
  839. m_cTabFile.GetString(nDataID + 1, ObjDataField_Kind, g_szObjKind[0], szBuffer, sizeof(szBuffer));
  840. int i;
  841. for (i = 0; i < Obj_Kind_Num; i++)
  842. {
  843. if (strcmp(szBuffer, g_szObjKind[i]) == 0)
  844. break;
  845. }
  846. if (i >= Obj_Kind_Num)
  847. return -1;
  848. return i;
  849. }
  850. #ifndef _SERVER
  851. int KObjSet::SearchObjAt(int nX, int nY, int nRange)
  852. {
  853. int nIdx = 0;
  854. int nMin = nRange;
  855. int nMinIdx = 0;
  856. int nLength = 0;
  857. int nSrcX[2];
  858. int nSrcY[2];
  859. nSrcX[0] = nX;
  860. nSrcY[0] = nY;
  861. g_ScenePlace.ViewPortCoordToSpaceCoord(nSrcX[0], nSrcY[0], 0);
  862. nSrcX[1] = nX;
  863. nSrcY[1] = nY;
  864. g_ScenePlace.ViewPortCoordToSpaceCoord(nSrcX[1], nSrcY[1], 120);
  865. int nDx = nSrcX[0] - nSrcX[1];
  866. int nDy = nSrcY[0] - nSrcY[1];
  867. while(1)
  868. {
  869. nIdx = m_UseIdx.GetNext(nIdx);
  870. if (!nIdx)
  871. break;
  872. if (Object[nIdx].m_nRegionIdx < 0)
  873. continue;
  874. if (Obj_Kind_Box != Object[nIdx].m_nKind
  875. && Obj_Kind_Item != Object[nIdx].m_nKind
  876. && Obj_Kind_Money != Object[nIdx].m_nKind
  877. && Obj_Kind_Prop != Object[nIdx].m_nKind
  878. && Obj_Kind_Door != Object[nIdx].m_nKind)
  879. continue;
  880. int x, y;
  881. SubWorld[0].Map2Mps(Object[nIdx].m_nRegionIdx, Object[nIdx].m_nMapX, Object[nIdx].m_nMapY,
  882. Object[nIdx].m_nOffX, Object[nIdx].m_nOffY, &x, &y);
  883. if (nSrcY[0] > y)
  884. continue;
  885. if (nSrcY[0] < y - 40 - Object[nIdx].m_nHeight)
  886. continue;
  887. nLength = abs(nDx * (nSrcY[0] - y) / nDy + nSrcX[0] - x);
  888. if (nLength < nMin)
  889. {
  890. nMin = nLength;
  891. nMinIdx = nIdx;
  892. }
  893. }
  894. return nMinIdx;
  895. }
  896. #endif
  897. #ifndef _SERVER
  898. DWORD KObjSet::GetNameColor(int nColorID)
  899. {
  900. if (nColorID < 0 || nColorID >= MAX_OBJ_NAME_COLOR)
  901. return this->m_dwNameColor[0];
  902. return this->m_dwNameColor[nColorID];
  903. }
  904. #endif
  905. #ifndef _SERVER
  906. //-------------------------------------------------------------------------
  907. // 功能:设定是否全部显示 item 和 money 类的 object 的名字
  908. // bFlag == TRUE 显示,bFlag == FALSE 不显示 zroc add
  909. //-------------------------------------------------------------------------
  910. void KObjSet::SetShowNameFlag(BOOL bFlag)
  911. {
  912. this->m_nShowNameFlag = bFlag;
  913. }
  914. #endif
  915. #ifndef _SERVER
  916. //-------------------------------------------------------------------------
  917. // 功能:判断是否全部显示 item 和 money 类的 object 的名字  返回值 TRUE 显示,FALSE 不显示
  918. //-------------------------------------------------------------------------
  919. BOOL KObjSet::CheckShowName()
  920. {
  921. return m_nShowNameFlag;
  922. }
  923. #endif