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.
 
 
 

276 lines
6.0 KiB

  1. define([
  2. 'js/system/events',
  3. 'js/system/client',
  4. 'ui/factory',
  5. 'html!ui/templates/characters/template',
  6. 'html!ui/templates/characters/templateListItem',
  7. 'css!ui/templates/characters/styles',
  8. 'js/system/globals'
  9. ], function (
  10. events,
  11. client,
  12. uiFactory,
  13. template,
  14. templateListItem,
  15. styles,
  16. globals
  17. ) {
  18. return {
  19. tpl: template,
  20. centered: true,
  21. characterInfo: {},
  22. characters: null,
  23. selected: null,
  24. selectedIndex: -1,
  25. deleteCount: 0,
  26. beforeRender: function () {
  27. const { clientConfig: { logoPath } } = globals;
  28. if (!logoPath)
  29. return;
  30. const tempEl = $(this.tpl);
  31. tempEl.find('.logo').attr('src', logoPath);
  32. this.tpl = tempEl.prop('outerHTML');
  33. },
  34. postRender: function () {
  35. this.find('.btnPlay').on('click', this.onPlayClick.bind(this));
  36. this.find('.btnNew').on('click', this.onNewClick.bind(this));
  37. this.find('.btnDelete')
  38. .on('click', this.onDeleteClick.bind(this))
  39. .on('mouseleave', this.onDeleteReset.bind(this));
  40. this.getCharacters();
  41. this.onEvent('onKeyDown', this.onKeyDown.bind(this));
  42. },
  43. onKeyDown: function (key) {
  44. if (this.el.hasClass('disabled'))
  45. return;
  46. if (key === 'enter')
  47. this.onPlayClick();
  48. else if (key === 'up' || key === 'down') {
  49. if (!this.characters || this.selectedIndex === -1)
  50. return;
  51. const numChars = this.characters.length;
  52. if (!numChars)
  53. return;
  54. const delta = key === 'up' ? -1 : 1;
  55. //Clamp index within range [0, numChars - 1]
  56. const newIndex = Math.min(Math.max(this.selectedIndex + delta, 0), numChars - 1);
  57. const list = this.find('.left');
  58. if (!list)
  59. return;
  60. const li = list.children()[newIndex];
  61. li.click();
  62. list.scrollTop(li.offsetTop);
  63. }
  64. },
  65. onPlayClick: function () {
  66. let char = this.selected;
  67. if (!char)
  68. return;
  69. this.el.addClass('disabled');
  70. client.request({
  71. cpn: 'auth',
  72. method: 'play',
  73. data: {
  74. name: this.selected
  75. },
  76. callback: this.onPlay.bind(this)
  77. });
  78. },
  79. onPlay: function () {
  80. this.el.removeClass('disabled');
  81. this.destroy();
  82. },
  83. onNewClick: function () {
  84. uiFactory.build('createCharacter', {});
  85. this.destroy();
  86. },
  87. getCharacters: function () {
  88. this.el.addClass('disabled');
  89. client.request({
  90. cpn: 'auth',
  91. method: 'getCharacterList',
  92. callback: this.onGetCharacters.bind(this)
  93. });
  94. },
  95. onGetCharacters: function (characters) {
  96. this.characters = characters;
  97. this.find('.sprite').css('background', '');
  98. this.find('.info div').html('');
  99. this.el.removeClass('disabled');
  100. let list = this.find('.left')
  101. .empty();
  102. this.characters
  103. .sort(function (a, b) {
  104. return (b.level - a.level);
  105. })
  106. .forEach(function (c, i) {
  107. let charName = c.name;
  108. if (c.level !== null)
  109. charName += '<font class="color-yellowB">&nbsp;(' + c.level + ')</font>';
  110. let html = templateListItem
  111. .replace('$NAME$', charName);
  112. let li = $(html)
  113. .appendTo(list);
  114. li.on('click', this.onCharacterClick.bind(this, c.name, i));
  115. if (i === 0)
  116. li.click();
  117. }, this);
  118. },
  119. onCharacterClick: function (charName, charIndex, e) {
  120. this.selectedIndex = charIndex;
  121. this.el.addClass('disabled');
  122. let el = $(e.target);
  123. el.parent().find('.selected').removeClass('selected');
  124. el.addClass('selected');
  125. let charInfo = this.characterInfo[charName];
  126. if (charInfo) {
  127. this.onGetCharacter(charName, charInfo);
  128. return;
  129. }
  130. client.request({
  131. cpn: 'auth',
  132. method: 'getCharacter',
  133. data: {
  134. name: charName
  135. },
  136. callback: this.onGetCharacter.bind(this, charName)
  137. });
  138. },
  139. onGetCharacter: function (charName, result) {
  140. this.find('.btn').removeClass('disabled');
  141. let spriteY = ~~(result.cell / 8);
  142. let spirteX = result.cell - (spriteY * 8);
  143. spirteX = -(spirteX * 8);
  144. spriteY = -(spriteY * 8);
  145. let spritesheet = result.sheetName;
  146. if (spritesheet === 'characters')
  147. spritesheet = '../../../images/characters.png';
  148. this.find('.sprite')
  149. .css('background', 'url("' + spritesheet + '") ' + spirteX + 'px ' + spriteY + 'px')
  150. .show();
  151. this.find('.name').html(charName);
  152. let stats = result.components.find(function (c) {
  153. return (c.type === 'stats');
  154. });
  155. if (stats) {
  156. this.find('.class').html(
  157. 'Lvl ' + stats.values.level +
  158. ' ' +
  159. result.class[0].toUpperCase() + result.class.substr(1)
  160. );
  161. } else
  162. this.find('.class').html('');
  163. this.el.removeClass('disabled');
  164. this.characterInfo[charName] = result;
  165. this.selected = charName;
  166. let prophecies = result.components.find(function (c) {
  167. return (c.type === 'prophecies');
  168. });
  169. if ((prophecies) && (prophecies.list.indexOf('hardcore') > -1))
  170. this.find('.name').html(charName + ' (hc)');
  171. this.find('.btnPlay').removeClass('disabled');
  172. if (result.permadead) {
  173. this.find('.name').html(charName + ' (hc - rip)');
  174. this.find('.btnPlay').addClass('disabled');
  175. }
  176. },
  177. setMessage: function (msg) {
  178. this.find('.message').html(msg);
  179. },
  180. onDeleteClick: async function () {
  181. if (!this.selected)
  182. return;
  183. if (this.deleteCount < 3) {
  184. this.deleteCount++;
  185. this.setMessage('click delete ' + (4 - this.deleteCount) + ' more time' + ((this.deleteCount === 3) ? '' : 's') + ' to confirm');
  186. this.find('.btnDelete')
  187. .removeClass('deleting')
  188. .addClass('deleting')
  189. .html('delete (' + (4 - this.deleteCount) + ')');
  190. return;
  191. }
  192. this.onDeleteReset();
  193. this.el.addClass('disabled');
  194. const result = await new Promise(res => {
  195. client.request({
  196. cpn: 'auth',
  197. method: 'deleteCharacter',
  198. data: {
  199. name: this.selected
  200. },
  201. callback: res
  202. });
  203. });
  204. if (!result.success) {
  205. this.setMessage(result.msg);
  206. this.el.removeClass('disabled');
  207. return;
  208. }
  209. this.onGetCharacters(result.characterList);
  210. },
  211. onDeleteReset: function () {
  212. this.deleteCount = 0;
  213. this.find('.btnDelete')
  214. .removeClass('deleting')
  215. .html('delete');
  216. setTimeout(this.setMessage.bind(this, ''), 5000);
  217. }
  218. };
  219. });