Frontend for viewing Dungeon Defender layouts
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.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668
  1. $.fn.rotate = function(rot) {
  2. return this.css('-webkit-transform', 'rotate(' + rot + 'deg)')
  3. .css('-moz-transform', 'rotate(' + rot + 'deg')
  4. .css('-o-transform', 'rotate(' + rot + 'deg')
  5. .css('-ms-transform', 'rotate(' + rot + 'deg')
  6. .css('transform', 'rotate(' + rot + 'deg');
  7. };
  8. $.fn.offsetFrom = function(el) {
  9. var offset = this.offset();
  10. var otherOffset = $(el).offset();
  11. return {top: offset.top - otherOffset.top, left: offset.left - otherOffset.left};
  12. }
  13. $.fn.offsetCentre = function() {
  14. var offset = this.offset();
  15. return {top: offset.top + this.height() / 2, left: offset.left + this.width() / 2};
  16. }
  17. function getURLParameter(name) {
  18. return decodeURIComponent((location.search.match(RegExp("[?|&]"+name+'=(.+?)(&|$)'))||[,null])[1]);
  19. }
  20. $(function() {
  21. // Instructions
  22. (function() {
  23. var cookieName = 'hideinstructions';
  24. function showInstructions() {
  25. $.cookie(cookieName, null);
  26. $('#instructions').show();
  27. $('#showinstructions').hide();
  28. }
  29. function hideInstructions() {
  30. $.cookie(cookieName, 1, { expires: 365 });
  31. $('#instructions').hide();
  32. $('#showinstructions').show();
  33. }
  34. $('#hideinstructions').click(hideInstructions);
  35. $('#showinstructions').click(showInstructions);
  36. if ($.cookie(cookieName)) {
  37. hideInstructions();
  38. }
  39. })();
  40. // Saving
  41. (function() {
  42. function saveLayout() {
  43. _gaq.push(['_trackEvent', 'General', 'Save']);
  44. layout.notes = $('#notecontent').val();
  45. $('#save_inprogress').show();
  46. $('#save_done').hide();
  47. $('#savecontainer').show();
  48. $('#save_error').hide();
  49. $.ajax({
  50. type: 'POST',
  51. url: 'res/data/layouts/new',
  52. data: {layout: JSON.stringify(layout)},
  53. success: function(res) {
  54. window.location.hash = res;
  55. var url = window.location.href;
  56. $('#link').children().remove();
  57. $('<a>').attr('href', url).text(url).appendTo($('#link'));
  58. $('#save_inprogress').hide();
  59. $('#save_done').show();
  60. },
  61. error: function(xhr, status, error) {
  62. $('#save_error').text('Save failed! Server said: ' + error).show();
  63. }
  64. });
  65. }
  66. function closeSave() {
  67. $('#savecontainer').hide();
  68. }
  69. $('#savelayout').click(saveLayout);
  70. $('#savemask').click(closeSave);
  71. $('#saveclose').click(closeSave);
  72. })();
  73. // Layout picker
  74. (function() {
  75. $.each(levels, function(key) {
  76. var name = this.name;
  77. name && $('<button>')
  78. .append($('<img>').attr('src', this.image))
  79. .append($('<p>').text(name))
  80. .click(function() {
  81. window.location.hash = '';
  82. _gaq.push(['_trackEvent', 'Level picker', 'Picked', name]);
  83. showBlankLayout(key + 1);
  84. closePicker();
  85. })
  86. .appendTo($('#layoutpicker .container'));
  87. });
  88. function showPicker() {
  89. _gaq.push(['_trackEvent', 'Level picker', 'Shown']);
  90. $('#layoutcontainer').show();
  91. }
  92. function closePicker() {
  93. $('#layoutcontainer').hide();
  94. }
  95. $('#createlayout').click(showPicker);
  96. $('#layoutmask').click(closePicker);
  97. $('#layoutclose').click(closePicker);
  98. })();
  99. // Address management
  100. (function() {
  101. function updateFromHash() {
  102. var id = window.location.hash;
  103. if (id === '') {
  104. showBlankLayout(1);
  105. } else if (id.substr(0,7) == '#blank:') {
  106. showBlankLayout(parseInt(id.substr(7)));
  107. } else {
  108. getLayout(id.substr(1));
  109. }
  110. }
  111. $(window).bind('hashchange', updateFromHash);
  112. updateFromHash();
  113. })();
  114. // Palette
  115. (function() {
  116. $.each(towers, function(key) {
  117. createBaseElForTower(key, this).appendTo($('#palette'));
  118. });
  119. $('.tower,.core').draggable({
  120. helper: 'clone',
  121. containment: 'document',
  122. stop: function(evt, ui) {
  123. if (!$(this).data('type')) {
  124. return;
  125. }
  126. var tower = {
  127. type: $(this).data('type'),
  128. rotation: 0,
  129. position: adjustMapOffset(ui.helper.offsetFrom('#mapcontainer'), thisLevel, 1)
  130. };
  131. layout.towers.push(tower);
  132. createElForTower(tower).appendTo($('#mapcontainer'));
  133. updateDefenseUnits();
  134. }
  135. });
  136. })();
  137. // Searching
  138. (function() {
  139. $('#search_classes img').click(function() {
  140. var el = $(this);
  141. if (el.hasClass('disabled')) {
  142. el.removeClass('disabled');
  143. } else {
  144. el.addClass('disabled');
  145. }
  146. });
  147. var sel = $('select[name=search_map]');
  148. $.each(levels, function(key) {
  149. this.name && $('<option>').val(key + 1).text(this.name).appendTo(sel);
  150. });
  151. function showSearch() {
  152. $('#searchcontainer').show();
  153. }
  154. function hideSearch() {
  155. $('#searchcontainer').hide();
  156. }
  157. function clearSearchResults() {
  158. $('#searchresults tbody tr').remove();
  159. }
  160. function buildSearchQuery() {
  161. var query = {};
  162. var level = $('select[name=search_map]').val();
  163. if (level != 'any') {
  164. query.map = level;
  165. }
  166. var difficulty = $('select[name=search_difficulty]').val();
  167. if (difficulty != 'any') {
  168. query.difficulty = difficulty;
  169. }
  170. var type = $('select[name=search_type]').val();
  171. if (type != 'any') {
  172. query.type = type;
  173. }
  174. query.classes = '';
  175. $.each($('#search_classes img'), function() {
  176. if (!$(this).hasClass('disabled')) {
  177. if (query.classes.length > 0) { query.classes += ','; }
  178. query.classes += this.id.replace('search_', '');
  179. }
  180. });
  181. query.mode = '';
  182. if ($('input[name=search_hc]').is(':checked')) {
  183. query.mode += ',hardcore';
  184. }
  185. if ($('input[name=search_mm]').is(':checked')) {
  186. query.mode += ',mixed';
  187. }
  188. if ($('input[name=search_ps]').is(':checked')) {
  189. query.mode += ',strategy';
  190. }
  191. if (query.mode.length == 0) {
  192. delete query.mode;
  193. } else {
  194. query.mode = query.mode.substr(1);
  195. }
  196. query.limit = 100;
  197. doSearch(query);
  198. return false;
  199. }
  200. function doSearch(data) {
  201. clearSearchResults();
  202. $.ajax({
  203. url: 'res/data/layouts/search',
  204. data: data,
  205. success: handleSearch
  206. });
  207. }
  208. function handleSearch(data) {
  209. var body = $('#searchresults tbody');
  210. $.each(data, function() {
  211. this.difficulty = this.difficulty || 'unknown';
  212. this.type = (this.type && this.type != 'none') ? this.type : 'unknown';
  213. var tr = $('<tr>');
  214. tr.append($('<td>').append($('<a>').attr('href', '#' + this.id).text(this.id).click(hideSearch)));
  215. tr.append($('<td>').text(levels[this.level - 1] ? levels[this.level - 1].name : 'Unknown!'));
  216. tr.append($('<td>').addClass(this.difficulty).text(this.difficulty));
  217. tr.append($('<td>').addClass(this.type).text(this.type));
  218. tr.append($('<td>').html(getModesHTML(this.mode)));
  219. var classes = this.classes;
  220. var td = $('<td>');
  221. $.each(['huntress', 'apprentice', 'monk', 'squire'], function(k, v) {
  222. var url = v == 'apprentice' ? 'mage' : v;
  223. var img = $('<img>').attr('src', 'res/images/classes/' + url + '_icon.png')
  224. .attr('alt', v);
  225. if ($.inArray(v, classes) == -1) {
  226. img.addClass('disabled');
  227. }
  228. td.append(img);
  229. });
  230. tr.append(td);
  231. body.append(tr);
  232. });
  233. }
  234. $('#search_submit').click(buildSearchQuery);
  235. $('#search').click(showSearch);
  236. $('#searchmask').click(hideSearch);
  237. $('#searchclose').click(hideSearch);
  238. })();
  239. var thisLevel;
  240. var layout;
  241. function getModesHTML(modes) {
  242. var res = '';
  243. modes && $.each(modes, function() {
  244. if (this == "hardcore") {
  245. res = '<abbr title="Hardcore">hc</abbr> ' + res;
  246. } else if (this == "mixed") {
  247. res = '<abbr title="Mixed mode">mm</abbr> ' + res;
  248. } else if (this == "strategy") {
  249. res = '<abbr title="Pure strategy">ps</abbr> ' + res;
  250. } else if (this == "none") {
  251. res = 'none';
  252. }
  253. });
  254. return res || 'unknown';
  255. }
  256. function updateDefenseUnits() {
  257. var used = 0;
  258. $.each(layout.towers, function() {
  259. used += towers[this.type].units;
  260. });
  261. $('#du_used').text(used);
  262. var hasClass = $('#du_wrapper').hasClass('over');
  263. $('#du_wrapper').removeClass('over');
  264. if (used > thisLevel.du) {
  265. $('#du_wrapper').addClass('over');
  266. if (!hasClass) {
  267. $('#du_wrapper').effect('pulsate', {times: 2}, 'fast');
  268. }
  269. }
  270. }
  271. function createElForCore() {
  272. return $('<img>')
  273. .attr('src', 'res/images/coreIcon.png')
  274. .attr('alt', 'Core')
  275. .addClass('core')
  276. .css('position', 'absolute')
  277. .css('height', (40 * thisLevel.towerscale) + 'px')
  278. .css('width', (40 * thisLevel.towerscale) + 'px');
  279. }
  280. function createBaseElForTower(key) {
  281. var type = towers[key];
  282. return $('<img>')
  283. .attr('src', type.image)
  284. .attr('alt', type.name)
  285. .data('type', key)
  286. .addClass(type.class.toLowerCase())
  287. .addClass('tower');
  288. }
  289. function createElForTower(tower) {
  290. return createBaseElForTower(tower.type)
  291. .data('tower', tower)
  292. .draggable({
  293. containment: 'document',
  294. start: function(evt) {
  295. return !evt.shiftKey;
  296. },
  297. stop: function() {
  298. var el = $(this);
  299. el.data('tower').position = adjustMapOffset({top: parseInt(el.css('top')), left: parseInt(el.css('left'))}, thisLevel, 1);
  300. }
  301. })
  302. .css('position', 'absolute')
  303. .css('height', (40 * thisLevel.towerscale * towers[tower.type].defaultscale) + 'px')
  304. .css('width', (40 * thisLevel.towerscale * towers[tower.type].defaultscale) + 'px')
  305. .offset(adjustMapOffset(tower.position, thisLevel))
  306. .rotate(tower.rotation)
  307. .dblclick(function() {
  308. layout.towers = $.grep(layout.towers, function(value) { return value != tower; });
  309. $(this).remove();
  310. updateDefenseUnits();
  311. })
  312. .mousedown(function(e) {
  313. if (!e.shiftKey) {
  314. return;
  315. }
  316. var el = $(this);
  317. var centre = el.offsetCentre();
  318. var mouseX = e.pageX - centre.left, mouseY = e.pageY - centre.top;
  319. var initialMouseAngle = Math.atan2(mouseY, mouseX);
  320. var initialRotation = tower.rotation;
  321. var moveHandler = function(evt) {
  322. var mouseX = evt.pageX - centre.left, mouseY = evt.pageY - centre.top;
  323. var newMouseAngle = Math.atan2(mouseY, mouseX);
  324. var mouseDelta = newMouseAngle - initialMouseAngle;
  325. var rotation = initialRotation + newMouseAngle * (180 / Math.PI);
  326. tower.rotation = rotation;
  327. el.rotate(rotation);
  328. };
  329. var upHandler = function() {
  330. $(document).unbind('mousemove', moveHandler);
  331. $(document).unbind('mouseup', upHandler);
  332. };
  333. $(document).mousemove(moveHandler);
  334. $(document).mouseup(upHandler);
  335. return false;
  336. });
  337. }
  338. function adjustMapOffset(towerOffset, level, reverse) {
  339. var res = $.extend({}, towerOffset);
  340. if (level.offsets && !reverse) {
  341. res.left += level.offsets.left;
  342. res.top += level.offsets.top;
  343. }
  344. if (level.scale) {
  345. if (reverse) {
  346. res.left /= level.scale.left;
  347. res.top /= level.scale.top;
  348. } else {
  349. res.left *= level.scale.left;
  350. res.top *= level.scale.top;
  351. }
  352. }
  353. if (level.offsets && reverse) {
  354. res.left -= level.offsets.left;
  355. res.top -= level.offsets.top;
  356. }
  357. return res;
  358. }
  359. function clearLayout() {
  360. $('#mapcontainer .tower').remove();
  361. if (layout) {
  362. layout.towers = [];
  363. }
  364. }
  365. function clearCores() {
  366. $('#mapcontainer .core').remove();
  367. }
  368. function updateLayout(data) {
  369. clearLayout();
  370. clearCores();
  371. layout = data;
  372. thisLevel = levels[layout.level - 1];
  373. $.each(thisLevel.cores, function() {
  374. createElForCore().offset(adjustMapOffset(this, thisLevel)).appendTo($('#mapcontainer'));
  375. });
  376. _gaq.push(['_setCustomVar', 1, 'Level', thisLevel.name, 1]);
  377. $('#mapcontainer').css('background-image', 'url("' + thisLevel.minimap + '")');
  378. $('#notecontent').val(layout.notes);
  379. $.each(layout.towers, function() {
  380. createElForTower(this).appendTo($('#mapcontainer'));
  381. });
  382. updateDefenseUnits();
  383. var difficulty = layout.difficulty ? layout.difficulty : "unknown";
  384. $('#difficulty').text(difficulty).removeClass().addClass(difficulty);
  385. var type = layout.type && layout.type != 'none' ? layout.type : "unknown";
  386. $('#type').text(type);
  387. $('#modes').html(getModesHTML(layout.mode));
  388. $('#du_total').text(thisLevel.du);
  389. }
  390. function getLayout(id) {
  391. _gaq.push(['_trackPageview', '/view/' + id]);
  392. $.getJSON('res/data/layouts/' + id + '.js', updateLayout);
  393. }
  394. function showBlankLayout(id) {
  395. window.location.hash = 'blank:' + id;
  396. _gaq.push(['_trackPageview', '/view/blank:' + id]);
  397. updateLayout({level: id, towers:[]});
  398. }
  399. });
  400. var levels = [
  401. {
  402. name: 'The Deeper Well',
  403. minimap: 'res/images/minimaps/Level1.png',
  404. image: 'res/images/levels/Level1.jpg',
  405. du: 60,
  406. offsets: {left: 130, top: 65},
  407. scale: {left: 1.19, top: 1.17},
  408. towerscape: 0.9,
  409. cores: [{left: 108, top: 576}]
  410. },
  411. {
  412. name: 'Foundries and Forges',
  413. minimap: 'res/images/minimaps/Level2.png',
  414. image: 'res/images/levels/Level2.jpg',
  415. du: 80,
  416. offsets: {left: 80, top: 35},
  417. scale: {left: 1.35, top: 1.35},
  418. towerscale: 1,
  419. cores: [{left: 286, top: 255}]
  420. },
  421. {
  422. name: 'Magus Quarters',
  423. minimap: 'res/images/minimaps/Level3.png',
  424. image: 'res/images/levels/Level3.jpg',
  425. du: 90,
  426. offsets: {left: 80, top: 45},
  427. scale: {left: 1.35, top: 1.35},
  428. towerscale: 1.2,
  429. cores: [{left: 283, top: 146}]
  430. },
  431. {
  432. name: 'Alchemical Laboratory',
  433. minimap: 'res/images/minimaps/Level4.png',
  434. image: 'res/images/levels/Level4.jpg',
  435. du: 85,
  436. offsets: {left: 280, top: 110},
  437. scale: {left: 0.92, top: 0.92},
  438. towerscale: 0.9,
  439. cores: [{left: 147, top: 422}]
  440. },
  441. {
  442. name: 'Servants Quarters',
  443. minimap: 'res/images/minimaps/Level5.png',
  444. image: 'res/images/levels/Level5.jpg',
  445. du: 85,
  446. offsets: {left: 115, top: 120},
  447. scale: {left: 1.17, top: 1.17},
  448. towerscale: 0.9,
  449. cores: [{left: 87, top: 290}, {left: 293, top: 335}]
  450. },
  451. {
  452. name: 'Castle Armory',
  453. minimap: 'res/images/minimaps/Level6.png',
  454. image: 'res/images/levels/Level6.jpg',
  455. du: 90,
  456. offsets: {left: 80, top: 45},
  457. scale: {left: 1.35, top: 1.34},
  458. towerscale: 1,
  459. cores: [{left: 234, top: 352}, {left: 341, top: 352}]
  460. },
  461. {
  462. name: 'Hall of Court',
  463. minimap: 'res/images/minimaps/Level7.png',
  464. image: 'res/images/levels/Level7.jpg',
  465. du: 100,
  466. offsets: {left: 35, top: 80},
  467. scale: {left: 1.45, top: 1.45},
  468. towerscale: 1,
  469. cores: [{left: 306, top: 264}, {left: 456, top: 264}]
  470. },
  471. {
  472. name: 'The Throne Room',
  473. minimap: 'res/images/minimaps/Level8.png',
  474. image: 'res/images/levels/Level8.jpg',
  475. du: 100,
  476. offsets: {left: 18, top: 130},
  477. scale: {left: 1.6, top: 1.5},
  478. towerscale: 1,
  479. cores: [{left: 288, top: 201}, {left: 288, top: 307}]
  480. },
  481. {
  482. name: 'Royal Gardens',
  483. minimap: 'res/images/minimaps/RoyalGardens.png',
  484. image: 'res/images/levels/Level9.jpg',
  485. du: 130,
  486. offsets: {left: 170, top: 55},
  487. scale: {left: 1.2, top: 1.2},
  488. towerscale: 0.75,
  489. cores: [{left: 175, top: 359}, {left: 322, top: 243}, {left: 322, top: 480}]
  490. },
  491. {
  492. name: 'The Ramparts',
  493. minimap: 'res/images/minimaps/Level9.png',
  494. image: 'res/images/levels/Level10.jpg',
  495. du: 110,
  496. offsets: {left: 142, top: 5},
  497. scale: {left: 1.08, top: 1.1},
  498. towerscale: 0.9,
  499. cores: [{left: 329, top: 540}, {left: 494, top: 300}, {left: 531, top: 330}]
  500. },
  501. {
  502. name: 'Endless Spires',
  503. minimap: 'res/images/minimaps/TheSpires.png',
  504. image: 'res/images/levels/Level11.jpg',
  505. du: 110,
  506. offsets: {left: 142, top: 57},
  507. scale: {left: 1.04, top: 1.04},
  508. towerscale: 0.65,
  509. cores: [{left: 420, top: 308}, {left: 424, top: 526}, {left: 262, top: 526}]
  510. },
  511. {
  512. name: 'The Summit',
  513. minimap: 'res/images/minimaps/TheSummit.png',
  514. image: 'res/images/levels/Level12.jpg',
  515. du: 150,
  516. offsets: {left: 200, top: 120},
  517. towerscale: 0.9,
  518. cores: [{left: 283, top: 362}, {left: 213, top: 548}, {left: 356, top: 547}]
  519. },
  520. {
  521. name: 'Glitterhelm Caverns',
  522. minimap: 'res/images/minimaps/caverns_minimap.png',
  523. image: 'http://placehold.it/200x100',
  524. du: 165,
  525. offsets: {left: 90, top: 35},
  526. scale: {left: 1.3, top: 1.27},
  527. towerscale: 0.8,
  528. cores: [{left: 230, top: 134}, {left: 234, top: 444}, {left: 413, top: 419}, {left: 38, top: 569}]
  529. },
  530. {}, // Uber monsterfest
  531. {}, // Tree of life
  532. {
  533. name: 'Mistymire Forest',
  534. minimap: 'res/images/minimaps/Mistymire.png',
  535. image: 'http://placehold.it/200x100',
  536. du: 140,
  537. offsets: {left: 170, top: 50},
  538. scale: {left: 1.1, top: 1.1},
  539. towerscale: 0.5,
  540. cores: [{left: 129, top: 354}, {left: 241, top: 242}, {left: 318, top: 284}, {left: 299, top: 404}]
  541. },
  542. ];
  543. var towers = {
  544. 'spike': {name: 'Spike Blockade', image: 'res/images/towers/spikyBlockadeTower_Icon.png', class: 'Squire', units: 3, defaultscale: 1},
  545. 'bouncer': {name: 'Bouncer Blockade', image: 'res/images/towers/bouncerTower_Icon.png', class: 'Squire', units: 4, defaultscale: 1},
  546. 'harpoon': {name: 'Harpoon Turret', image: 'res/images/towers/harpoonTower_Icon.png', class: 'Squire', units: 6, defaultscale: 1},
  547. 'bowling': {name: 'Bowling Ball Turret', image: 'res/images/towers/bowlingBallTower_Icon.png', class: 'Squire', units: 7, defaultscale: 1},
  548. 'slice': {name: 'Slice N Dice Blockade', image: 'res/images/towers/slicerTower_Icon.png', class: 'Squire', units: 8},
  549. 'missile': {name: 'Magic Missile Tower', image: 'res/images/towers/missleTower_Icon.png', class: 'Apprentice', units: 3, defaultscale: 1},
  550. 'blockade': {name: 'Magic Blockade', image: 'res/images/towers/blockadeTower_Icon.png', class: 'Apprentice', units: 1, defaultscale: 1},
  551. 'fireball': {name: 'Fireball Tower', image: 'res/images/towers/fireTower_Icon.png', class: 'Apprentice', units: 5, defaultscale: 1},
  552. 'lightning': {name: 'Lightning Tower', image: 'res/images/towers/lightningTower_Icon.png', class: 'Apprentice', units: 7, defaultscale: 1},
  553. 'striker': {name: 'Deadly Striker Tower', image: 'res/images/towers/strikerTower_Icon.png', class: 'Apprentice', units: 8, defaultscale: 1},
  554. 'ensnare': {name: 'Ensnare Aura', image: 'res/images/towers/stickyGoopAura_Icon.png', class: 'Monk', units: 3, defaultscale: 2.5},
  555. 'electric': {name: 'Electric Aura', image: 'res/images/towers/deathlyHallowsAura_Icon.png', class: 'Monk', units: 5, defaultscale: 2.5},
  556. 'healing': {name: 'Healing Aura', image: 'res/images/towers/healingAura_Icon.png', class: 'Monk', units: 5, defaultscale: 2.5},
  557. 'drain': {name: 'Strength Drain Aura', image: 'res/images/towers/strengthDrainAura_Icon.png', class: 'Monk', units: 6, defaultscale: 2.5},
  558. 'enrage': {name: 'Enrage Aura', image: 'res/images/towers/enrageAura_Icon.png', class: 'Monk', units: 5, defaultscale: 2.5},
  559. 'gas': {name: 'Gas Trap', image: 'res/images/towers/gasTrap_Icon.png', class: 'Huntress', units: 3, defaultscale: 1},
  560. 'mine': {name: 'Proximity Mine Trap', image: 'res/images/towers/proxMineTrap_Icon.png', class: 'Huntress', units: 3, defaultscale: 1},
  561. 'inferno': {name: 'Inferno Trap', image: 'res/images/towers/infernoTrap_Icon.png', class: 'Huntress', units: 4, defaultscale: 1},
  562. 'etheral': {name: 'Etheral Spike Trap', image: 'res/images/towers/etherialSpikeTrap_Icon.png', class: 'Huntress', units: 3, defaultscale: 1},
  563. 'darkness': {name: 'Darkness Trap', image: 'res/images/towers/darknessTrap_Icon.png', class: 'Huntress', units: 6, defaultscale: 1},
  564. };