您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 

507 行
12 KiB

  1. define([
  2. 'world/map',
  3. 'world/syncer',
  4. 'objects/objects',
  5. 'world/spawners',
  6. 'world/physics',
  7. 'world/resourceSpawner',
  8. 'config/spells/spellCallbacks',
  9. 'config/quests/questBuilder',
  10. 'world/randomMap',
  11. 'world/customMap',
  12. 'events/events'
  13. ], function(
  14. map,
  15. syncer,
  16. objects,
  17. spawners,
  18. physics,
  19. resourceSpawner,
  20. spellCallbacks,
  21. questBuilder,
  22. randomMap,
  23. customMap,
  24. events
  25. ) {
  26. return {
  27. instances: [],
  28. zoneId: -1,
  29. speed: 350,
  30. lastTime: 0,
  31. init: function(args) {
  32. this.zoneId = args.zoneId;
  33. spellCallbacks.init();
  34. map.init(args);
  35. if (!map.instanced) {
  36. var fakeInstance = {
  37. objects: objects,
  38. syncer: syncer,
  39. physics: physics,
  40. zoneId: this.zoneId,
  41. spawners: spawners,
  42. questBuilder: questBuilder,
  43. events: events,
  44. zone: map.zone,
  45. map: map
  46. };
  47. spawners.init(fakeInstance);
  48. map.create();
  49. map.clientMap.zoneId = this.zoneId;
  50. [resourceSpawner, syncer, objects, questBuilder, events].forEach(i => i.init(fakeInstance));
  51. this.addObject = this.nonInstanced.addObject.bind(this);
  52. this.onAddObject = this.nonInstanced.onAddObject.bind(this);
  53. this.updateObject = this.nonInstanced.updateObject.bind(this);
  54. this.queueAction = this.nonInstanced.queueAction.bind(this);
  55. this.performAction = this.nonInstanced.performAction.bind(this);
  56. this.removeObject = this.nonInstanced.removeObject.bind(this);
  57. this.onRemoveObject = this.nonInstanced.onRemoveObject.bind(this);
  58. this.tick = this.nonInstanced.tick.bind(this);
  59. this.tick();
  60. } else {
  61. spawners.init({
  62. zone: map.zone
  63. });
  64. map.create();
  65. map.clientMap.zoneId = this.zoneId;
  66. this.addObject = this.instanced.addObject.bind(this);
  67. this.onAddObject = this.instanced.onAddObject.bind(this);
  68. this.updateObject = this.instanced.updateObject.bind(this);
  69. this.queueAction = this.instanced.queueAction.bind(this);
  70. this.performAction = this.instanced.performAction.bind(this);
  71. this.removeObject = this.instanced.removeObject.bind(this);
  72. this.onRemoveObject = this.instanced.onRemoveObject.bind(this);
  73. if (map.mapFile.properties.isRandom)
  74. this.ttlGen = 0;
  75. this.tick = this.instanced.tick.bind(this);
  76. this.tick();
  77. }
  78. },
  79. nonInstanced: {
  80. tick: function() {
  81. objects.update();
  82. spawners.update();
  83. resourceSpawner.update();
  84. events.update();
  85. syncer.update();
  86. setTimeout(this.tick.bind(this), this.speed);
  87. },
  88. addObject: function(msg) {
  89. var obj = msg.obj;
  90. obj.serverId = obj.id;
  91. delete obj.id;
  92. if ((msg.keepPos) && (!physics.isValid(obj.x, obj.y))) {
  93. msg.keepPos = false;
  94. }
  95. if ((!msg.keepPos) || (obj.x == null)) {
  96. obj.x = map.spawn.x;
  97. obj.y = map.spawn.y;
  98. }
  99. obj.spawn = {
  100. x: map.spawn.x,
  101. y: map.spawn.y
  102. };
  103. syncer.queue('onGetMap', map.clientMap, [obj.serverId]);
  104. if (!msg.transfer)
  105. objects.addObject(obj, this.onAddObject.bind(this));
  106. else {
  107. var o = objects.transferObject(obj);
  108. if (o.zoneName != 'tutorial-cove')
  109. questBuilder.obtain(o);
  110. }
  111. },
  112. onAddObject: function(obj) {
  113. if (obj.zoneName != 'tutorial-cove')
  114. questBuilder.obtain(obj);
  115. },
  116. updateObject: function(msg) {
  117. var obj = objects.find(o => o.serverId == msg.id);
  118. if (!obj)
  119. return;
  120. var msgObj = msg.obj;
  121. var components = msgObj.components || [];
  122. delete msgObj.components;
  123. for (var p in msgObj) {
  124. obj[p] = msgObj[p];
  125. }
  126. var cLen = components.length;
  127. for (var i = 0; i < cLen; i++) {
  128. var c = components[i];
  129. var component = obj[c.type];
  130. for (var p in c) {
  131. component[p] = c[p];
  132. }
  133. }
  134. },
  135. queueAction: function(msg) {
  136. var obj = objects.find(o => o.serverId == msg.id);
  137. if (!obj)
  138. return;
  139. obj.queue(msg.action);
  140. },
  141. performAction: function(msg) {
  142. var obj = null;
  143. var targetId = msg.action.targetId;
  144. if (!targetId)
  145. obj = objects.find(o => o.serverId == msg.id);
  146. else {
  147. obj = objects.find(o => o.id == targetId);
  148. if (obj) {
  149. var action = msg.action;
  150. if (!action.data)
  151. action.data = {};
  152. action.data.sourceId = msg.id;
  153. }
  154. }
  155. if (!obj)
  156. return;
  157. obj.performAction(msg.action);
  158. },
  159. removeObject: function(msg) {
  160. var obj = msg.obj;
  161. obj = objects.find(o => o.serverId == obj.id);
  162. if (!obj) {
  163. //We should probably never reach this
  164. return;
  165. }
  166. if (obj.auth)
  167. obj.auth.doSave();
  168. if (obj.player)
  169. obj.fireEvent('beforeRezone');
  170. obj.destroyed = true;
  171. },
  172. onRemoveObject: function(obj) {
  173. }
  174. },
  175. instanced: {
  176. tick: function() {
  177. if (map.mapFile.properties.isRandom) {
  178. if (this.ttlGen <= 0) {
  179. if (!map.oldMap)
  180. map.oldMap = map.clientMap.map;
  181. if (!map.oldCollisionMap)
  182. map.oldCollisionMap = map.collisionMap;
  183. spawners.reset();
  184. randomMap.generate({
  185. map: map,
  186. physics: physics,
  187. spawners: spawners
  188. });
  189. this.ttlGen = 2000;
  190. } else
  191. this.ttlGen--;
  192. }
  193. var instances = this.instances;
  194. var iLen = instances.length;
  195. for (var i = 0; i < iLen; i++) {
  196. var instance = instances[i];
  197. instance.objects.update();
  198. instance.spawners.update();
  199. instance.resourceSpawner.update();
  200. instance.syncer.update();
  201. if (instance.closeTtl != null) {
  202. var hasPlayers = instance.objects.objects.some(o => o.player);
  203. if (hasPlayers) {
  204. delete instance.closeTtl;
  205. continue;
  206. }
  207. instance.closeTtl--;
  208. if (instance.closeTtl <= 0) {
  209. instances.splice(i, 1);
  210. i--;
  211. iLen--;
  212. }
  213. } else {
  214. var isEmpty = !instance.objects.objects.some(o => o.player);
  215. if (isEmpty) {
  216. //Zones reset after being empty for 10 minutes
  217. instance.closeTtl = 2;
  218. }
  219. }
  220. }
  221. setTimeout(this.tick.bind(this), this.speed);
  222. },
  223. addObject: function(msg) {
  224. var obj = msg.obj;
  225. var instanceId = msg.instanceId;
  226. //Maybe a party member is in here already?
  227. var social = obj.components.find(c => c.type == 'social');
  228. if ((social) && (social.party)) {
  229. var party = social.party;
  230. var instances = this.instances;
  231. var iLen = instances.length;
  232. for (var i = 0; i < iLen; i++) {
  233. var instance = instances[i];
  234. var partyInside = instance.objects.objects.some(o => party.indexOf(o.serverId) > -1);
  235. if (partyInside) {
  236. if (instance.id != obj.instanceId)
  237. msg.keepPos = false;
  238. obj.instanceId = instance.id;
  239. obj.instance = instance;
  240. instanceId = instance.id;
  241. break;
  242. }
  243. }
  244. }
  245. if (msg.transfer)
  246. msg.keepPos = false;
  247. var exists = this.instances.find(i => i.id == instanceId);
  248. if (exists) {
  249. if ((msg.keepPos) && (!exists.physics.isValid(obj.x, obj.y)))
  250. msg.keepPos = false;
  251. }
  252. if ((!msg.keepPos) || (obj.x == null)) {
  253. obj.x = map.spawn.x;
  254. obj.y = map.spawn.y;
  255. }
  256. obj.spawn = {
  257. x: map.spawn.x,
  258. y: map.spawn.y
  259. };
  260. if (exists) {
  261. //Keep track of what the connection id is (sent from the server)
  262. obj.serverId = obj.id;
  263. delete obj.id;
  264. obj.spawn = {
  265. x: exists.map.spawn.x,
  266. y: exists.map.spawn.y
  267. };
  268. exists.syncer.queue('onGetMap', exists.map.clientMap, [obj.serverId]);
  269. if (!msg.transfer) {
  270. exists.objects.addObject(obj, this.onAddObject.bind(this, msg.keepPos));
  271. } else {
  272. var newObj = exists.objects.transferObject(obj);
  273. this.onAddObject(false, newObj);
  274. }
  275. process.send({
  276. method: 'object',
  277. serverId: obj.serverId,
  278. obj: {
  279. instanceId: exists.id
  280. }
  281. });
  282. } else
  283. obj = this.instanced.createInstance.call(this, obj, msg.transfer);
  284. },
  285. onAddObject: function(keepPos, obj) {
  286. if (!keepPos) {
  287. obj.x = obj.instance.map.spawn.x;
  288. obj.y = obj.instance.map.spawn.y;
  289. }
  290. obj.instance.spawners.scale(obj.stats.values.level);
  291. if (obj.zoneName != 'tutorial-cove')
  292. obj.instance.questBuilder.obtain(obj);
  293. },
  294. updateObject: function(msg) {
  295. var id = msg.id;
  296. var instanceId = msg.instanceId;
  297. var exists = this.instances.find(i => i.id == instanceId);
  298. if (!exists)
  299. return;
  300. var obj = exists.objects.find(o => o.serverId == id);
  301. if (!obj) {
  302. console.log('OBJECT NOT FOUND!!!!!!!!!!!!!!!!!!!!!!!!!!!');
  303. console.log(msg);
  304. }
  305. var msgObj = msg.obj;
  306. var components = msgObj.components || [];
  307. delete msgObj.components;
  308. for (var p in msgObj) {
  309. obj[p] = msgObj[p];
  310. }
  311. var cLen = components.length;
  312. for (var i = 0; i < cLen; i++) {
  313. var c = components[i];
  314. var component = obj[c.type];
  315. for (var p in c) {
  316. component[p] = c[p];
  317. }
  318. }
  319. },
  320. performAction: function(msg) {
  321. var id = msg.id;
  322. var instanceId = msg.instanceId;
  323. var exists = this.instances.find(i => i.id == instanceId);
  324. if (!exists)
  325. return;
  326. var obj = exists.objects.find(o => o.serverId == id);
  327. if (!obj)
  328. return;
  329. obj.performAction(msg.action);
  330. },
  331. queueAction: function(msg) {
  332. var id = msg.id;
  333. var instanceId = msg.instanceId;
  334. var exists = this.instances.find(i => i.id == instanceId);
  335. if (!exists)
  336. return;
  337. var obj = exists.objects.find(o => o.serverId == id);
  338. if (obj)
  339. obj.queue(msg.action);
  340. },
  341. removeObject: function(msg) {
  342. var obj = msg.obj;
  343. var instanceId = msg.instanceId;
  344. var exists = this.instances.find(i => i.id == instanceId);
  345. if (!exists)
  346. return;
  347. var obj = msg.obj;
  348. obj = exists.objects.find(o => o.serverId == obj.id);
  349. if (!obj)
  350. return;
  351. if (obj.auth)
  352. obj.auth.doSave();
  353. obj.destroyed = true;
  354. },
  355. onRemoveObject: function(obj) {
  356. },
  357. createInstance: function(objToAdd, transfer) {
  358. var instance = {
  359. id: objToAdd.name + '_' + (+new Date),
  360. objects: extend(true, {}, objects),
  361. spawners: extend(true, {}, spawners),
  362. syncer: extend(true, {}, syncer),
  363. physics: extend(true, {}, physics),
  364. resourceSpawner: extend(true, {}, resourceSpawner),
  365. zoneId: this.zoneId,
  366. zone: map.zone,
  367. closeTtl: null,
  368. questBuilder: extend(true, {}, questBuilder),
  369. events: extend(true, {}, events),
  370. map: {
  371. name: map.name,
  372. spawn: extend(true, {}, map.spawn),
  373. clientMap: extend(true, {}, map.clientMap)
  374. }
  375. };
  376. ['objects', 'spawners', 'syncer', 'resourceSpawner', 'questBuilder', 'events'].forEach(i => instance[i].init(instance));
  377. this.instances.push(instance);
  378. var onDone = this.instanced.onCreateInstance.bind(this, instance, objToAdd, transfer);
  379. if (map.custom) {
  380. instance.customMap = extend(true, {}, customMap);
  381. instance.customMap.load(instance, objToAdd, onDone);
  382. }
  383. else
  384. onDone();
  385. },
  386. onCreateInstance: function(instance, objToAdd, transfer) {
  387. objToAdd.instance = instance;
  388. objToAdd.instanceId = instance.id;
  389. //Keep track of what the connection id is (sent from the server)
  390. objToAdd.serverId = objToAdd.id;
  391. delete objToAdd.id;
  392. var obj = null;
  393. instance.syncer.queue('onGetMap', instance.map.clientMap, [objToAdd.serverId]);
  394. if (!transfer)
  395. obj = instance.objects.addObject(objToAdd, this.onAddObject.bind(this, false));
  396. else {
  397. obj = instance.objects.transferObject(objToAdd);
  398. obj.x = instance.map.spawn.x;
  399. obj.y = instance.map.spawn.y;
  400. if (obj.zoneName != 'tutorial-cove')
  401. instance.questBuilder.obtain(obj);
  402. obj.instance.spawners.scale(obj.stats.values.level);
  403. }
  404. process.send({
  405. method: 'object',
  406. serverId: obj.serverId,
  407. obj: {
  408. instanceId: instance.id
  409. }
  410. });
  411. return obj;
  412. }
  413. },
  414. };
  415. });