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.
 
 
 

226 regels
4.3 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.zone = msg.zone;
  11. this.mobBuilder = extend({
  12. zone: this.zone
  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.zone.mobs.default, this.zone.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. performLast: true,
  51. components: [spawnAnimation]
  52. }, -1);
  53. }
  54. }
  55. if (!customSpawn) {
  56. this.syncer.queue('onGetObject', {
  57. x: obj.x,
  58. y: obj.y,
  59. components: [{
  60. type: 'attackAnimation',
  61. row: 0,
  62. col: 4
  63. }]
  64. }, -1);
  65. }
  66. if (spawner.amountLeft !== -1)
  67. spawner.amountLeft--;
  68. return obj;
  69. },
  70. update: function () {
  71. const spawners = this.list;
  72. let count = spawners.length;
  73. for (let i = 0; i < count; i++) {
  74. const l = spawners[i];
  75. if (l.destroyed) {
  76. spawners.splice(i, 1);
  77. i--;
  78. count--;
  79. continue;
  80. }
  81. if (l.lifetime && l.mob) {
  82. if (!l.age)
  83. l.age = 1;
  84. else
  85. l.age++;
  86. if (l.age >= l.lifetime) {
  87. this.syncer.queue('onGetObject', {
  88. x: l.mob.x,
  89. y: l.mob.y,
  90. components: [{
  91. type: 'attackAnimation',
  92. row: 0,
  93. col: 4
  94. }]
  95. }, -1);
  96. l.mob.destroyed = true;
  97. }
  98. }
  99. if (!l.cron) {
  100. if (l.cd > 0)
  101. l.cd--;
  102. else if (l.mob && l.mob.destroyed)
  103. l.cd = l.cdMax;
  104. }
  105. if (l.mob && l.mob.destroyed) {
  106. delete l.age;
  107. delete l.mob;
  108. }
  109. const cronInfo = {
  110. cron: l.cron,
  111. lastRun: l.lastRun
  112. };
  113. const doSpawn = (
  114. (
  115. !l.cron &&
  116. !l.cd
  117. ) || (
  118. l.cron &&
  119. !l.mob &&
  120. scheduler.shouldRun(cronInfo)
  121. )
  122. );
  123. if (doSpawn) {
  124. if (!l.cron)
  125. l.cd = -1;
  126. else
  127. l.lastRun = cronInfo.lastRun;
  128. const mob = this.spawn(l);
  129. if (!mob)
  130. continue;
  131. const name = (l.blueprint.objZoneName || l.blueprint.name).toLowerCase();
  132. if (l.blueprint.layerName === 'mobs')
  133. this.setupMob(mob, l.zonePrint);
  134. else {
  135. const blueprint = extend({}, this.zone.objects.default, this.zone.objects[name] || {});
  136. this.setupObj(mob, blueprint);
  137. }
  138. if (l.blueprint.objZoneName)
  139. mob.objZoneName = l.blueprint.objZoneName;
  140. l.mob = mob;
  141. }
  142. }
  143. },
  144. setupMob: function (mob, blueprint) {
  145. let type = 'regular';
  146. if (blueprint.isChampion)
  147. type = 'champion';
  148. else if (blueprint.rare.count > 0) {
  149. const rareCount = this.list.filter(l => (
  150. (l.mob) &&
  151. (!l.mob.destroyed) &&
  152. (l.mob.isRare) &&
  153. (l.mob.baseName === mob.name)
  154. ));
  155. if (rareCount.length < blueprint.rare.count) {
  156. const roll = Math.random() * 100;
  157. if (roll < blueprint.rare.chance)
  158. type = 'rare';
  159. }
  160. }
  161. this.setupObj(mob, blueprint);
  162. this.mobBuilder.build(mob, blueprint, type, this.zone.name);
  163. },
  164. setupObj: function (obj, blueprint) {
  165. const cpns = blueprint.components;
  166. if (!cpns)
  167. return;
  168. for (let c in cpns) {
  169. const cpn = cpns[c];
  170. let cType = c.replace('cpn', '');
  171. cType = cType[0].toLowerCase() + cType.substr(1);
  172. const builtCpn = obj.addComponent(cType, cpn);
  173. if (cpn.simplify)
  174. builtCpn.simplify = cpn.simplify.bind(builtCpn);
  175. }
  176. },
  177. destroySpawnerForObject: function (obj) {
  178. const spawner = this.list.find(l => l.mob === obj);
  179. if (spawner)
  180. spawner.destroyed = true;
  181. }
  182. };