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

模拟服务器

开发平台:

C/C++

  1. #include "KCore.h"
  2. #include <math.h>
  3. #include "KRegion.h"
  4. #include "KMath.h"
  5. #include "KNpc.h"
  6. #include "KPlayer.h"
  7. #include "KNpcSet.h"
  8. #include "KObjSet.h"
  9. #include "KPlayerSet.h"
  10. #include "KMissleSet.h"
  11. #ifndef _STANDALONE
  12. #include "crtdbg.h"
  13. #endif
  14. #include "Scene/ObstacleDef.h"
  15. #ifdef _SERVER
  16. //#include "KNetServer.h"
  17. //#include "../MultiServer/Heaven/Interface/iServer.h"
  18. #endif
  19. #ifndef _SERVER
  20. #include "scene/KScenePlaceC.h"
  21. #endif
  22. #include "KSubWorld.h"
  23. #ifndef TOOLVERSION
  24. KSubWorld SubWorld[MAX_SUBWORLD];
  25. #else 
  26. CORE_API KSubWorld SubWorld[MAX_SUBWORLD];
  27. #endif
  28. #define defLOGIC_CELL_WIDTH 32
  29. #define defLOGIC_CELL_HEIGHT 32
  30. #ifdef _SERVER
  31. KGlobalMissionArray g_GlobalMissionArray;
  32. #endif
  33. KSubWorld::KSubWorld()
  34. {
  35. m_Region = NULL;
  36. m_nRegionWidth = 512 / 32;
  37. m_nRegionHeight = 1024 / 32;
  38. m_nCellWidth = defLOGIC_CELL_WIDTH;
  39. m_nCellHeight = defLOGIC_CELL_HEIGHT;
  40. m_dwCurrentTime = 0;
  41. m_SubWorldID = -1;
  42. m_nWeather = WEATHERID_NOTHING;
  43. #ifndef _SERVER
  44. m_nWorldRegionWidth = 3;
  45. m_nWorldRegionHeight = 3;
  46. memset(m_ClientRegionIdx, 0, sizeof(this->m_ClientRegionIdx));
  47. memset(this->m_szMapPath, 0, sizeof(this->m_szMapPath));
  48. #endif
  49. #ifdef _SERVER
  50. m_nWorldRegionWidth = 0;
  51. m_nWorldRegionHeight = 0;
  52. m_pWeatherMgr = NULL;
  53. //MissionArry中0虽然无效,但还是加上去,容错.TotalCount 为空间减1,所以不会越界
  54. for (int i = 0; i <= m_MissionArray.GetTotalCount(); i ++)
  55. {
  56. m_MissionArray.m_Data[i].SetOwner(this);
  57. }
  58. #endif
  59. m_nTotalRegion = m_nWorldRegionWidth * m_nWorldRegionHeight;
  60. }
  61. KSubWorld::~KSubWorld()
  62. {
  63. if (m_Region)
  64. {
  65. delete [] m_Region;
  66. m_Region = NULL;
  67. }
  68. #ifdef _SERVER
  69. if(m_pWeatherMgr)
  70. {
  71. delete m_pWeatherMgr;
  72. m_pWeatherMgr = NULL;
  73. }
  74. #endif
  75. }
  76. int KSubWorld::FindRegion(int nRegion)
  77. {
  78. for (int i = 0; i < m_nTotalRegion; i++)
  79. {
  80. if (m_Region[i].m_RegionID == nRegion)
  81. return i;
  82. }
  83. return -1;
  84. }
  85. int KSubWorld::FindFreeRegion(int nX, int nY)
  86. {
  87. if (nX == 0 && nY == 0)
  88. {
  89. for (int i = 0; i < m_nTotalRegion; i++)
  90. {
  91. if (m_Region[i].m_RegionID == -1)
  92. return i;
  93. }
  94. }
  95. else
  96. {
  97. for (int i = 0; i < m_nTotalRegion; i++)
  98. {
  99. if (m_Region[i].m_RegionID == -1)
  100. return i;
  101. int nRegoinX = LOWORD(m_Region[i].m_RegionID);
  102. int nRegoinY = HIWORD(m_Region[i].m_RegionID);
  103. if ((nX - nRegoinX) * (nX - nRegoinX) + (nY - nRegoinY) * (nY - nRegoinY) > 2) // 不在附近
  104. return i;
  105. }
  106. }
  107. return -1;
  108. }
  109. extern int nActiveRegionCount;
  110. void KSubWorld::Activate()
  111. {
  112. if (m_SubWorldID == -1)
  113. return;
  114. m_dwCurrentTime ++;
  115. #ifndef _SERVER
  116. g_ScenePlace.SetCurrentTime(m_dwCurrentTime);
  117. NpcSet.ClearActivateFlagOfAllNpc();
  118. #endif
  119. for (int i = 0; i < m_nTotalRegion; i++)
  120. {
  121. if (m_Region[i].IsActive())
  122. {
  123. // g_DebugLog("[Region]%d Activating", i);
  124. m_Region[i].Activate();
  125. nActiveRegionCount++;
  126. }
  127. }
  128. #ifdef _SERVER
  129. KIndexNode* pNode = (KIndexNode *)m_NoneRegionNpcList.GetHead();
  130. while(pNode)
  131. {
  132. Npc[pNode->m_nIndex].Activate();
  133. pNode = (KIndexNode *)pNode->GetNext();
  134. }
  135. if(m_pWeatherMgr)
  136. {
  137. int nWeather = m_pWeatherMgr->Activate();
  138. if(m_nWeather != nWeather)
  139. {
  140. m_nWeather = nWeather;
  141. SYNC_WEATHER weatherMsg;
  142. weatherMsg.ProtocolType = s2c_changeweather;
  143. weatherMsg.WeatherID = (BYTE)m_nWeather;
  144. BroadCast((const char*)&weatherMsg, sizeof(SYNC_WEATHER));
  145. }
  146. }
  147. m_MissionArray.Activate();
  148. #endif
  149. }
  150. int KSubWorld::GetDistance(int nRx1, int nRy1, int nRx2, int nRy2)
  151. {
  152. return (int)sqrt((nRx1 - nRx2) * (nRx1 - nRx2) + (nRy1 - nRy2) * (nRy1 - nRy2));
  153. }
  154. void KSubWorld::Map2Mps(int nR, int nX, int nY, int nDx, int nDy, int *nRx, int *nRy)
  155. {
  156. /*
  157. #ifdef TOOLVERION
  158. *nRx = nX;
  159. *nRy = nY;
  160. return;
  161. #endif
  162. */
  163. #ifndef _SERVER
  164. // _ASSERT(nR >= 0 && nR < 9);
  165. #endif
  166. //_ASSERT(nR >= 0);
  167. if (nR < 0 || nR >= m_nTotalRegion)
  168. {
  169. *nRx = 0;
  170. *nRy = 0;
  171. return;
  172. }
  173. int x, y;
  174. x = m_Region[nR].m_nRegionX;
  175. y = m_Region[nR].m_nRegionY;
  176. x += nX * m_nCellWidth;
  177. y += nY * m_nCellHeight;
  178. x += (nDx >> 10);
  179. y += (nDy >> 10);
  180. *nRx = x;
  181. *nRy = y;
  182. }
  183. void KSubWorld::Map2Mps(int nRx, int nRy, int nX, int nY, int nDx, int nDy, int *pnX, int *pnY)
  184. {
  185. *pnX = (nRx * REGION_GRID_WIDTH + nX) * defLOGIC_CELL_WIDTH + (nDx >> 10);
  186. *pnY = (nRy * REGION_GRID_HEIGHT + nY) * defLOGIC_CELL_HEIGHT + (nDy >> 10);
  187. }
  188. void KSubWorld::Mps2Map(int Rx, int Ry, int * nR, int * nX, int * nY, int *nDx, int * nDy)
  189. {
  190. if (m_nCellWidth == 0 || m_nCellHeight == 0 || m_nRegionWidth == 0 || m_nRegionHeight == 0)
  191. return;
  192. int x = Rx / (m_nRegionWidth * m_nCellWidth);
  193. int y = Ry / (m_nRegionHeight * m_nCellHeight);
  194. *nX = 0;
  195. *nY = 0;
  196. *nDx = 0;
  197. *nDy = 0;
  198. #ifdef _SERVER
  199. // 非法的坐标
  200. if (x >= m_nWorldRegionWidth + m_nRegionBeginX || y >= m_nWorldRegionHeight + m_nRegionBeginY || x < m_nRegionBeginX || y < m_nRegionBeginY)
  201. {
  202. *nR = -1;
  203. return;
  204. }
  205. #endif
  206. // 非法的坐标
  207. #ifdef _SERVER
  208. *nR = GetRegionIndex(MAKELONG(x, y));
  209. #else
  210. int nRegionID = MAKELONG(x, y);
  211. *nR = FindRegion(nRegionID);
  212. if (*nR == -1)
  213. return;
  214. #endif
  215. if (*nR >= m_nTotalRegion)
  216. {
  217. *nR = -1;
  218. return;
  219. }
  220. x = Rx - m_Region[*nR].m_nRegionX;
  221. y = Ry - m_Region[*nR].m_nRegionY;
  222. *nX = x / m_nCellWidth;
  223. *nY = y / m_nCellHeight;
  224. *nDx = (x - *nX * m_nCellWidth) << 10;
  225. *nDy = (y - *nY * m_nCellHeight) << 10;
  226. }
  227. BYTE KSubWorld::TestBarrier(int nMpsX, int nMpsY)
  228. {
  229. if (m_nCellWidth == 0 || m_nCellHeight == 0 || m_nRegionWidth == 0 || m_nRegionHeight == 0)
  230. return 0xff;
  231. int x = nMpsX / (m_nRegionWidth * m_nCellWidth);
  232. int y = nMpsY / (m_nRegionHeight * m_nCellHeight);
  233. #ifdef _SERVER
  234. // 非法的坐标
  235. if (x >= m_nWorldRegionWidth + m_nRegionBeginX || y >= m_nWorldRegionHeight + m_nRegionBeginY || x < m_nRegionBeginX || y < m_nRegionBeginY)
  236. return 0xff;
  237. int nRegion = GetRegionIndex(MAKELONG(x, y));
  238. #else
  239. int nRegion = FindRegion(MAKELONG(x, y));
  240. if (nRegion == -1)
  241. return 0xff;
  242. #endif
  243. if (nRegion >= m_nTotalRegion)
  244. return 0xff;
  245. x = nMpsX - m_Region[nRegion].m_nRegionX;
  246. y = nMpsY - m_Region[nRegion].m_nRegionY;
  247. int nCellX = x / m_nCellWidth;
  248. int nCellY = y / m_nCellHeight;
  249. int nOffX = x - nCellX * m_nCellWidth;
  250. int nOffY = y - nCellY * m_nCellHeight;
  251. #ifndef _SERVER
  252. BYTE bRet = (BYTE)g_ScenePlace.GetObstacleInfo(nMpsX, nMpsY);
  253. if (bRet != Obstacle_NULL)
  254. return bRet;
  255. return m_Region[nRegion].GetBarrier(nCellX, nCellY, nOffX, nOffY);
  256. #endif
  257. #ifdef _SERVER
  258. return m_Region[nRegion].GetBarrier(nCellX, nCellY, nOffX, nOffY);
  259. #endif
  260. }
  261. BYTE KSubWorld::TestBarrier(int nRegion, int nMapX, int nMapY, int nDx, int nDy, int nChangeX, int nChangeY)
  262. {
  263. int nOldMapX = nMapX;
  264. int nOldMapY = nMapY;
  265. int nOldRegion = nRegion;
  266. nDx += nChangeX;
  267. nDy += nChangeY;
  268. if (nDx < 0)
  269. {
  270. nDx += (m_nCellWidth << 10);
  271. nMapX--;
  272. }
  273. else if (nDx >= (m_nCellWidth << 10))
  274. {
  275. nDx -= (m_nCellWidth << 10);
  276. nMapX++;
  277. }
  278. if (nDy < 0)
  279. {
  280. nDy += (m_nCellHeight << 10);
  281. nMapY--;
  282. }
  283. else if (nDy >= (m_nCellHeight << 10))
  284. {
  285. nDy -= (m_nCellHeight << 10);
  286. nMapY++;
  287. }
  288. if (nMapX < 0)
  289. {
  290. if (m_Region[nRegion].m_nConnectRegion[DIR_LEFT] == -1)
  291. return 0xff;
  292. nRegion = m_Region[nRegion].m_nConnectRegion[DIR_LEFT];
  293. nMapX += m_nRegionWidth;
  294. }
  295. else if (nMapX >= m_nRegionWidth)
  296. {
  297. if (m_Region[nRegion].m_nConnectRegion[DIR_RIGHT] == -1)
  298. return 0xff;
  299. nRegion = m_Region[nRegion].m_nConnectRegion[DIR_RIGHT];
  300. nMapX -= m_nRegionWidth;
  301. }
  302. if (nMapY < 0)
  303. {
  304. if (m_Region[nRegion].m_nConnectRegion[DIR_UP] == -1)
  305. return 0xff;
  306. nRegion = m_Region[nRegion].m_nConnectRegion[DIR_UP];;
  307. nMapY += m_nRegionHeight;
  308. }
  309. else if (nMapY >= m_nRegionHeight)
  310. {
  311. if (m_Region[nRegion].m_nConnectRegion[DIR_DOWN] == -1)
  312. return 0xff;
  313. nRegion = m_Region[nRegion].m_nConnectRegion[DIR_DOWN];
  314. nMapY -= m_nRegionHeight;
  315. }
  316. int nXf, nYf;
  317. nXf = (nDx >> 10);
  318. nYf = (nDy >> 10);
  319. #ifdef TOOLVERSION
  320. return Obstacle_NULL;
  321. #endif
  322. #ifndef _SERVER
  323. int nMpsX, nMpsY;
  324. Map2Mps(nRegion, nMapX, nMapY, nDx, nDy, &nMpsX, &nMpsY);
  325. BYTE bRet = (BYTE)g_ScenePlace.GetObstacleInfo(nMpsX, nMpsY);
  326. if (bRet != Obstacle_NULL)
  327. return bRet;
  328. // if (nMapX == nOldMapX && nMapY == nOldMapY && nRegion == nOldRegion)
  329. // return Obstacle_NULL;
  330. return m_Region[nRegion].GetBarrier(nMapX, nMapY, nXf, nYf);
  331. #else
  332. // if (nMapX == nOldMapX && nMapY == nOldMapY && nRegion == nOldRegion)
  333. // return 0;
  334. return m_Region[nRegion].GetBarrier(nMapX, nMapY, nXf, nYf);
  335. #endif
  336. }
  337. BYTE KSubWorld::TestBarrierMin(int nRegion, int nMapX, int nMapY, int nDx, int nDy, int nChangeX, int nChangeY)
  338. {
  339. int nOldMapX = nMapX;
  340. int nOldMapY = nMapY;
  341. int nOldRegion = nRegion;
  342. nDx += nChangeX;
  343. nDy += nChangeY;
  344. if (nDx < 0)
  345. {
  346. nDx += (m_nCellWidth << 10);
  347. nMapX--;
  348. }
  349. else if (nDx >= (m_nCellWidth << 10))
  350. {
  351. nDx -= (m_nCellWidth << 10);
  352. nMapX++;
  353. }
  354. if (nDy < 0)
  355. {
  356. nDy += (m_nCellHeight << 10);
  357. nMapY--;
  358. }
  359. else if (nDy >= (m_nCellHeight << 10))
  360. {
  361. nDy -= (m_nCellHeight << 10);
  362. nMapY++;
  363. }
  364. if (nMapX < 0)
  365. {
  366. if (m_Region[nRegion].m_nConnectRegion[DIR_LEFT] == -1)
  367. return 0xff;
  368. nRegion = m_Region[nRegion].m_nConnectRegion[DIR_LEFT];
  369. nMapX += m_nRegionWidth;
  370. }
  371. else if (nMapX >= m_nRegionWidth)
  372. {
  373. if (m_Region[nRegion].m_nConnectRegion[DIR_RIGHT] == -1)
  374. return 0xff;
  375. nRegion = m_Region[nRegion].m_nConnectRegion[DIR_RIGHT];
  376. nMapX -= m_nRegionWidth;
  377. }
  378. if (nMapY < 0)
  379. {
  380. if (m_Region[nRegion].m_nConnectRegion[DIR_UP] == -1)
  381. return 0xff;
  382. nRegion = m_Region[nRegion].m_nConnectRegion[DIR_UP];;
  383. nMapY += m_nRegionHeight;
  384. }
  385. else if (nMapY >= m_nRegionHeight)
  386. {
  387. if (m_Region[nRegion].m_nConnectRegion[DIR_DOWN] == -1)
  388. return 0xff;
  389. nRegion = m_Region[nRegion].m_nConnectRegion[DIR_DOWN];
  390. nMapY -= m_nRegionHeight;
  391. }
  392. #ifndef _SERVER
  393. int nMpsX, nMpsY;
  394. Map2Mps(nRegion, nMapX, nMapY, nDx, nDy, &nMpsX, &nMpsY);
  395. BYTE bRet = (BYTE)g_ScenePlace.GetObstacleInfoMin(nMpsX, nMpsY, nDx & 0x000003ff, nDy & 0x000003ff);
  396. if (bRet != Obstacle_NULL)
  397. return bRet;
  398. if (nMapX == nOldMapX && nMapY == nOldMapY && nRegion == nOldRegion)
  399. return Obstacle_NULL;
  400. return m_Region[nRegion].GetBarrierMin(nMapX, nMapY, nDx, nDy, TRUE);
  401. #else
  402. if (nMapX == nOldMapX && nMapY == nOldMapY && nRegion == nOldRegion)
  403. {
  404. return m_Region[nRegion].GetBarrierMin(nMapX, nMapY, nDx, nDy, FALSE);
  405. }
  406. return m_Region[nRegion].GetBarrierMin(nMapX, nMapY, nDx, nDy, TRUE);
  407. #endif
  408. }
  409. DWORD KSubWorld::GetTrap(int nMpsX, int nMpsY)
  410. {
  411. int nRegion, nMapX, nMapY, nOffX, nOffY;
  412. Mps2Map(nMpsX, nMpsY, &nRegion, &nMapX, &nMapY, &nOffX, &nOffY);
  413. if (nRegion == -1)
  414. return 0;
  415. return m_Region[nRegion].GetTrap(nMapX, nMapY);
  416. }
  417. BYTE KSubWorld::GetBarrier(int nMpsX, int nMpsY)
  418. {
  419. #ifdef _SERVER
  420. int nRegion, nMapX, nMapY, nOffX, nOffY;
  421. Mps2Map(nMpsX, nMpsY, &nRegion, &nMapX, &nMapY, &nOffX, &nOffY);
  422. if (nRegion == -1)
  423. return 0xff;
  424. return m_Region[nRegion].GetBarrier(nMapX, nMapY, (nOffX >> 10), (nOffY) >> 10);
  425. #else
  426. return (BYTE)g_ScenePlace.GetObstacleInfo(nMpsX, nMpsY);
  427. #endif
  428. }
  429. #ifdef _SERVER
  430. BOOL KSubWorld::LoadMap(int nId)
  431. {
  432. KIniFile IniFile;
  433. char szPathName[FILE_NAME_LENGTH];
  434. char szFileName[FILE_NAME_LENGTH];
  435. char szKeyName[32];
  436. m_SubWorldID = nId;
  437. g_SetFilePath("\settings");
  438. IniFile.Load("MapList.ini");
  439. sprintf(szKeyName, "%d", nId);
  440. IniFile.GetString("List", szKeyName, "", szPathName, sizeof(szPathName));
  441. g_SetFilePath("\maps");
  442. sprintf(szFileName, "%s.wor", szPathName);
  443. if (!IniFile.Load(szFileName))
  444. return FALSE;
  445. int nIsInDoor;
  446. IniFile.GetInteger("MAIN", "IsInDoor", 0, &nIsInDoor);
  447. if(!nIsInDoor)
  448. {
  449. m_pWeatherMgr = new KWeatherMgr;
  450. m_pWeatherMgr->InitFromIni(IniFile);
  451. }
  452. m_nRegionWidth = 512 / 32;
  453. m_nRegionHeight = 1024 / 32;
  454. RECT sRect;
  455. IniFile.GetRect("MAIN", "rect", &sRect);
  456. m_nRegionBeginX = sRect.left;
  457. m_nRegionBeginY = sRect.top;
  458. m_nWorldRegionWidth = sRect.right - sRect.left + 1;
  459. m_nWorldRegionHeight = sRect.bottom - sRect.top + 1;
  460. m_nTotalRegion = m_nWorldRegionWidth * m_nWorldRegionHeight;
  461. m_nCellWidth = defLOGIC_CELL_WIDTH;
  462. m_nCellHeight = defLOGIC_CELL_HEIGHT;
  463. if (m_nTotalRegion <= 0 || m_nWorldRegionWidth <= 0 || m_nWorldRegionHeight <= 0)
  464. return FALSE;
  465. m_Region = new KRegion[m_nTotalRegion];
  466. char szPath[MAX_PATH];
  467. sprintf(szPath, "\maps\%s", szPathName);
  468. int nX, nY, nIdx;
  469. // 加载地图障碍,并连接各Region
  470. for (nY = 0; nY < m_nWorldRegionHeight; nY++)
  471. {
  472. for (nX = 0; nX < m_nWorldRegionWidth; nX++)
  473. {
  474. char szRegionPath[128];
  475. g_SetFilePath(szPath);
  476. nIdx = nY * m_nWorldRegionWidth + nX;
  477. if (m_Region[nIdx].Load(nX + m_nRegionBeginX, nY + m_nRegionBeginY))
  478. {
  479. m_Region[nIdx].Init(m_nRegionWidth, m_nRegionHeight);
  480. m_Region[nIdx].m_nIndex = nIdx;
  481. }
  482. for (int i = 0; i < 8; i++)
  483. {
  484. short nTmpX, nTmpY;
  485. nTmpX = (short)LOWORD(m_Region[nIdx].m_nConRegionID[i]) - m_nRegionBeginX;
  486. nTmpY = (short)HIWORD(m_Region[nIdx].m_nConRegionID[i]) - m_nRegionBeginY;
  487. if (nTmpX < 0 || nTmpY < 0 || nTmpX >= m_nWorldRegionWidth || nTmpY >= m_nWorldRegionHeight)
  488. {
  489. m_Region[nIdx].m_nConnectRegion[i] = -1;
  490. continue;
  491. }
  492. int nConIdx = nTmpY * m_nWorldRegionWidth + nTmpX;
  493. m_Region[nIdx].m_nConnectRegion[i] = nConIdx;
  494. }
  495. }
  496. }
  497. sprintf(szPath, "\maps\%s", szPathName);
  498. for (nY = 0; nY < m_nWorldRegionHeight; nY++)
  499. {
  500. for (nX = 0; nX < m_nWorldRegionWidth; nX++)
  501. {
  502. g_SetFilePath(szPath);
  503. m_Region[nY * m_nWorldRegionWidth + nX].LoadObject(m_nIndex,nX + m_nRegionBeginX, nY + m_nRegionBeginY);
  504. }
  505. }
  506. return TRUE;
  507. }
  508. #endif
  509. #ifndef _SERVER
  510. BOOL KSubWorld::LoadMap(int nId, int nRegion)
  511. {
  512. static int nXOff[8] = {0, -1, -1, -1, 0,  1, 1, 1};
  513. static int nYOff[8] = {1, 1,  0,  -1, -1, -1, 0, 1};
  514. KIniFile IniFile;
  515. if (!m_Region)
  516. {
  517. m_Region = new KRegion[MAX_REGION];
  518. }
  519. if (nId != m_SubWorldID)
  520. {
  521. SubWorld[0].Close();
  522. g_ScenePlace.ClosePlace();
  523. // NpcSet.RemoveAll(Player[CLIENT_PLAYER_INDEX].m_nIndex); -- later finish it. spe
  524. char szKeyName[32], szPathName[FILE_NAME_LENGTH];
  525. g_SetFilePath("\settings");
  526. IniFile.Load("MapList.ini");
  527. sprintf(szKeyName, "%d", nId);
  528. IniFile.GetString("List", szKeyName, "", szPathName, sizeof(szPathName));
  529. sprintf(m_szMapPath, "\maps\%s", szPathName);
  530. g_ScenePlace.OpenPlace(nId);
  531. m_SubWorldID = nId;
  532. m_nRegionWidth = KScenePlaceRegionC::RWPP_AREGION_WIDTH / 32;
  533. m_nRegionHeight = KScenePlaceRegionC::RWPP_AREGION_HEIGHT / 32;
  534. m_nCellWidth = 32;
  535. m_nCellHeight = 32;
  536. Npc[Player[CLIENT_PLAYER_INDEX].m_nIndex].m_RegionIndex = -1;
  537. }
  538. int nX = LOWORD(nRegion);
  539. int nY = HIWORD(nRegion);
  540. int nIdx = FindRegion(nRegion);
  541. if (nIdx < 0)
  542. {
  543. nIdx = m_ClientRegionIdx[0];
  544. if (m_Region[nIdx].Load(nX, nY))
  545. {
  546. m_Region[nIdx].m_nIndex = nIdx;
  547. m_Region[nIdx].Init(m_nRegionWidth, m_nRegionHeight);
  548. m_Region[nIdx].LoadObject(0, nX, nY, m_szMapPath);
  549. }
  550. }
  551. g_ScenePlace.SetFocusPosition(m_Region[nIdx].m_nRegionX, m_Region[nIdx].m_nRegionY, 0);
  552. m_ClientRegionIdx[0] = nIdx;
  553. for (int i = 0; i < 8; i++)
  554. {
  555. int nConIdx;
  556. nConIdx = FindRegion(m_Region[nIdx].m_nConRegionID[i]);
  557. if (nConIdx < 0)
  558. {
  559. nConIdx = FindFreeRegion(nX, nY);
  560. _ASSERT(nConIdx >= 0);
  561. if (m_Region[nConIdx].Load(nX + nXOff[i], nY + nYOff[i]))
  562. {
  563. m_Region[nConIdx].m_nIndex = nConIdx;
  564. m_Region[nConIdx].Init(m_nRegionWidth, m_nRegionHeight);
  565. m_Region[nConIdx].LoadObject(0, nX + nXOff[i], nY + nYOff[i], m_szMapPath);
  566. }
  567. else
  568. {
  569. m_Region[nConIdx].m_nIndex = -1;
  570. m_Region[nConIdx].m_RegionID = -1;
  571. nConIdx = -1;
  572. }
  573. }
  574. m_ClientRegionIdx[i + 1] = nConIdx;
  575. m_Region[nIdx].m_nConnectRegion[i] = nConIdx;
  576. }
  577. if (m_Region[nIdx].m_nConnectRegion[0] >= 0)
  578. {
  579. m_Region[m_Region[nIdx].m_nConnectRegion[0]].m_nConnectRegion[0] = -1;
  580. m_Region[m_Region[nIdx].m_nConnectRegion[0]].m_nConnectRegion[1] = -1;
  581. m_Region[m_Region[nIdx].m_nConnectRegion[0]].m_nConnectRegion[7] = -1;
  582. m_Region[m_Region[nIdx].m_nConnectRegion[0]].m_nConnectRegion[4] = nIdx;
  583. m_Region[m_Region[nIdx].m_nConnectRegion[0]].m_nConnectRegion[2] = m_Region[nIdx].m_nConnectRegion[1];
  584. m_Region[m_Region[nIdx].m_nConnectRegion[0]].m_nConnectRegion[3] = m_Region[nIdx].m_nConnectRegion[2];
  585. m_Region[m_Region[nIdx].m_nConnectRegion[0]].m_nConnectRegion[5] = m_Region[nIdx].m_nConnectRegion[6];
  586. m_Region[m_Region[nIdx].m_nConnectRegion[0]].m_nConnectRegion[6] = m_Region[nIdx].m_nConnectRegion[7];
  587. }
  588. if (m_Region[nIdx].m_nConnectRegion[1] >= 0)
  589. {
  590. m_Region[m_Region[nIdx].m_nConnectRegion[1]].m_nConnectRegion[0] = -1;
  591. m_Region[m_Region[nIdx].m_nConnectRegion[1]].m_nConnectRegion[1] = -1;
  592. m_Region[m_Region[nIdx].m_nConnectRegion[1]].m_nConnectRegion[7] = -1;
  593. m_Region[m_Region[nIdx].m_nConnectRegion[1]].m_nConnectRegion[4] = m_Region[nIdx].m_nConnectRegion[2];
  594. m_Region[m_Region[nIdx].m_nConnectRegion[1]].m_nConnectRegion[2] = -1;
  595. m_Region[m_Region[nIdx].m_nConnectRegion[1]].m_nConnectRegion[3] = -1;
  596. m_Region[m_Region[nIdx].m_nConnectRegion[1]].m_nConnectRegion[5] = nIdx;
  597. m_Region[m_Region[nIdx].m_nConnectRegion[1]].m_nConnectRegion[6] = m_Region[nIdx].m_nConnectRegion[0];
  598. }
  599. if (m_Region[nIdx].m_nConnectRegion[2] >= 0)
  600. {
  601. m_Region[m_Region[nIdx].m_nConnectRegion[2]].m_nConnectRegion[0] = m_Region[nIdx].m_nConnectRegion[1];
  602. m_Region[m_Region[nIdx].m_nConnectRegion[2]].m_nConnectRegion[1] = -1;
  603. m_Region[m_Region[nIdx].m_nConnectRegion[2]].m_nConnectRegion[7] = m_Region[nIdx].m_nConnectRegion[0];
  604. m_Region[m_Region[nIdx].m_nConnectRegion[2]].m_nConnectRegion[4] = m_Region[nIdx].m_nConnectRegion[3];
  605. m_Region[m_Region[nIdx].m_nConnectRegion[2]].m_nConnectRegion[2] = -1;
  606. m_Region[m_Region[nIdx].m_nConnectRegion[2]].m_nConnectRegion[3] = -1;
  607. m_Region[m_Region[nIdx].m_nConnectRegion[2]].m_nConnectRegion[5] = m_Region[nIdx].m_nConnectRegion[4];
  608. m_Region[m_Region[nIdx].m_nConnectRegion[2]].m_nConnectRegion[6] = nIdx;
  609. }
  610. if (m_Region[nIdx].m_nConnectRegion[3] >= 0)
  611. {
  612. m_Region[m_Region[nIdx].m_nConnectRegion[3]].m_nConnectRegion[0] = m_Region[nIdx].m_nConnectRegion[2];
  613. m_Region[m_Region[nIdx].m_nConnectRegion[3]].m_nConnectRegion[1] = -1;
  614. m_Region[m_Region[nIdx].m_nConnectRegion[3]].m_nConnectRegion[2] = -1;
  615. m_Region[m_Region[nIdx].m_nConnectRegion[3]].m_nConnectRegion[3] = -1;
  616. m_Region[m_Region[nIdx].m_nConnectRegion[3]].m_nConnectRegion[4] = -1;
  617. m_Region[m_Region[nIdx].m_nConnectRegion[3]].m_nConnectRegion[5] = -1;
  618. m_Region[m_Region[nIdx].m_nConnectRegion[3]].m_nConnectRegion[6] = m_Region[nIdx].m_nConnectRegion[4];
  619. m_Region[m_Region[nIdx].m_nConnectRegion[3]].m_nConnectRegion[7] = nIdx;
  620. }
  621. if (m_Region[nIdx].m_nConnectRegion[4] >= 0)
  622. {
  623. m_Region[m_Region[nIdx].m_nConnectRegion[4]].m_nConnectRegion[0] = nIdx;
  624. m_Region[m_Region[nIdx].m_nConnectRegion[4]].m_nConnectRegion[1] = m_Region[nIdx].m_nConnectRegion[2];
  625. m_Region[m_Region[nIdx].m_nConnectRegion[4]].m_nConnectRegion[2] = m_Region[nIdx].m_nConnectRegion[3];
  626. m_Region[m_Region[nIdx].m_nConnectRegion[4]].m_nConnectRegion[3] = -1;
  627. m_Region[m_Region[nIdx].m_nConnectRegion[4]].m_nConnectRegion[4] = -1;
  628. m_Region[m_Region[nIdx].m_nConnectRegion[4]].m_nConnectRegion[5] = -1;
  629. m_Region[m_Region[nIdx].m_nConnectRegion[4]].m_nConnectRegion[6] = m_Region[nIdx].m_nConnectRegion[5];
  630. m_Region[m_Region[nIdx].m_nConnectRegion[4]].m_nConnectRegion[7] = m_Region[nIdx].m_nConnectRegion[6];
  631. }
  632. if (m_Region[nIdx].m_nConnectRegion[5] >= 0)
  633. {
  634. m_Region[m_Region[nIdx].m_nConnectRegion[5]].m_nConnectRegion[0] = m_Region[nIdx].m_nConnectRegion[6];
  635. m_Region[m_Region[nIdx].m_nConnectRegion[5]].m_nConnectRegion[1] = nIdx;
  636. m_Region[m_Region[nIdx].m_nConnectRegion[5]].m_nConnectRegion[2] = m_Region[nIdx].m_nConnectRegion[4];
  637. m_Region[m_Region[nIdx].m_nConnectRegion[5]].m_nConnectRegion[3] = -1;
  638. m_Region[m_Region[nIdx].m_nConnectRegion[5]].m_nConnectRegion[4] = -1;
  639. m_Region[m_Region[nIdx].m_nConnectRegion[5]].m_nConnectRegion[5] = -1;
  640. m_Region[m_Region[nIdx].m_nConnectRegion[5]].m_nConnectRegion[6] = -1;
  641. m_Region[m_Region[nIdx].m_nConnectRegion[5]].m_nConnectRegion[7] = -1;
  642. }
  643. if (m_Region[nIdx].m_nConnectRegion[6] >= 0)
  644. {
  645. m_Region[m_Region[nIdx].m_nConnectRegion[6]].m_nConnectRegion[0] = m_Region[nIdx].m_nConnectRegion[7];
  646. m_Region[m_Region[nIdx].m_nConnectRegion[6]].m_nConnectRegion[1] = m_Region[nIdx].m_nConnectRegion[0];
  647. m_Region[m_Region[nIdx].m_nConnectRegion[6]].m_nConnectRegion[2] = nIdx;
  648. m_Region[m_Region[nIdx].m_nConnectRegion[6]].m_nConnectRegion[3] = m_Region[nIdx].m_nConnectRegion[4];
  649. m_Region[m_Region[nIdx].m_nConnectRegion[6]].m_nConnectRegion[4] = m_Region[nIdx].m_nConnectRegion[5];
  650. m_Region[m_Region[nIdx].m_nConnectRegion[6]].m_nConnectRegion[5] = -1;
  651. m_Region[m_Region[nIdx].m_nConnectRegion[6]].m_nConnectRegion[6] = -1;
  652. m_Region[m_Region[nIdx].m_nConnectRegion[6]].m_nConnectRegion[7] = -1;
  653. }
  654. if (m_Region[nIdx].m_nConnectRegion[7] >= 0)
  655. {
  656. m_Region[m_Region[nIdx].m_nConnectRegion[7]].m_nConnectRegion[0] = -1;
  657. m_Region[m_Region[nIdx].m_nConnectRegion[7]].m_nConnectRegion[1] = -1;
  658. m_Region[m_Region[nIdx].m_nConnectRegion[7]].m_nConnectRegion[2] = m_Region[nIdx].m_nConnectRegion[0];
  659. m_Region[m_Region[nIdx].m_nConnectRegion[7]].m_nConnectRegion[3] = nIdx;
  660. m_Region[m_Region[nIdx].m_nConnectRegion[7]].m_nConnectRegion[4] = m_Region[nIdx].m_nConnectRegion[6];
  661. m_Region[m_Region[nIdx].m_nConnectRegion[7]].m_nConnectRegion[5] = -1;
  662. m_Region[m_Region[nIdx].m_nConnectRegion[7]].m_nConnectRegion[6] = -1;
  663. m_Region[m_Region[nIdx].m_nConnectRegion[7]].m_nConnectRegion[7] = -1;
  664. }
  665. return TRUE;
  666. }
  667. #endif
  668. void KSubWorld::LoadTrap()
  669. {
  670. }
  671. void KSubWorld::MessageLoop()
  672. {
  673. KWorldMsgNode Msg;
  674. while(m_WorldMessage.Get(&Msg))
  675. {
  676. ProcessMsg(&Msg);
  677. }
  678. }
  679. void KSubWorld::ProcessMsg(KWorldMsgNode *pMsg)
  680. {
  681. switch(pMsg->m_dwMsgType)
  682. {
  683. case GWM_NPC_DEL:
  684. #ifndef _SERVER
  685. if (Npc[pMsg->m_nParam[0]].m_RegionIndex >= 0)
  686. {
  687. int nIdx = pMsg->m_nParam[0];
  688. int nSubWorld = Npc[nIdx].m_SubWorldIndex;
  689. int nRegion = Npc[nIdx].m_RegionIndex;
  690. SubWorld[nSubWorld].m_Region[nRegion].RemoveNpc(nIdx);
  691. SubWorld[nSubWorld].m_Region[nRegion].DecRef(Npc[nIdx].m_MapX, Npc[nIdx].m_MapY, obj_npc);
  692. }
  693. NpcSet.Remove(pMsg->m_nParam[0]);
  694. #else
  695. {
  696. int nIdx = pMsg->m_nParam[0];
  697. int nSubWorld = Npc[nIdx].m_SubWorldIndex;
  698. int nRegion = Npc[nIdx].m_RegionIndex;
  699. SubWorld[nSubWorld].m_Region[nRegion].RemoveNpc(nIdx);
  700. SubWorld[nSubWorld].m_Region[nRegion].DecRef(Npc[nIdx].m_MapX, Npc[nIdx].m_MapY, obj_npc);
  701. NpcSet.Remove(nIdx);
  702. }
  703. #endif
  704. break;
  705. /* case GWM_NPC_CHANGE_REGION:
  706. NpcChangeRegion(pMsg->m_nParam[0], pMsg->m_nParam[1], pMsg->m_nParam[2]);
  707. break;*/
  708. case GWM_OBJ_DEL:
  709. #ifndef _SERVER
  710. if (Object[pMsg->m_nParam[0]].m_nRegionIdx >= 0)
  711. SubWorld[Object[pMsg->m_nParam[0]].m_nSubWorldID].m_Region[Object[pMsg->m_nParam[0]].m_nRegionIdx].RemoveObj(pMsg->m_nParam[0]);
  712. ObjSet.Remove(pMsg->m_nParam[0]);
  713. #else
  714. SubWorld[Object[pMsg->m_nParam[0]].m_nSubWorldID].m_Region[Object[pMsg->m_nParam[0]].m_nRegionIdx].RemoveObj(pMsg->m_nParam[0]);
  715. ObjSet.Remove(pMsg->m_nParam[0]);
  716. #endif
  717. break;
  718. case GWM_OBJ_CHANGE_REGION:
  719. ObjChangeRegion(pMsg->m_nParam[0], pMsg->m_nParam[1], pMsg->m_nParam[2]);
  720. break;
  721. case GWM_MISSLE_CHANGE_REGION:
  722. MissleChangeRegion(pMsg->m_nParam[0], pMsg->m_nParam[1], pMsg->m_nParam[2]);
  723. break;
  724. case GWM_MISSLE_DEL:
  725. #ifndef _SERVER
  726. if (Missle[pMsg->m_nParam[0]].m_nRegionId >= 0)
  727. {
  728. SubWorld[Missle[pMsg->m_nParam[0]].m_nSubWorldId].m_Region[Missle[pMsg->m_nParam[0]].m_nRegionId].RemoveMissle(pMsg->m_nParam[0]);
  729. // g_DebugLog("[Missle]Missle%dDEL", pMsg->m_nParam[0]);
  730. MissleSet.Remove(pMsg->m_nParam[0]);
  731. }
  732. #else
  733. SubWorld[Missle[pMsg->m_nParam[0]].m_nSubWorldId].m_Region[Missle[pMsg->m_nParam[0]].m_nRegionId].RemoveMissle(pMsg->m_nParam[0]);
  734. MissleSet.Remove(pMsg->m_nParam[0]);
  735. #endif
  736. break;
  737. /* case GWM_PLAYER_CHANGE_REGION:
  738. PlayerChangeRegion(pMsg->m_nParam[0], pMsg->m_nParam[1], pMsg->m_nParam[2]);
  739. break;*/
  740. default:
  741. break;
  742. }
  743. }
  744. #ifdef _SERVER
  745. void KSubWorld::NpcChangeRegion(int nSrcRnidx, int nDesRnIdx, int nIdx)
  746. {
  747. if (nIdx <= 0 || nIdx >= MAX_NPC)
  748. return;
  749. Npc[nIdx].SetActiveFlag(TRUE);
  750. if (nSrcRnidx == -1)
  751. {
  752. _ASSERT(nDesRnIdx >= 0);
  753. if (nDesRnIdx >= 0)
  754. {
  755. m_Region[nDesRnIdx].AddNpc(nIdx);
  756. Npc[nIdx].m_RegionIndex = nDesRnIdx;
  757. }
  758. return;
  759. }
  760. else if (nSrcRnidx == VOID_REGION)
  761. {
  762. Npc[nIdx].m_Node.Remove();
  763. Npc[nIdx].m_Node.Release();
  764. }
  765. else if (nSrcRnidx >= 0)
  766. {
  767. SubWorld[Npc[nIdx].m_SubWorldIndex].m_Region[nSrcRnidx].RemoveNpc(nIdx);
  768. if (nDesRnIdx != VOID_REGION) // 不是加入到死亡重生链表
  769. Npc[nIdx].m_RegionIndex = -1;
  770. }
  771. if (nDesRnIdx >= 0)
  772. {
  773. m_Region[nDesRnIdx].AddNpc(nIdx);
  774. Npc[nIdx].m_RegionIndex = nDesRnIdx;
  775. }
  776. else if (nDesRnIdx == VOID_REGION)
  777. {
  778. m_NoneRegionNpcList.AddTail(&Npc[nIdx].m_Node);
  779. Npc[nIdx].m_Node.AddRef();
  780. }
  781. }
  782. #endif
  783. #ifndef _SERVER
  784. void KSubWorld::NpcChangeRegion(int nSrcRnidx, int nDesRnIdx, int nIdx)
  785. {
  786. int nSrc, nDest;
  787. if (nSrcRnidx == -1)
  788. {
  789. nDest = SubWorld[0].FindRegion(nDesRnIdx);
  790. if (nDest < 0)
  791. return;
  792. m_Region[nDest].AddNpc(nIdx);
  793. Npc[nIdx].m_dwRegionID = m_Region[nDest].m_RegionID;
  794. Npc[nIdx].m_RegionIndex = nDest;
  795. return;
  796. }
  797. nSrc = SubWorld[0].FindRegion(nSrcRnidx);
  798. if (nSrc >= 0)
  799. SubWorld[0].m_Region[nSrc].RemoveNpc(nIdx);
  800. nDest = SubWorld[0].FindRegion(nDesRnIdx);
  801. KIndexNode *pNode = &Npc[nIdx].m_Node;
  802. if (nDest >= 0)
  803. {
  804. m_Region[nDest].AddNpc(nIdx);
  805. if (Player[CLIENT_PLAYER_INDEX].m_nIndex == nIdx)
  806. LoadMap(m_SubWorldID, m_Region[nDest].m_RegionID);
  807. Npc[nIdx].m_dwRegionID = m_Region[nDest].m_RegionID;
  808. Npc[nIdx].m_RegionIndex = nDest;
  809. }
  810. else if (Player[CLIENT_PLAYER_INDEX].m_nIndex == nIdx)
  811. {
  812. LoadMap(m_SubWorldID, nDesRnIdx);
  813. nDest = SubWorld[0].FindRegion(nDesRnIdx);
  814. if (nDest >= 0)
  815. {
  816. m_Region[nDest].AddNpc(nIdx);
  817. Npc[nIdx].m_dwRegionID = m_Region[nDest].m_RegionID;
  818. Npc[nIdx].m_RegionIndex = nDest;
  819. }
  820. }
  821. }
  822. #endif
  823. void KSubWorld::ObjChangeRegion(int nSrcRnidx, int nDesRnIdx, int nIdx)
  824. {
  825. #ifdef _SERVER
  826. _ASSERT(nSrcRnidx >= 0);
  827. #endif
  828. if (nDesRnIdx == -1)
  829. {
  830. SubWorld[Object[nIdx].m_nSubWorldID].m_Region[nSrcRnidx].RemoveObj(nIdx);
  831. // ObjSet.Remove(nIdx);
  832. return;
  833. }
  834. if (nSrcRnidx == -1)
  835. {
  836. m_Region[nDesRnIdx].AddObj(nIdx);
  837. return;
  838. }
  839. KIndexNode* pNode = (KIndexNode *)m_Region[nSrcRnidx].GetObjNode(nIdx);
  840. if (pNode)
  841. {
  842. pNode->Remove();
  843. m_Region[nDesRnIdx].m_ObjList.AddTail(pNode);
  844. }
  845. }
  846. void KSubWorld::MissleChangeRegion(int nSrcRnidx, int nDesRnIdx, int nIdx)
  847. {
  848. if (nIdx <= 0 || nIdx >= MAX_MISSLE)
  849. return;
  850. if (nSrcRnidx == -1)
  851. {
  852. m_Region[nDesRnIdx].AddMissle(nIdx);
  853. return;
  854. }
  855. SubWorld[Missle[nIdx].m_nSubWorldId].m_Region[nSrcRnidx].RemoveMissle(nIdx);
  856. if (nDesRnIdx == -1)
  857. {
  858. MissleSet.Remove(nIdx);
  859. return;
  860. }
  861. m_Region[nDesRnIdx].AddMissle(nIdx);
  862. }
  863. #ifdef _SERVER
  864. void KSubWorld::PlayerChangeRegion(int nSrcRnidx, int nDesRnIdx, int nIdx)
  865. {
  866. if (nIdx <= 0 || nIdx >= MAX_PLAYER)
  867. return;
  868. if (nSrcRnidx < 0)
  869. return;
  870. RemovePlayer(nSrcRnidx, nIdx);
  871. if (nDesRnIdx == -1)
  872. {
  873. //PlayerSet.PrepareRemove(Player[nIdx].m_nNetConnectIdx);
  874. printf("Player change region to not exist..., kill itn");
  875. g_pServer->ShutdownClient(Player[nIdx].m_nNetConnectIdx);
  876. return;
  877. }
  878. if (nDesRnIdx >= 0)
  879. {
  880. AddPlayer(nDesRnIdx, nIdx);
  881. }
  882. /* 因为RemovePlayer和AddPlayer已经做了从链表中清除节点,修改周边九个REGION的引用计数的操作了
  883. KIndexNode* pNode = &Player[nIdx].m_Node;
  884. if (pNode->m_Ref > 0)
  885. {
  886. pNode->Remove();
  887. pNode->Release();
  888. }
  889. m_Region[nSrcRnidx].m_nActive--;
  890. if (m_Region[nSrcRnidx].m_nActive < 0)
  891. m_Region[nSrcRnidx].m_nActive = 0;
  892. for (int i = 0; i < 8; i++)
  893. {
  894. if (m_Region[nSrcRnidx].m_nConnectRegion[i] < 0)
  895. continue;
  896. m_Region[m_Region[nSrcRnidx].m_nConnectRegion[i]].m_nActive--;
  897. if (m_Region[m_Region[nSrcRnidx].m_nConnectRegion[i]].m_nActive < 0)
  898. m_Region[m_Region[nSrcRnidx].m_nConnectRegion[i]].m_nActive = 0;
  899. }
  900. if (pNode->m_Ref == 0)
  901. {
  902. m_Region[nDesRnIdx].m_PlayerList.AddTail(pNode);
  903. pNode->AddRef();
  904. }
  905. m_Region[nDesRnIdx].m_nActive++;
  906. for (i = 0; i < 8; i++)
  907. {
  908. if (m_Region[nDesRnIdx].m_nConnectRegion[i] < 0)
  909. continue;
  910. m_Region[m_Region[nDesRnIdx].m_nConnectRegion[i]].m_nActive++;
  911. if (m_Region[m_Region[nDesRnIdx].m_nConnectRegion[i]].m_nActive < 0)
  912. m_Region[m_Region[nDesRnIdx].m_nConnectRegion[i]].m_nActive = 0;
  913. }
  914. */
  915. }
  916. #endif
  917. void KSubWorld::GetMps(int *nX, int *nY, int nSpeed, int nDir, int nMaxDir /* = 64 */)
  918. {
  919. *nX += (g_DirCos(nDir, nMaxDir) * nSpeed) >> 10;
  920. *nY += (g_DirSin(nDir, nMaxDir) * nSpeed) >> 10;
  921. }
  922. #ifdef _SERVER
  923. BOOL KSubWorld::SendSyncData(int nIdx, int nClient)
  924. {
  925. WORLD_SYNC WorldSync;
  926. WorldSync.ProtocolType = (BYTE)s2c_syncworld;
  927. WorldSync.Region = m_Region[Npc[nIdx].m_RegionIndex].m_RegionID;
  928. WorldSync.Weather = m_nWeather;
  929. WorldSync.Frame = m_dwCurrentTime;
  930. WorldSync.SubWorld = m_SubWorldID;
  931. if (SUCCEEDED(g_pServer->PackDataToClient(nClient, (BYTE*)&WorldSync, sizeof(WORLD_SYNC))))
  932. {
  933. return TRUE;
  934. }
  935. else
  936. {
  937. printf("player Packing world sync data failed...n");
  938. return FALSE;
  939. }
  940. }
  941. #endif
  942. #ifndef _SERVER
  943. void KSubWorld::LoadCell()
  944. {
  945. }
  946. #endif
  947. #ifdef TOOLVERSION
  948. int CORE_API g_ScreenX  = 0;
  949. int CORE_API g_ScreenY  = 0;
  950. #endif
  951. #ifndef _SERVER
  952. void KSubWorld::Paint()
  953. {
  954. int nIdx = Player[CLIENT_PLAYER_INDEX].m_nIndex;
  955. int nX, nY;
  956. Map2Mps(Npc[nIdx].m_RegionIndex, Npc[nIdx].m_MapX, Npc[nIdx].m_MapY, Npc[nIdx].m_OffX, Npc[nIdx].m_OffY, &nX, &nY);
  957. // m_nScreenX = nX - 400;
  958. // m_nScreenY = nY - 300;
  959. #ifdef TOOLVERSION
  960. g_ScreenX = nX;
  961. g_ScreenY = nY;
  962. #endif
  963. for (int i = 0; i < m_nTotalRegion; i++)
  964. {
  965. m_Region[i].Paint();
  966. }
  967. }
  968. void KSubWorld::Mps2Screen(int *Rx, int *Ry)
  969. {
  970. }
  971. void KSubWorld::Screen2Mps(int *Rx, int *Ry)
  972. {
  973. }
  974. #endif
  975. #ifdef _SERVER
  976. int KSubWorld::GetRegionIndex(int nRegionID)
  977. {
  978. int nRet;
  979. short nX = (short)LOWORD(nRegionID) - m_nRegionBeginX;
  980. short nY = (short)HIWORD(nRegionID) - m_nRegionBeginY;
  981. if (nX < 0 || nY < 0 || nX >= m_nWorldRegionWidth || nY >= m_nWorldRegionHeight)
  982. return -1;
  983. nRet = nY * m_nWorldRegionWidth + nX;
  984. return nRet;
  985. }
  986. #endif
  987. void KSubWorld::Close()
  988. {
  989. if (m_SubWorldID == -1)
  990. return;
  991. for (int i = 0; i < m_nTotalRegion; i++)
  992. {
  993. m_Region[i].Close();
  994. }
  995. m_WorldMessage.Clear();
  996. m_nIndex = -1;
  997. m_SubWorldID = -1;
  998. }
  999. #ifdef _SERVER
  1000. void KSubWorld::LoadObject(char* szPath, char* szFileName)
  1001. {
  1002. if (!szFileName || !szFileName[0])
  1003. return;
  1004. KIniFile IniFile;
  1005. // 加载世界中的动态物件(Npc、Object、Trap)
  1006. g_SetFilePath(szPath);
  1007. int nObjNumber = 0;
  1008. if (IniFile.Load(szFileName))
  1009. {
  1010. IniFile.GetInteger("MAIN", "elementnum", 0, &nObjNumber);
  1011. }
  1012. int nLength = strlen(szFileName);
  1013. szFileName[nLength - 4] = 0;
  1014. strcat(szPath, "\");
  1015. strcat(szPath, szFileName);
  1016. char szSection[32];
  1017. char szDataFile[32];
  1018. for (int i = 0; i < nObjNumber; i++)
  1019. {
  1020. float fPos[3];
  1021. int nPos[3];
  1022. g_SetFilePath(szPath);
  1023. sprintf(szSection, "%d", i);
  1024. IniFile.GetFloat3(szSection, "groundoffset", fPos);
  1025. nPos[0] = (int)(fPos[0] * 32);
  1026. nPos[1] = (int)(fPos[1] * 32);
  1027. nPos[2] = (int)fPos[2];
  1028. szDataFile[0] = 0;
  1029. IniFile.GetString(szSection, "event", "", szDataFile, sizeof(szDataFile));
  1030. strcat(szDataFile, "_data.ini");
  1031. KIniFile IniChange;
  1032. int nType = 0, nLevel = 0;
  1033. char szName[32];
  1034. if (!IniChange.Load(szDataFile))
  1035. continue;
  1036. IniChange.GetInteger("MAIN", "Type", 0, &nType);
  1037. IniChange.GetInteger("MAIN", "Level", 4, &nLevel);
  1038. IniChange.GetString("MAIN", "mapedit_templatesection", "", szName, sizeof(szName));
  1039. switch(nType)
  1040. {
  1041. case kind_normal: // 普通战斗npc
  1042. {
  1043. int nFindNo = g_NpcSetting.FindRow(szName);
  1044. if (nFindNo == -1)
  1045. continue;
  1046. else
  1047. nFindNo = nFindNo - 2;
  1048. int nSettingInfo = MAKELONG(nLevel, nFindNo);
  1049. NpcSet.Add(nSettingInfo, m_nIndex, nPos[0], nPos[1]);
  1050. }
  1051. break;
  1052. case kind_player:
  1053. break;
  1054. case kind_partner:
  1055. break;
  1056. case kind_dialoger: // 普通非战斗npc
  1057. break;
  1058. case kind_bird: // 客户端only
  1059. break;
  1060. case kind_mouse: // 客户端only
  1061. break;
  1062. default:
  1063. break;
  1064. }
  1065. }
  1066. }
  1067. #endif
  1068. void KSubWorld::AddPlayer(int nRegion, int nIdx)
  1069. {
  1070. if (nRegion < 0 || nRegion >= m_nTotalRegion)
  1071. {
  1072. printf("Region:(%d) Player(%d)n", nRegion, nIdx);
  1073. return;
  1074. }
  1075. if (m_Region[nRegion].AddPlayer(nIdx))
  1076. {
  1077. m_Region[nRegion].m_nActive++;
  1078. for (int i = 0; i < 8; i++)
  1079. {
  1080. int nConRegion = m_Region[nRegion].m_nConnectRegion[i];
  1081. if (nConRegion == -1)
  1082. continue;
  1083. m_Region[nConRegion].m_nActive++;
  1084. }
  1085. }
  1086. else
  1087. {
  1088. printf("Region:(%d) Player(%d)n", nRegion, nIdx);
  1089. }
  1090. }
  1091. void KSubWorld::RemovePlayer(int nRegion, int nIdx)
  1092. {
  1093. if (nRegion < 0 || nRegion >= m_nTotalRegion)
  1094. return;
  1095. if (m_Region[nRegion].RemovePlayer(nIdx))
  1096. {
  1097. m_Region[nRegion].m_nActive--;
  1098. if (m_Region[nRegion].m_nActive < 0)
  1099. {
  1100. _ASSERT(0);
  1101. m_Region[nRegion].m_nActive = 0;
  1102. }
  1103. for (int i = 0; i < 8; i++)
  1104. {
  1105. int nConRegion = m_Region[nRegion].m_nConnectRegion[i];
  1106. if (nConRegion == -1)
  1107. continue;
  1108. m_Region[nConRegion].m_nActive--;
  1109. if (m_Region[nConRegion].m_nActive < 0)
  1110. {
  1111. _ASSERT(0);
  1112. m_Region[nConRegion].m_nActive = 0;
  1113. }
  1114. }
  1115. }
  1116. }
  1117. void KSubWorld::GetFreeObjPos(POINT& pos)
  1118. {
  1119. POINT posLocal = pos;
  1120. POINT posTemp;
  1121. int nLayer = 1;
  1122. if (CanPutObj(posLocal))
  1123. return;
  1124. while(1)
  1125. {
  1126. for (int i = 0; i <= nLayer; i++)
  1127. {
  1128. posTemp.y = posLocal.y + i * 32;
  1129. posTemp.x = posLocal.x + (nLayer - i) * 32;
  1130. if (CanPutObj(posTemp))
  1131. {
  1132. pos = posTemp;
  1133. return;
  1134. }
  1135. posTemp.y = posLocal.y + i * 32;
  1136. posTemp.x = posLocal.x - (nLayer - i) * 32;
  1137. if (CanPutObj(posTemp))
  1138. {
  1139. pos = posTemp;
  1140. return;
  1141. }
  1142. posTemp.y = posLocal.y - i * 32;
  1143. posTemp.x = posLocal.x + (nLayer - i) * 32;
  1144. if (CanPutObj(posTemp))
  1145. {
  1146. pos = posTemp;
  1147. return;
  1148. }
  1149. posTemp.y = posLocal.y - i * 32;
  1150. posTemp.x = posLocal.x - (nLayer - i) * 32;
  1151. if (CanPutObj(posTemp))
  1152. {
  1153. pos = posTemp;
  1154. return;
  1155. }
  1156. }
  1157. nLayer++;
  1158. if (nLayer >= 10)
  1159. break;
  1160. }
  1161. return;
  1162. }
  1163. BOOL KSubWorld::CanPutObj(POINT pos)
  1164. {
  1165. int nRegion, nMapX, nMapY, nOffX, nOffY;
  1166. Mps2Map(pos.x, pos.y, &nRegion, &nMapX, &nMapY, &nOffX, &nOffY);
  1167. if (nRegion >= 0 
  1168. && !m_Region[nRegion].GetBarrier(nMapX, nMapY, nOffX, nOffY) 
  1169. && !m_Region[nRegion].GetRef(nMapX, nMapY, obj_object))
  1170. return TRUE;
  1171. return FALSE;
  1172. }
  1173. #ifdef _SERVER
  1174. void KSubWorld::BroadCast(const char* pBuffer, size_t uSize)
  1175. {
  1176. int nIdx = PlayerSet.GetFirstPlayer();
  1177. while(nIdx)
  1178. {
  1179. if (Player[nIdx].m_nNetConnectIdx >= 0 
  1180. && Player[nIdx].m_nIndex > 0 
  1181. && Npc[Player[nIdx].m_nIndex].m_SubWorldIndex == m_nIndex)
  1182. {
  1183. g_pServer->PackDataToClient(Player[nIdx].m_nNetConnectIdx, pBuffer, uSize);
  1184. }
  1185. nIdx = PlayerSet.GetNextPlayer();
  1186. }
  1187. }
  1188. int KSubWorld::RevivalAllNpc()
  1189. {
  1190. KIndexNode * pNode = NULL;
  1191. size_t ulCount = 0;
  1192. for (int i = 0; i < m_nTotalRegion; i++)
  1193. {
  1194. KRegion * pCurRegion = &m_Region[i];
  1195. pNode = (KIndexNode *)pCurRegion->m_NpcList.GetHead();
  1196. while(pNode)
  1197. {
  1198. int nNpcIdx = pNode->m_nIndex;
  1199. if (!Npc[nNpcIdx].IsPlayer())
  1200. {
  1201. Npc[nNpcIdx].ExecuteRevive();
  1202. }
  1203. pNode = (KIndexNode *)pNode->GetNext();
  1204. }
  1205. }
  1206. pNode = (KIndexNode*)m_NoneRegionNpcList.GetHead();
  1207. while(pNode)
  1208. {
  1209. int nNpcIdx = pNode->m_nIndex;
  1210. if (!Npc[nNpcIdx].IsPlayer())
  1211. {
  1212. Npc[nNpcIdx].m_Frames.nTotalFrame = 1;
  1213. Npc[nNpcIdx].m_Frames.nCurrentFrame = 0;
  1214. ulCount ++;
  1215. }
  1216. pNode = (KIndexNode *)pNode->GetNext();
  1217. }
  1218. return ulCount;
  1219. }
  1220. int KSubWorld::FindNpcFromName(const char * szName)
  1221. {
  1222. if (!szName || !szName[0])
  1223. return 0;
  1224. KIndexNode * pNode = NULL;
  1225. int nResult = 0;
  1226. for (int i = 0; i < m_nTotalRegion; i++)
  1227. {
  1228. KRegion * pCurRegion = &m_Region[i];
  1229. pNode = (KIndexNode *)pCurRegion->m_NpcList.GetHead();
  1230. while(pNode)
  1231. {
  1232. int nNpcIdx = pNode->m_nIndex;
  1233. if (!strcmp(Npc[nNpcIdx].Name, szName))
  1234. {
  1235. nResult = nNpcIdx;
  1236. return nResult;
  1237. }
  1238. pNode = (KIndexNode *)pNode->GetNext();
  1239. }
  1240. }
  1241. pNode = (KIndexNode*)m_NoneRegionNpcList.GetHead();
  1242. while(pNode)
  1243. {
  1244. int nNpcIdx = pNode->m_nIndex;
  1245. if (!strcmp(Npc[nNpcIdx].Name, szName))
  1246. {
  1247. return nNpcIdx;
  1248. }
  1249. pNode = (KIndexNode *)pNode->GetNext();
  1250. }
  1251. return nResult;
  1252. }
  1253. #endif