Frontend for viewing Dungeon Defender layouts
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

viewer.js 9.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402
  1. $(function() {
  2. // Instructions
  3. (function() {
  4. var cookieName = 'hideinstructions';
  5. function showInstructions() {
  6. $.cookie(cookieName, null);
  7. $('#instructions').show();
  8. $('#showinstructions').hide();
  9. }
  10. function hideInstructions() {
  11. $.cookie(cookieName, 1, { expires: 365 });
  12. $('#instructions').hide();
  13. $('#showinstructions').show();
  14. }
  15. $('#hideinstructions').click(hideInstructions);
  16. $('#showinstructions').click(showInstructions);
  17. if ($.cookie(cookieName)) {
  18. hideInstructions();
  19. }
  20. })();
  21. // Saving
  22. (function() {
  23. function saveLayout() {
  24. _gaq.push(['_trackEvent', 'General', 'Save']);
  25. layout.notes = $('#notecontent').val();
  26. $('#save_inprogress').show();
  27. $('#save_done').hide();
  28. $('#savecontainer').show();
  29. $('#save_error').hide();
  30. $.ajax({
  31. type: 'POST',
  32. url: 'res/data/layouts/new',
  33. data: {layout: JSON.stringify(layout)},
  34. success: function(res) {
  35. window.location.hash = res;
  36. var url = window.location.href;
  37. $('#link').children().remove();
  38. $('<a>').attr('href', url).text(url).appendTo($('#link'));
  39. $('#save_inprogress').hide();
  40. $('#save_done').show();
  41. },
  42. error: function(xhr, status, error) {
  43. $('#save_error').text('Save failed! Server said: ' + error).show();
  44. }
  45. });
  46. }
  47. function closeSave() {
  48. $('#savecontainer').hide();
  49. }
  50. $('#savelayout').click(saveLayout);
  51. $('#savemask').click(closeSave);
  52. $('#saveclose').click(closeSave);
  53. })();
  54. // Layout picker
  55. (function() {
  56. $.each(levels, function(key) {
  57. var name = this.name;
  58. $('<button>')
  59. .append($('<img>').attr('src', this.image))
  60. .append($('<p>').text(name))
  61. .click(function() {
  62. window.location.hash = '';
  63. _gaq.push(['_trackEvent', 'Level picker', 'Picked', name]);
  64. showBlankLayout(key + 1);
  65. closePicker();
  66. })
  67. .appendTo($('#layoutpicker .container'));
  68. });
  69. function showPicker() {
  70. _gaq.push(['_trackEvent', 'Level picker', 'Shown']);
  71. $('#layoutcontainer').show();
  72. }
  73. function closePicker() {
  74. $('#layoutcontainer').hide();
  75. }
  76. $('#createlayout').click(showPicker);
  77. $('#layoutmask').click(closePicker);
  78. $('#layoutclose').click(closePicker);
  79. })();
  80. // Address management
  81. (function() {
  82. function updateFromHash() {
  83. var id = window.location.hash;
  84. if (id === '') {
  85. showBlankLayout(1);
  86. } else if (id.substr(0,7) == '#blank:') {
  87. showBlankLayout(parseInt(id.substr(7)));
  88. } else {
  89. getLayout(id.substr(1));
  90. }
  91. }
  92. $(window).bind('hashchange', updateFromHash);
  93. updateFromHash();
  94. })();
  95. // Palette
  96. (function() {
  97. $.each(towers, function(key) {
  98. createBaseElForTower(key, this).appendTo($('#palette'));
  99. });
  100. $('.tower,.core').draggable({
  101. helper: 'clone',
  102. containment: 'document',
  103. stop: function(evt, ui) {
  104. if (!$(this).data('type')) {
  105. return;
  106. }
  107. var tower = {
  108. type: $(this).data('type'),
  109. rotation: 0,
  110. position: adjustMapOffset(ui.helper.offsetFrom('#mapcontainer'), thisLevel, 1)
  111. };
  112. layout.towers.push(tower);
  113. createElForTower(tower).appendTo($('#mapcontainer'));
  114. updateDefenseUnits();
  115. }
  116. });
  117. })();
  118. // Searching
  119. (function() {
  120. $('#search_classes img').click(function() {
  121. var el = $(this);
  122. if (el.hasClass('disabled')) {
  123. el.removeClass('disabled');
  124. } else {
  125. el.addClass('disabled');
  126. }
  127. });
  128. var sel = $('select[name=search_map]');
  129. $.each(levels, function(key) {
  130. $('<option>').val(key + 1).text(this.name).appendTo(sel);
  131. });
  132. function showSearch() {
  133. $('#searchcontainer').show();
  134. }
  135. function hideSearch() {
  136. $('#searchcontainer').hide();
  137. }
  138. function clearSearchResults() {
  139. $('#searchresults tbody tr').remove();
  140. }
  141. function buildSearchQuery() {
  142. var query = {};
  143. var level = $('select[name=search_map]').val();
  144. if (level != 'any') {
  145. query.map = level;
  146. }
  147. doSearch(query);
  148. return false;
  149. }
  150. function doSearch(data) {
  151. clearSearchResults();
  152. $.ajax({
  153. url: 'res/data/layouts/search',
  154. data: data,
  155. success: handleSearch
  156. });
  157. }
  158. function handleSearch(data) {
  159. var body = $('#searchresults tbody');
  160. $.each(data, function() {
  161. this.difficulty = this.difficulty || 'unknown';
  162. this.type = (this.type && this.type != 'none') ? this.type : 'unknown';
  163. var tr = $('<tr>');
  164. tr.append($('<td>').append($('<a>').attr('href', '#' + this.id).text(this.id).click(hideSearch)));
  165. tr.append($('<td>').text(levels[this.level - 1] ? levels[this.level - 1].name : 'Unknown!'));
  166. tr.append($('<td>').addClass(this.difficulty).text(this.difficulty));
  167. tr.append($('<td>').addClass(this.type).text(this.type));
  168. body.append(tr);
  169. });
  170. }
  171. $('#search_submit').click(buildSearchQuery);
  172. $('#search').click(showSearch);
  173. $('#searchmask').click(hideSearch);
  174. $('#searchclose').click(hideSearch);
  175. })();
  176. var thisLevel;
  177. var layout;
  178. function updateDefenseUnits() {
  179. var used = 0;
  180. $.each(layout.towers, function() {
  181. used += towers[this.type].units;
  182. });
  183. $('#du_used').text(used);
  184. var hasClass = $('#du_wrapper').hasClass('over');
  185. $('#du_wrapper').removeClass('over');
  186. if (used > thisLevel.du) {
  187. $('#du_wrapper').addClass('over');
  188. if (!hasClass) {
  189. $('#du_wrapper').effect('pulsate', {times: 2}, 'fast');
  190. }
  191. }
  192. }
  193. function createElForCore() {
  194. return $('<img>')
  195. .attr('src', 'res/images/coreIcon.png')
  196. .attr('alt', 'Core')
  197. .addClass('core')
  198. .css('position', 'absolute')
  199. .css('height', (40 * thisLevel.towerscale) + 'px')
  200. .css('width', (40 * thisLevel.towerscale) + 'px');
  201. }
  202. function createBaseElForTower(key) {
  203. var type = towers[key];
  204. return $('<img>')
  205. .attr('src', type.image)
  206. .attr('alt', type.name)
  207. .data('type', key)
  208. .addClass(type.class.toLowerCase())
  209. .addClass('tower');
  210. }
  211. function createElForTower(tower) {
  212. return createBaseElForTower(tower.type)
  213. .data('tower', tower)
  214. .draggable({
  215. containment: 'document',
  216. start: function(evt) {
  217. return !evt.shiftKey;
  218. },
  219. stop: function() {
  220. var el = $(this);
  221. el.data('tower').position = adjustMapOffset({top: parseInt(el.css('top')), left: parseInt(el.css('left'))}, thisLevel, 1);
  222. }
  223. })
  224. .css('position', 'absolute')
  225. .css('height', (40 * thisLevel.towerscale * towers[tower.type].defaultscale) + 'px')
  226. .css('width', (40 * thisLevel.towerscale * towers[tower.type].defaultscale) + 'px')
  227. .offset(adjustMapOffset(tower.position, thisLevel))
  228. .rotate(tower.rotation)
  229. .dblclick(function() {
  230. layout.towers = $.grep(layout.towers, function(value) { return value != tower; });
  231. $(this).remove();
  232. updateDefenseUnits();
  233. })
  234. .mousedown(function(e) {
  235. if (!e.shiftKey) {
  236. return;
  237. }
  238. var el = $(this);
  239. var centre = el.offsetCentre();
  240. var mouseX = e.pageX - centre.left, mouseY = e.pageY - centre.top;
  241. var initialMouseAngle = Math.atan2(mouseY, mouseX);
  242. var initialRotation = tower.rotation;
  243. var moveHandler = function(evt) {
  244. var mouseX = evt.pageX - centre.left, mouseY = evt.pageY - centre.top;
  245. var newMouseAngle = Math.atan2(mouseY, mouseX);
  246. var mouseDelta = newMouseAngle - initialMouseAngle;
  247. var rotation = initialRotation + newMouseAngle * (180 / Math.PI);
  248. tower.rotation = rotation;
  249. el.rotate(rotation);
  250. };
  251. var upHandler = function() {
  252. $(document).unbind('mousemove', moveHandler);
  253. $(document).unbind('mouseup', upHandler);
  254. };
  255. $(document).mousemove(moveHandler);
  256. $(document).mouseup(upHandler);
  257. return false;
  258. });
  259. }
  260. function adjustMapOffset(towerOffset, level, reverse) {
  261. var res = $.extend({}, towerOffset);
  262. if (level.offsets && !reverse) {
  263. res.left += level.offsets.left;
  264. res.top += level.offsets.top;
  265. }
  266. if (level.scale) {
  267. if (reverse) {
  268. res.left /= level.scale.left;
  269. res.top /= level.scale.top;
  270. } else {
  271. res.left *= level.scale.left;
  272. res.top *= level.scale.top;
  273. }
  274. }
  275. if (level.offsets && reverse) {
  276. res.left -= level.offsets.left;
  277. res.top -= level.offsets.top;
  278. }
  279. return res;
  280. }
  281. function clearLayout() {
  282. $('#mapcontainer .tower').remove();
  283. if (layout) {
  284. layout.towers = [];
  285. }
  286. }
  287. function clearCores() {
  288. $('#mapcontainer .core').remove();
  289. }
  290. function updateLayout(data) {
  291. clearLayout();
  292. clearCores();
  293. layout = data;
  294. thisLevel = levels[layout.level - 1];
  295. $.each(thisLevel.cores, function() {
  296. createElForCore().offset(adjustMapOffset(this, thisLevel)).appendTo($('#mapcontainer'));
  297. });
  298. _gaq.push(['_setCustomVar', 1, 'Level', thisLevel.name, 1]);
  299. $('#mapcontainer').css('background-image', 'url("' + thisLevel.minimap + '")');
  300. $('#notecontent').val(layout.notes);
  301. $.each(layout.towers, function() {
  302. createElForTower(this).appendTo($('#mapcontainer'));
  303. });
  304. updateDefenseUnits();
  305. var difficulty = layout.difficulty ? layout.difficulty : "unknown";
  306. $('#difficulty').text(difficulty).removeClass().addClass(difficulty);
  307. var type = layout.type && layout.type != 'none' ? layout.type : "unknown";
  308. var modes = '';
  309. layout.mode && $.each(layout.mode, function() {
  310. if (this == "hardcore") {
  311. modes = '<abbr title="Hardcore">hc</abbr> ' + modes;
  312. } else if (this == "mixed") {
  313. modes = '<abbr title="Mixed mode">mm</abbr> ' + modes;
  314. } else if (this == "strategy") {
  315. modes = '<abbr title="Pure strategy">ps</abbr> ' + modes;
  316. } else if (this == "none") {
  317. modes = 'none';
  318. }
  319. });
  320. $('#type').text(type);
  321. $('#modes').html(modes == '' ? 'unknown' : modes);
  322. $('#du_total').text(thisLevel.du);
  323. }
  324. function getLayout(id) {
  325. _gaq.push(['_trackPageview', '/view/' + id]);
  326. $.getJSON('res/data/layouts/' + id + '.js', updateLayout);
  327. }
  328. function showBlankLayout(id) {
  329. window.location.hash = 'blank:' + id;
  330. _gaq.push(['_trackPageview', '/view/blank:' + id]);
  331. updateLayout({level: id, towers:[]});
  332. }
  333. });