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.
 
 
 

218 lines
4.2 KiB

  1. let mobBuilder = require('./mobBuilder');
  2. let animations = require('../config/animations');
  3. let 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. let 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. let 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. let blueprint = spawner.blueprint;
  41. let obj = this.objects.buildObjects([blueprint]);
  42. let customSpawn = false;
  43. let sheetName = blueprint.sheetName;
  44. if ((sheetName) && (blueprint.sheetName.indexOf('/'))) {
  45. let 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. let list = this.list;
  72. let lLen = list.length;
  73. for (let i = 0; i < lLen; i++) {
  74. let l = list[i];
  75. if ((l.lifetime) && (l.mob)) {
  76. if (l.mob.destroyed) {
  77. delete l.age;
  78. delete l.mob;
  79. } else {
  80. if (!l.age)
  81. l.age = 1;
  82. else
  83. l.age++;
  84. if (l.age >= l.lifetime) {
  85. this.syncer.queue('onGetObject', {
  86. x: l.mob.x,
  87. y: l.mob.y,
  88. components: [{
  89. type: 'attackAnimation',
  90. row: 0,
  91. col: 4
  92. }]
  93. }, -1);
  94. l.mob.destroyed = true;
  95. delete l.age;
  96. delete l.mob;
  97. }
  98. }
  99. }
  100. if (!l.cron) {
  101. if (l.cd > 0)
  102. l.cd--;
  103. else if ((l.mob) && (l.mob.destroyed))
  104. l.cd = l.cdMax;
  105. }
  106. let cronInfo = {
  107. cron: l.cron,
  108. lastRun: l.lastRun
  109. };
  110. let doSpawn = (
  111. (
  112. (!l.cron) &&
  113. (!l.mob)
  114. ) ||
  115. (
  116. (!l.cron) &&
  117. (l.cd === 0)
  118. ) ||
  119. (
  120. (!l.mob) &&
  121. (l.cron) &&
  122. (scheduler.shouldRun(cronInfo))
  123. )
  124. );
  125. if (doSpawn) {
  126. if (!l.cron)
  127. l.cd = -1;
  128. else
  129. l.lastRun = cronInfo.lastRun;
  130. let mob = this.spawn(l);
  131. if (!mob)
  132. continue;
  133. let name = (l.blueprint.objZoneName || l.blueprint.name).toLowerCase();
  134. if (l.blueprint.layerName === 'mobs')
  135. this.setupMob(mob, l.zonePrint);
  136. else {
  137. let blueprint = extend({}, this.zone.objects.default, this.zone.objects[name] || {});
  138. this.setupObj(mob, blueprint);
  139. }
  140. if (l.blueprint.objZoneName)
  141. mob.objZoneName = l.blueprint.objZoneName;
  142. l.mob = mob;
  143. }
  144. }
  145. },
  146. setupMob: function (mob, blueprint) {
  147. let type = 'regular';
  148. if (blueprint.isChampion)
  149. type = 'champion';
  150. else if (blueprint.rare.count > 0) {
  151. let rareCount = this.list.filter(l => (
  152. (l.mob) &&
  153. (!l.mob.destroyed) &&
  154. (l.mob.isRare) &&
  155. (l.mob.baseName === mob.name)
  156. ));
  157. if (rareCount.length < blueprint.rare.count) {
  158. let roll = Math.random() * 100;
  159. if (roll < blueprint.rare.chance)
  160. type = 'rare';
  161. }
  162. }
  163. this.setupObj(mob, blueprint);
  164. this.mobBuilder.build(mob, blueprint, type, this.zone.name);
  165. },
  166. setupObj: function (obj, blueprint) {
  167. let cpns = blueprint.components;
  168. if (!cpns)
  169. return;
  170. for (let c in cpns) {
  171. let cpn = cpns[c];
  172. let cType = c.replace('cpn', '');
  173. cType = cType[0].toLowerCase() + cType.substr(1);
  174. let builtCpn = obj.addComponent(cType, cpn);
  175. if (cpn.simplify)
  176. builtCpn.simplify = cpn.simplify.bind(builtCpn);
  177. }
  178. }
  179. };