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ů.
 
 
 

197 řádky
3.6 KiB

  1. const { viewDistanceX, viewDistanceY } = consts;
  2. module.exports = {
  3. buffer: {},
  4. dirty: false,
  5. init: function (msg) {
  6. this.objects = msg.objects;
  7. },
  8. update: function () {
  9. let objects = this.objects;
  10. let oList = objects.objects;
  11. let oLen = oList.length;
  12. let pList = oList.filter(f => f.player && !f.destroyed);
  13. let pLen = pList.length;
  14. if (pLen === 0)
  15. this.updateZoneEmpty(objects, oList, oLen);
  16. else if (pLen > 0)
  17. this.updateZoneNotEmpty(objects, oList, oLen, pList, pLen);
  18. oLen = oList.length;
  19. for (let i = 0; i < oList.length; i++)
  20. oList[i].syncer.reset();
  21. },
  22. updateZoneEmpty: function (objects, oList, oLen) {
  23. for (let i = 0; i < oLen; i++) {
  24. let o = oList[i];
  25. if (!o.destroyed)
  26. continue;
  27. objects.removeObject(o);
  28. oLen--;
  29. i--;
  30. }
  31. },
  32. updateZoneNotEmpty: function (objects, oList, oLen, pList, pLen) {
  33. let queueFunction = this.queue.bind(this, 'onGetObject');
  34. let cache = {};
  35. for (let i = 0; i < oLen; i++) {
  36. let o = oList[i];
  37. let canBeSeenBy = o.canBeSeenBy;
  38. let oId = o.id;
  39. let ox = o.x;
  40. let oy = o.y;
  41. if (!o.syncer)
  42. continue;
  43. let destroyed = o.destroyed;
  44. let sync = null;
  45. let syncSelf = null;
  46. if (!destroyed) {
  47. sync = o.syncer.get();
  48. syncSelf = o.syncer.get(true);
  49. o.syncer.locked = true;
  50. } else {
  51. sync = {
  52. id: o.id,
  53. destroyed: true
  54. };
  55. objects.removeObject(o);
  56. oLen--;
  57. i--;
  58. }
  59. let toList = [];
  60. let completeList = [];
  61. let completeObj = null;
  62. let sendTo = false;
  63. let sendComplete = false;
  64. for (let j = 0; j < pLen; j++) {
  65. let p = pList[j];
  66. let px = p.x;
  67. let py = p.y;
  68. const canSee = (
  69. Math.abs(ox - px) <= viewDistanceX && Math.abs(oy - py) < viewDistanceY &&
  70. (
  71. !canBeSeenBy ||
  72. canBeSeenBy === p.name
  73. )
  74. );
  75. let hasSeen = p.player.hasSeen(oId);
  76. if (hasSeen) {
  77. if (canSee) {
  78. if (p.id === oId && syncSelf)
  79. queueFunction(syncSelf, [ p.serverId ]);
  80. if (sync) {
  81. toList.push(p.serverId);
  82. sendTo = true;
  83. }
  84. }
  85. if (destroyed || !canSee) {
  86. if (!canSee)
  87. queueFunction({ id: oId, destroyed: true }, [ p.serverId ]);
  88. p.player.unsee(oId);
  89. }
  90. } else if (!destroyed && canSee) {
  91. let cached = null;
  92. if (p.id === oId) {
  93. let syncO = o.getSimple(true);
  94. syncO.self = true;
  95. queueFunction(syncO, [ p.serverId ]);
  96. p.player.see(oId);
  97. continue;
  98. } else {
  99. cached = cache[oId];
  100. if (!cached)
  101. cached = cache[oId] = o.getSimple();
  102. }
  103. completeObj = cached;
  104. completeList.push(p.serverId);
  105. sendComplete = true;
  106. p.player.see(oId);
  107. }
  108. }
  109. if (sendTo)
  110. queueFunction(sync, toList);
  111. if (sendComplete)
  112. queueFunction(completeObj, completeList);
  113. }
  114. this.send();
  115. },
  116. queue: function (event, obj, to) {
  117. //Send to all players in zone?
  118. if (to === -1) {
  119. let pList = this.objects.objects.filter(o => o.player);
  120. to = pList.map(p => p.serverId);
  121. }
  122. if (!to.length)
  123. return;
  124. this.dirty = true;
  125. let buffer = this.buffer;
  126. let list = buffer[event] || (buffer[event] = []);
  127. list.push({
  128. to: to,
  129. obj: obj
  130. });
  131. },
  132. flushForTarget: function (targetServerId) {
  133. const buffer = this.buffer;
  134. for (let p in buffer) {
  135. const list = buffer[p];
  136. list.forEach(l => l.to.splice(f => f === targetServerId));
  137. list.spliceWhere(l => !l.to.length);
  138. if (!list.length)
  139. delete buffer[p];
  140. }
  141. },
  142. send: function () {
  143. if (!this.dirty)
  144. return;
  145. this.dirty = false;
  146. process.send({
  147. method: 'events',
  148. data: this.buffer
  149. });
  150. this.buffer = {};
  151. }
  152. };