Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.
 
 
 

225 wiersze
4.4 KiB

  1. const mobBuilder = require('./mobBuilder');
  2. const animations = require('../config/animations');
  3. const scheduler = require('../misc/scheduler');
  4. module.exports = {
  5. list: [],
  6. mobTypes: {},
  7. init: function (msg) {
  8. this.objects = msg.objects;
  9. this.syncer = msg.syncer;
  10. this.zoneConfig = msg.zoneConfig;
  11. this.mobBuilder = extend({
  12. zoneConfig: this.zoneConfig
  13. }, mobBuilder);
  14. },
  15. reset: function () {
  16. this.list = [];
  17. this.mobTypes = {};
  18. },
  19. register: function (blueprint, cdMax) {
  20. const spawner = extend({
  21. cdMax: cdMax || 171,
  22. cron: blueprint.cron,
  23. lifetime: blueprint.lifetime,
  24. blueprint: blueprint,
  25. amountLeft: blueprint.amount || -1
  26. });
  27. this.list.push(spawner);
  28. if (blueprint.layerName !== 'mobs')
  29. return;
  30. const name = blueprint.name.toLowerCase();
  31. if (!this.mobTypes[name])
  32. this.mobTypes[name] = 1;
  33. else
  34. this.mobTypes[name]++;
  35. spawner.zonePrint = extend({}, this.zoneConfig.mobs.default, this.zoneConfig.mobs[name] || {});
  36. },
  37. spawn: function (spawner) {
  38. if (spawner.amountLeft === 0)
  39. return;
  40. const blueprint = spawner.blueprint;
  41. const obj = this.objects.buildObjects([blueprint]);
  42. let customSpawn = false;
  43. const sheetName = blueprint.sheetName;
  44. if ((sheetName) && (blueprint.sheetName.indexOf('/'))) {
  45. const spawnAnimation = _.getDeepProperty(animations, ['mobs', sheetName, blueprint.cell, 'spawn']);
  46. if (spawnAnimation) {
  47. customSpawn = true;
  48. this.syncer.queue('onGetObject', {
  49. id: obj.id,
  50. components: [spawnAnimation]
  51. }, -1);
  52. }
  53. }
  54. if (!customSpawn) {
  55. this.syncer.queue('onGetObject', {
  56. x: obj.x,
  57. y: obj.y,
  58. components: [{
  59. type: 'attackAnimation',
  60. row: 0,
  61. col: 4
  62. }]
  63. }, -1);
  64. }
  65. if (spawner.amountLeft !== -1)
  66. spawner.amountLeft--;
  67. return obj;
  68. },
  69. update: function () {
  70. const spawners = this.list;
  71. let count = spawners.length;
  72. for (let i = 0; i < count; i++) {
  73. const l = spawners[i];
  74. if (l.destroyed) {
  75. spawners.splice(i, 1);
  76. i--;
  77. count--;
  78. continue;
  79. }
  80. if (l.lifetime && l.mob) {
  81. if (!l.age)
  82. l.age = 1;
  83. else
  84. l.age++;
  85. if (l.age >= l.lifetime) {
  86. this.syncer.queue('onGetObject', {
  87. x: l.mob.x,
  88. y: l.mob.y,
  89. components: [{
  90. type: 'attackAnimation',
  91. row: 0,
  92. col: 4
  93. }]
  94. }, -1);
  95. l.mob.destroyed = true;
  96. }
  97. }
  98. if (!l.cron) {
  99. if (l.cd > 0)
  100. l.cd--;
  101. else if (l.mob && l.mob.destroyed)
  102. l.cd = l.cdMax;
  103. }
  104. if (l.mob && l.mob.destroyed) {
  105. delete l.age;
  106. delete l.mob;
  107. }
  108. const cronInfo = {
  109. cron: l.cron,
  110. lastRun: l.lastRun
  111. };
  112. const doSpawn = (
  113. (
  114. !l.cron &&
  115. !l.cd
  116. ) || (
  117. l.cron &&
  118. !l.mob &&
  119. scheduler.shouldRun(cronInfo)
  120. )
  121. );
  122. if (doSpawn) {
  123. if (!l.cron)
  124. l.cd = -1;
  125. else
  126. l.lastRun = cronInfo.lastRun;
  127. const mob = this.spawn(l);
  128. if (!mob)
  129. continue;
  130. const name = (l.blueprint.objZoneName || l.blueprint.name).toLowerCase();
  131. if (l.blueprint.layerName === 'mobs')
  132. this.setupMob(mob, l.zonePrint);
  133. else {
  134. const blueprint = extend({}, this.zoneConfig.objects.default, this.zoneConfig.objects[name] || {});
  135. this.setupObj(mob, blueprint);
  136. }
  137. if (l.blueprint.objZoneName)
  138. mob.objZoneName = l.blueprint.objZoneName;
  139. l.mob = mob;
  140. }
  141. }
  142. },
  143. setupMob: function (mob, blueprint) {
  144. let type = 'regular';
  145. if (blueprint.isChampion)
  146. type = 'champion';
  147. else if (blueprint.rare.count > 0) {
  148. const rareCount = this.list.filter(l => (
  149. (l.mob) &&
  150. (!l.mob.destroyed) &&
  151. (l.mob.isRare) &&
  152. (l.mob.baseName === mob.name)
  153. ));
  154. if (rareCount.length < blueprint.rare.count) {
  155. const roll = Math.random() * 100;
  156. if (roll < blueprint.rare.chance)
  157. type = 'rare';
  158. }
  159. }
  160. this.setupObj(mob, blueprint);
  161. this.mobBuilder.build(mob, blueprint, type, this.zoneConfig.name);
  162. },
  163. setupObj: function (obj, blueprint) {
  164. const cpns = blueprint.components;
  165. if (!cpns)
  166. return;
  167. for (let c in cpns) {
  168. const cpn = cpns[c];
  169. let cType = c.replace('cpn', '');
  170. cType = cType[0].toLowerCase() + cType.substr(1);
  171. const builtCpn = obj.addComponent(cType, cpn);
  172. if (cpn.simplify)
  173. builtCpn.simplify = cpn.simplify.bind(builtCpn);
  174. }
  175. },
  176. destroySpawnerForObject: function (obj) {
  177. const spawner = this.list.find(l => l.mob === obj);
  178. if (spawner)
  179. spawner.destroyed = true;
  180. }
  181. };