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.
 
 
 

331 lines
6.9 KiB

  1. define([
  2. 'components/components'
  3. ], function(
  4. components
  5. ) {
  6. return {
  7. components: [],
  8. actionQueue: [],
  9. addComponent: function(type, blueprint, isTransfer) {
  10. var cpn = this[type];
  11. if (!cpn) {
  12. var template = components.components[type];
  13. if (!template) {
  14. template = extend(true, {
  15. type: type
  16. }, blueprint || {});
  17. }
  18. var cpn = extend(true, {}, template);
  19. cpn.obj = this;
  20. this.components.push(cpn);
  21. this[cpn.type] = cpn;
  22. }
  23. if ((cpn.init) && (this.instance != null))
  24. cpn.init(blueprint || {}, isTransfer);
  25. else {
  26. for (var p in blueprint) {
  27. cpn[p] = blueprint[p];
  28. }
  29. }
  30. return cpn;
  31. },
  32. extendComponent: function(ext, type, blueprint) {
  33. var template = require('./components/extensions/' + type);
  34. var cpn = this[ext];
  35. extend(true, cpn, template);
  36. if (template.init)
  37. cpn.init(blueprint);
  38. return cpn;
  39. },
  40. update: function() {
  41. var usedTurn = false;
  42. var components = this.components;
  43. var len = components.length;
  44. for (var i = 0; i < len; i++) {
  45. var c = components[i];
  46. if (c.update) {
  47. if (c.update())
  48. usedTurn = true;
  49. }
  50. }
  51. if (!usedTurn) {
  52. this.performQueue();
  53. }
  54. },
  55. getSimple: function(self, isSave) {
  56. var s = this.simplify(null, self, isSave);
  57. if (this.instance)
  58. s.zoneId = this.instance.zoneId;
  59. if ((self) && (!isSave)) {
  60. var syncer = this.syncer;
  61. if (this.syncer) {
  62. //Add things that have been queued by the syncer (that aren't tied to server-side components)
  63. var components = this.syncer.oSelf.components
  64. .filter((c => !this[c.type]), this)
  65. .forEach(c => s.components.push(c));
  66. }
  67. }
  68. return s;
  69. },
  70. simplify: function(o, self, isSave) {
  71. var result = {};
  72. if (!o) {
  73. result.components = [];
  74. o = this;
  75. }
  76. var syncTypes = ['portrait'];
  77. for (var p in o) {
  78. var value = o[p];
  79. if (value == null)
  80. continue;
  81. var type = typeof(value);
  82. //build component
  83. if (type == 'object') {
  84. if (value.type) {
  85. if (!value.simplify) {
  86. if (self) {
  87. result.components.push({
  88. type: value.type
  89. });
  90. }
  91. } else {
  92. var component = null;
  93. if (isSave)
  94. component = value.save ? value.save() : value.simplify(self);
  95. else
  96. component = value.simplify(self);
  97. if (component)
  98. result.components.push(component);
  99. }
  100. }
  101. else if (syncTypes.indexOf(p) > -1) {
  102. result[p] = value;
  103. }
  104. } else if (type != 'function')
  105. result[p] = value;
  106. }
  107. return result;
  108. },
  109. sendEvent: function(event, data) {
  110. process.send({
  111. method: 'event',
  112. id: this.serverId,
  113. data: {
  114. event: event,
  115. data: data
  116. }
  117. });
  118. },
  119. queue: function(action) {
  120. if (action.list) {
  121. var type = action.action;
  122. var data = action.data;
  123. var dLen = data.length;
  124. for (var i = 0; i < dLen; i++) {
  125. var d = data[i];
  126. this.actionQueue.push({
  127. action: type,
  128. data: d
  129. });
  130. }
  131. return;
  132. }
  133. if (action.priority)
  134. this.actionQueue.splice(this.actionQueue.firstIndex(a => !a.priority), 0, action);
  135. else
  136. this.actionQueue.push(action);
  137. },
  138. dequeue: function() {
  139. if (this.actionQueue.length == 0)
  140. return null;
  141. return this.actionQueue.splice(0, 1)[0];
  142. },
  143. clearQueue: function() {
  144. if (this.serverId != null) {
  145. this.instance.syncer.queue('onClearQueue', {
  146. id: this.id
  147. }, [this.serverId]);
  148. }
  149. this.actionQueue = [];
  150. },
  151. performAction: function(action) {
  152. if (action.instanceModule) {
  153. /*action.data.obj = this;
  154. this.instance[action.instanceModule][action.method](action.data);
  155. this.inventory.resolveCallback(action.data, action.data.result);*/
  156. return;
  157. }
  158. var cpn = this[action.cpn];
  159. if (!cpn)
  160. return;
  161. cpn[action.method](action.data);
  162. },
  163. performQueue: function() {
  164. var q = this.dequeue();
  165. if (!q) {
  166. return;
  167. }
  168. if (q.action == 'move') {
  169. if ((this.actionQueue[0]) && (this.actionQueue[0].action == 'move')) {
  170. var sprintChance = this.stats.values.sprintChance || 0;
  171. if (~~(Math.random() * 100) < sprintChance) {
  172. q = this.dequeue();
  173. q.isDouble = true;
  174. }
  175. }
  176. var success = this.performMove(q);
  177. if (!success) {
  178. this.clearQueue();
  179. }
  180. } else if (q.action == 'clearQueue')
  181. this.clearQueue();
  182. else if (q.action == 'spell') {
  183. var success = this.spellbook.cast(q);
  184. if (!success)
  185. this.performQueue();
  186. }
  187. },
  188. performMove: function(action) {
  189. var data = action.data;
  190. var physics = this.instance.physics;
  191. if (physics.isTileBlocking(data.x, data.y))
  192. return false;
  193. data.success = true;
  194. this.fireEvent('beforeMove', data);
  195. if (data.success == false) {
  196. action.priority = true;
  197. this.queue(action);
  198. return true;
  199. }
  200. if (!action.isDouble) {
  201. var deltaX = Math.abs(this.x - data.x);
  202. var deltaY = Math.abs(this.y - data.y);
  203. if (
  204. ((deltaX > 1) || (deltaY > 1)) ||
  205. ((deltaX == 0) && (deltaY == 0))
  206. )
  207. return false;
  208. }
  209. //Don't allow mob overlap during combat
  210. if ((this.mob) && (this.mob.target)) {
  211. if (physics.addObject(this, data.x, data.y)) {
  212. physics.removeObject(this, this.x, this.y);
  213. this.x = data.x;
  214. this.y = data.y;
  215. } else
  216. return false;
  217. } else {
  218. physics.removeObject(this, this.x, this.y, data.x, data.y);
  219. physics.addObject(this, data.x, data.y, this.x, this.y);
  220. this.x = data.x;
  221. this.y = data.y;
  222. }
  223. var syncer = this.syncer;
  224. syncer.o.x = this.x;
  225. syncer.o.y = this.y;
  226. if (this.aggro)
  227. this.aggro.move();
  228. return true;
  229. },
  230. collisionEnter: function(obj) {
  231. var components = this.components;
  232. var cLen = components.length;
  233. for (var i = 0; i < cLen; i++) {
  234. var c = components[i];
  235. if (c.collisionEnter) {
  236. if (c.collisionEnter(obj))
  237. return true;
  238. }
  239. }
  240. },
  241. collisionExit: function(obj) {
  242. var components = this.components;
  243. var cLen = components.length;
  244. for (var i = 0; i < cLen; i++) {
  245. var c = components[i];
  246. if (c.collisionExit)
  247. c.collisionExit(obj);
  248. }
  249. },
  250. fireEvent: function(event) {
  251. var args = [].slice.call(arguments, 1);
  252. var components = this.components;
  253. var cLen = components.length;
  254. for (var i = 0; i < cLen; i++) {
  255. var cpn = components[i];
  256. var events = cpn.events;
  257. if (!events)
  258. continue;
  259. var callback = events[event];
  260. if (!callback)
  261. continue;
  262. callback.apply(cpn, args);
  263. }
  264. if (this.effects)
  265. this.effects.fireEvent(event, args);
  266. if (this.quests)
  267. this.quests.fireEvent(event, args);
  268. if (this.prophecies)
  269. this.prophecies.fireEvent(event, args);
  270. if (this.inventory)
  271. this.inventory.fireEvent(event, args);
  272. },
  273. destroy: function() {
  274. var components = this.components;
  275. var len = components.length;
  276. for (var i = 0; i < len; i++) {
  277. var c = components[i];
  278. if (c.destroy)
  279. c.destroy();
  280. }
  281. }
  282. };
  283. });