Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.
 
 
 

226 řádky
4.7 KiB

  1. let map = require('./map');
  2. let syncer = require('./syncer');
  3. let objects = require('../objects/objects');
  4. let spawners = require('./spawners');
  5. let physics = require('./physics');
  6. let spellCallbacks = require('../config/spells/spellCallbacks');
  7. let questBuilder = require('../config/quests/questBuilder');
  8. let randomMap = require('./randomMap');
  9. let events = require('../events/events');
  10. let scheduler = require('../misc/scheduler');
  11. let mail = require('../mail/mail');
  12. let resourceNodes = require('../config/resourceNodes');
  13. let eventEmitter = require('../misc/events');
  14. const transactions = require('../security/transactions');
  15. module.exports = {
  16. instances: [],
  17. zoneId: -1,
  18. speed: consts.tickTime,
  19. lastTime: 0,
  20. init: function (args) {
  21. this.zoneId = args.zoneId;
  22. spellCallbacks.init();
  23. resourceNodes.init();
  24. map.init(args);
  25. const fakeInstance = {
  26. objects: objects,
  27. syncer: syncer,
  28. physics: physics,
  29. zoneId: this.zoneId,
  30. spawners: spawners,
  31. questBuilder: questBuilder,
  32. events: events,
  33. zone: map.zone,
  34. mail: mail,
  35. map: map,
  36. scheduler: scheduler,
  37. eventEmitter: eventEmitter
  38. };
  39. this.instances.push(fakeInstance);
  40. spawners.init(fakeInstance);
  41. scheduler.init();
  42. map.create();
  43. if (map.mapFile.properties.isRandom) {
  44. if (!map.oldCollisionMap)
  45. map.oldCollisionMap = map.collisionMap;
  46. randomMap.generate({
  47. map: map,
  48. physics: physics,
  49. spawners: spawners
  50. });
  51. map.seed = _.getGuid();
  52. }
  53. map.clientMap.zoneId = this.zoneId;
  54. [syncer, objects, questBuilder, events, mail].forEach(i => i.init(fakeInstance));
  55. eventEmitter.emitNoSticky('onInitModules', fakeInstance);
  56. this.tick();
  57. },
  58. tick: function () {
  59. eventEmitter.emitNoSticky('onBeforeZoneUpdate');
  60. events.update();
  61. objects.update();
  62. spawners.update();
  63. syncer.update();
  64. scheduler.update();
  65. setTimeout(this.tick.bind(this), this.speed);
  66. },
  67. addObject: function (msg) {
  68. let obj = msg.obj;
  69. obj.serverId = obj.id;
  70. delete obj.id;
  71. let spawnPos = map.getSpawnPos(obj);
  72. let spawnEvent = {
  73. spawnPos: extend({}, spawnPos),
  74. changed: false
  75. };
  76. eventEmitter.emitNoSticky('onBeforePlayerSpawn', { name: obj.name, instance: { physics } }, spawnEvent);
  77. if (spawnEvent.changed)
  78. msg.keepPos = false;
  79. if (msg.keepPos && (!physics.isValid(obj.x, obj.y) || !map.canPathFromPos(obj)))
  80. msg.keepPos = false;
  81. if (!msg.keepPos || !obj.has('x') || (map.mapFile.properties.isRandom && obj.instanceId !== map.seed)) {
  82. obj.x = spawnPos.x;
  83. obj.y = spawnPos.y;
  84. }
  85. obj.instanceId = map.seed || null;
  86. obj.spawn = map.spawn;
  87. syncer.queue('onGetMap', map.clientMap, [obj.serverId]);
  88. if (!msg.transfer)
  89. objects.addObject(obj, this.onAddObject.bind(this));
  90. else {
  91. let o = objects.transferObject(obj);
  92. questBuilder.obtain(o);
  93. }
  94. },
  95. onAddObject: function (obj) {
  96. if (obj.player)
  97. obj.stats.onLogin();
  98. questBuilder.obtain(obj);
  99. obj.fireEvent('afterMove');
  100. if (obj.dead) {
  101. obj.instance.syncer.queue('onDeath', {
  102. x: obj.x,
  103. y: obj.y
  104. }, [obj.serverId]);
  105. }
  106. },
  107. updateObject: function (msg) {
  108. let obj = objects.find(o => o.serverId === msg.id);
  109. if (!obj)
  110. return;
  111. let msgObj = msg.obj;
  112. let components = msgObj.components || [];
  113. delete msgObj.components;
  114. for (let p in msgObj)
  115. obj[p] = msgObj[p];
  116. let cLen = components.length;
  117. for (let i = 0; i < cLen; i++) {
  118. let c = components[i];
  119. let component = obj[c.type];
  120. for (let p in c)
  121. component[p] = c[p];
  122. }
  123. },
  124. queueAction: function (msg) {
  125. let obj = objects.find(o => o.serverId === msg.id);
  126. if (!obj)
  127. return;
  128. else if (msg.action.action === 'move') {
  129. let moveEntries = obj.actionQueue.filter(q => (q.action === 'move')).length;
  130. if (moveEntries >= 50)
  131. return;
  132. }
  133. obj.queue(msg.action);
  134. },
  135. performAction: function (msg) {
  136. let obj = null;
  137. let targetId = msg.action.targetId;
  138. if (!targetId)
  139. obj = objects.find(o => o.serverId === msg.id);
  140. else {
  141. obj = objects.find(o => o.id === targetId);
  142. if (obj) {
  143. let action = msg.action;
  144. if (!action.data)
  145. action.data = {};
  146. action.data.sourceId = msg.id;
  147. }
  148. }
  149. if (!obj)
  150. return;
  151. obj.performAction(msg.action);
  152. },
  153. removeObject: async function (msg) {
  154. let obj = msg.obj;
  155. obj = objects.find(o => o.serverId === obj.id);
  156. if (!obj) {
  157. //We should probably never reach this
  158. return;
  159. }
  160. if (obj.auth)
  161. await obj.auth.doSave();
  162. if (obj.player)
  163. obj.fireEvent('beforeRezone');
  164. obj.destroyed = true;
  165. if (msg.callbackId) {
  166. process.send({
  167. module: 'atlas',
  168. method: 'resolveCallback',
  169. msg: {
  170. id: msg.callbackId
  171. }
  172. });
  173. }
  174. },
  175. notifyOnceIdle: async function () {
  176. await transactions.returnWhenDone();
  177. process.send({
  178. method: 'onZoneIdle'
  179. });
  180. }
  181. };