You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

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