Advertisement
Guest User

Starve.io Extension Source Code v.0.0.1.5

a guest
Jun 11th, 2017
366
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. setTimeout(function() {
  2.   // DEOBFUSCATION
  3.   var SPRITE = yolo1492;
  4.   var client = yolo1476;
  5.   var RECIPES = yolo1491;
  6.   var world = yolo1556;
  7.   var WORLD = yolo1438;
  8.   user.show_spectators = user.yolo1609;
  9.   get_mouse_pos = yolo1608;
  10.   ctx = yolo1540;
  11.  
  12.   var OBFUSCATOR_FN = _0x97e8;
  13.   var WORLD_FAST_UNITS_ARR_NAME = "yolo1519";
  14.   var USER_UID_VAR_NAME = OBFUSCATOR_FN("0x3b2");
  15.   var UPDATE_INV_BUTTONS_FN_NAME = OBFUSCATOR_FN("0x483");
  16.   var SELECT_CRAFT_FN_NAME = OBFUSCATOR_FN("0x49c");
  17.   var CLIENT_SELECT_INV_FN_NAME = OBFUSCATOR_FN("0x4aa");
  18.   var DRAW_UI_INVENTORY_FN_NAME = "yolo1433";
  19.   var GAME_TRIGGER_KEYUP_FN_NAME = OBFUSCATOR_FN("0x588");
  20.   var CLIENT_BUILD_STOP_FN_NAME = OBFUSCATOR_FN("0x46f");
  21.   var CLIENT_DELETE_INV_FN_NAME = OBFUSCATOR_FN("0x4ac");
  22.   var CLIENT_SOCKET_VAR_NAME = OBFUSCATOR_FN("0x450");
  23.   var GAME_DRAW_UI_FN_NAME = OBFUSCATOR_FN("0x584");
  24.   var CLIENT_GET_TIME_FN_NAME = OBFUSCATOR_FN("0x484")
  25.   // END DEOBFUSCATION
  26.  
  27.   var unique_index_counter = 500;
  28.   var find_unique_index = function() {
  29.     while(sprite[unique_index_counter] != null) {
  30.       unique_index_counter++;
  31.     }
  32.     return unique_index_counter;
  33.   };
  34.  
  35.   var create_help = function() {
  36.     var title = 'HELP MENU';
  37.     var title_font = "bold 40px Baloo Paaji";
  38.     var letter_font = "bold 35px Baloo Paaji";
  39.     var msg_font = "30px Baloo Paaji";
  40.    
  41.     var title_font_height = 40 * 1.1;
  42.     var letter_font_height = 35 * 1.1;
  43.     var msg_font_height = 30 * 1.1;
  44.    
  45.     var help_messages = [
  46.      [ 'H', 'Open Help - open this help menu' ],
  47.      [ 'Y', 'Open Map - open the larger map' ],
  48.      [ 'U', 'Open Recipes - show all recipes' ],
  49.      [ 'R', 'Auto-Feed - auto-eat food when low' ],
  50.      [ 'T', 'Auto-Book - auto-equip book on craft' ],
  51.      [ 'P', 'Show Spectators - only in hunger games' ],
  52.      [ 'L', 'Fast-Delete - no warning on deleting items' ],
  53.      [ 'C', 'Clock - toggle the clock' ],
  54.      [ '*', 'Type "-swap 1 2" to swap slots 1 and 2' ],
  55.      [ '*', 'Type "-remap F 1" to have slot 1 bound to F' ],
  56.      [ '*', 'Type "-unmapall" to clear all remaps' ]
  57.     ];
  58.    
  59.     var edge_padding_x = 5;
  60.     var top_edge_padding_y = 15;
  61.     var bot_edge_padding_y = 3;
  62.     var title_padding_extra_y = 5;
  63.     var line_padding_y = 3;
  64.     var letter_msg_padding = 3;
  65.    
  66.     var temp_canv = document.createElement("canvas");
  67.     var temp_ctx = temp_canv.getContext("2d");
  68.    
  69.     var longest_letter = 0;
  70.     var longest_msg = 0;
  71.     var total_height = top_edge_padding_y + title_font_height + title_padding_extra_y;
  72.     for(var i = 0; i < help_messages.length; i++)
  73.     {
  74.       total_height += line_padding_y;
  75.      
  76.       temp_ctx.font = letter_font;
  77.       var letter_metrics = temp_ctx.measureText(help_messages[i][0]);
  78.      
  79.       temp_ctx.font = msg_font;
  80.       var msg_metrics = temp_ctx.measureText(help_messages[i][1]);
  81.       longest_letter = Math.max(longest_letter, letter_metrics.width);
  82.       longest_msg = Math.max(longest_msg, msg_metrics.width);
  83.       total_height += Math.max(msg_font_height, letter_font_height);
  84.     }
  85.     total_height += bot_edge_padding_y;
  86.    
  87.     var total_width = edge_padding_x + longest_letter + letter_msg_padding + longest_msg + edge_padding_x;
  88.    
  89.     temp_canv.width = total_width;
  90.     temp_canv.height = total_height;
  91.    
  92.     temp_ctx.globalAlpha = .5;
  93.     round_rect(temp_ctx, 0, 0, temp_canv.width, temp_canv.height, 10);
  94.     fill_path(temp_ctx, "#000");
  95.    
  96.     temp_ctx.globalAlpha = 1.0;
  97.    
  98.     temp_ctx.textAlign = 'left';
  99.     temp_ctx.fillStyle = '#FFF';
  100.     temp_ctx.font = title_font;
  101.     temp_ctx.fillText(title, (temp_canv.width / 2) - (temp_ctx.measureText(title).width / 2), top_edge_padding_y + title_font_height / 2);
  102.    
  103.     temp_ctx.textAlign = 'left';
  104.     var y = top_edge_padding_y + title_font_height + title_padding_extra_y;
  105.     for(var i = 0; i < help_messages.length; i++) {
  106.       y += line_padding_y;
  107.      
  108.       var x = edge_padding_x;
  109.       temp_ctx.font = letter_font;
  110.       temp_ctx.fillText(help_messages[i][0], x, y + letter_font_height / 2)
  111.       x += longest_letter + letter_msg_padding;
  112.      
  113.       temp_ctx.font = msg_font;
  114.       temp_ctx.fillText(help_messages[i][1], x, y + msg_font_height / 2);
  115.       y += Math.max(letter_font_height, msg_font_height)
  116.     }
  117.    
  118.     return temp_canv
  119.   }
  120.  
  121.   function create_arrow_back(color) {
  122.     var bknd_canv = document.createElement("canvas");
  123.     var bknd_ctx = bknd_canv.getContext("2d");
  124.    
  125.     // todo make an arrow
  126.     bknd_ctx.font = "20px Baloo Paaji";
  127.     bknd_canv.width = bknd_ctx.measureText("BACK").width + 2;
  128.     bknd_canv.height = 24;
  129.    
  130.     bknd_ctx.font = "20px Baloo Paaji";
  131.     bknd_ctx.textAlign = 'center';
  132.     bknd_ctx.fillStyle = color;
  133.     bknd_ctx.fillText('BACK', bknd_canv.width / 2, bknd_canv.height / 2);
  134.    
  135.     return bknd_canv;
  136.   }
  137.  
  138.   function create_arrow_next(color) {
  139.     var bknd_canv = document.createElement("canvas");
  140.     var bknd_ctx = bknd_canv.getContext("2d");
  141.    
  142.     // todo make an arrow
  143.     bknd_ctx.font = "20px Baloo Paaji";
  144.     bknd_canv.width = bknd_ctx.measureText("NEXT").width + 2;
  145.     bknd_canv.height = 24;
  146.    
  147.     bknd_ctx.font = "20px Baloo Paaji";
  148.     bknd_ctx.textAlign = 'center';
  149.     bknd_ctx.fillStyle = color;
  150.     bknd_ctx.fillText('NEXT', bknd_canv.width / 2, bknd_canv.height / 2);
  151.    
  152.     return bknd_canv;
  153.   }
  154.  
  155.   var cntr = 0;
  156.   var PAGES = [];
  157.   PAGES["CATEGORIES_1"] = cntr++;
  158.   PAGES["PICKAXES"] = cntr++;
  159.   PAGES["SWORDS"] = cntr++;
  160.   PAGES["SPEARS"] = cntr++;
  161.   PAGES["HAMMERS"] = cntr++;
  162.   PAGES["PLACEABLES"] = cntr++;
  163.   PAGES["WALLS"] = cntr++;
  164.   PAGES["SPIKES"] = cntr++;
  165.   PAGES["DOORS"] = cntr++;
  166.   PAGES["FOOD_HEALING"] = cntr++;
  167.   PAGES["HELMETS"] = cntr++;
  168.   PAGES["WEARABLES"] = cntr++;
  169.   PAGES["MISCELLANEOUS"] = cntr++;
  170.   PAGES["CRAFTING_ITEMS"] = cntr++;
  171.  
  172.   // All the create_recipe_page_ functions return [ canvas, buttons ]
  173.   // ex. [ img, [ { page_num, translate: {x, y}, width, height, normal, hovered, pushed, contains(x,y) }, ... ]
  174.  
  175.   // returns canvas
  176.   var __create_category_button = function(img, text, font, font_height, bknd_color, bknd_opacity, text_color) {
  177.     var edge_padding_x = 3;
  178.     var edge_padding_y = 3;
  179.     var img_text_spacing_x = 3;
  180.     var roundedness = 10;
  181.    
  182.     var bknd_canv = document.createElement("canvas");
  183.     var bknd_ctx = bknd_canv.getContext("2d");
  184.    
  185.     bknd_ctx.font = font
  186.     var text_metric = bknd_ctx.measureText(text);
  187.    
  188.     bknd_canv.width = edge_padding_x + img.width + img_text_spacing_x + text_metric.width + edge_padding_x;
  189.     bknd_canv.height = edge_padding_y + Math.max(font_height, img.height) + edge_padding_y;
  190.    
  191.     if(bknd_color != null) {
  192.       bknd_ctx.globalAlpha = bknd_opacity;
  193.       round_rect(bknd_ctx, 0, 0, bknd_canv.width, bknd_canv.height, roundedness);
  194.       fill_path(bknd_ctx, bknd_color);
  195.       bknd_ctx.globalAlpha = 1;
  196.     }
  197.    
  198.     bknd_ctx.font = font;
  199.     bknd_ctx.fillStyle = text_color;
  200.     bknd_ctx.drawImage(img, edge_padding_x, edge_padding_y);
  201.     bknd_ctx.fillText(text, edge_padding_x + img.width + img_text_spacing_x, edge_padding_y + img.height / 2);
  202.    
  203.     return bknd_canv;
  204.   }
  205.  
  206.   function __ext_create_button(normal, hovered, pushed) {
  207.     var res = { translate: { x: 0, y: 0 } }
  208.     res.normal = normal;
  209.     res.hovered = hovered;
  210.     res.pushed = pushed;
  211.     res.width = res.normal.width;
  212.     res.height = res.normal.height;
  213.     res.contains = function(x, y) {
  214.       return x >= this.translate.x && y >= this.translate.y && x <= (this.translate.x + this.width) && y <= (this.translate.y + this.height);
  215.     };
  216.     return res;
  217.   }
  218.   // returns { translate: {x, y}, width, height, normal, hovered, pushed, contains(x,y) }
  219.   var create_category_button = function(img, text) {
  220.     var font = '24px Baloo Paaji';
  221.     var font_height = 24;
  222.     var text_color = '#FFF';
  223.     var hovered_background_color = '#000';
  224.     var pushed_background_color = '#000';
  225.     var hovered_background_opacity = 0.4;
  226.     var pushed_background_opacity = 0.8;
  227.    
  228.     var res = {
  229.       translate: { x: 0, y: 0 }  
  230.     }
  231.    
  232.     res.normal = CTI(__create_category_button(img, text, font, font_height, null, 0, text_color));
  233.     res.width = res.normal.width;
  234.     res.height = res.normal.height;
  235.     res.hovered = CTI(__create_category_button(img, text, font, font_height, hovered_background_color, hovered_background_opacity, text_color));
  236.     res.pushed = CTI(__create_category_button(img, text, font, font_height, pushed_background_color, pushed_background_opacity, text_color));
  237.     res.contains = function(x, y) {
  238.       return x >= this.translate.x && y >= this.translate.y && x <= (this.translate.x + this.width) && y <= (this.translate.y + this.height);
  239.     };
  240.    
  241.     return res;
  242.   }
  243.  
  244.   // categories, in the form [ { page_num, img, category_name }, ... ]
  245.   // returns [ canvas, context2d, buttons ]
  246.   var __create_recipe_page_categories = function(categories, prev_category_page_num, next_category_page_num) {
  247.     var columns = 3;
  248.     var left_edge_padding_x = 5;
  249.     var right_edge_padding_x = 5;
  250.     var top_edge_padding_y = 15;
  251.     var bot_edge_padding_y = 10;
  252.     var title_below_padding_y = 5;
  253.     var row_padding_y = 5;
  254.     var title_font = "bold 40px Baloo Paaji";
  255.     var title_font_height = 44;
  256.     var category_font = "24px Baloo Paaji";
  257.     var category_font_height = 24;
  258.     var category_img_text_padding_x = 5;
  259.     var padding_y_before_pagination = 8;
  260.     var column_padding_x = 5;
  261.    
  262.     var prev_button = __ext_create_button(sprite[SPRITE.ARROW_BACK][0], sprite[SPRITE.ARROW_BACK][1], sprite[SPRITE.ARROW_BACK][2]);
  263.     var next_button = __ext_create_button(sprite[SPRITE.ARROW_NEXT][0], sprite[SPRITE.ARROW_NEXT][1], sprite[SPRITE.ARROW_NEXT][2]);
  264.    
  265.     var title = 'CATEGORIES';
  266.    
  267.     var bknd_canv = document.createElement("canvas");
  268.     var bknd_ctx = bknd_canv.getContext("2d");
  269.    
  270.     var title = 'CATEGORIES'
  271.    
  272.     bknd_ctx.font = title_font;
  273.     var title_width = bknd_ctx.measureText(title).width;
  274.    
  275.     bknd_ctx.font = category_font;
  276.     var row_height_prev = 0;
  277.     var max_column_width = 0;
  278.     var total_height = top_edge_padding_y + title_font_height + title_below_padding_y;
  279.     for(var i = 0; i < categories.length; i++) {
  280.       if(i != 0 && i % columns == 0) {
  281.         total_height += row_padding_y + row_height_prev;
  282.         row_height_prev = 0;
  283.       }
  284.      
  285.       var cat_width = categories[i].img.width + category_img_text_padding_x + bknd_ctx.measureText(categories[i].category_name).width;
  286.       max_column_width = Math.max(max_column_width, cat_width);
  287.       row_height_prev = Math.max(row_height_prev, categories[i].img.height);
  288.     }
  289.     total_height += row_padding_y + row_height_prev;
  290.     if(prev_category_page_num != null || next_category_page_num != null) {
  291.       total_height += padding_y_before_pagination + Math.max(prev_button.height, next_button.height);
  292.     }
  293.     total_height += bot_edge_padding_y;
  294.     var total_width = left_edge_padding_x + max_column_width * columns + column_padding_x * (columns - 1) + right_edge_padding_x;
  295.    
  296.     bknd_canv.width = total_width;
  297.     bknd_canv.height = total_height;
  298.    
  299.     bknd_ctx.globalAlpha = 0.5;
  300.     round_rect(bknd_ctx, 0, 0, bknd_canv.width, bknd_canv.height, 10);
  301.     fill_path(bknd_ctx, '#000');
  302.     bknd_ctx.globalAlpha = 1;
  303.    
  304.     bknd_ctx.font = title_font;
  305.     bknd_ctx.fillStyle = '#FFF';
  306.     var title_metr = bknd_ctx.measureText(title);
  307.     bknd_ctx.fillText(title, bknd_canv.width / 2 - title_metr.width / 2, top_edge_padding_y + title_font_height / 2);
  308.    
  309.     var buttons = []
  310.     bknd_ctx.font = category_font;
  311.     var y = top_edge_padding_y + title_font_height + title_below_padding_y;
  312.     var x = left_edge_padding_x;
  313.     row_height_prev = 0;
  314.     for(var i = 0; i < categories.length; i++) {
  315.       if(i != 0 && i % columns == 0) {
  316.         y += row_padding_y + row_height_prev;
  317.         x = left_edge_padding_x;
  318.       }
  319.      
  320.       var but = create_category_button(categories[i].img, categories[i].category_name);
  321.       but.page_num = categories[i].page_num;
  322.       but.translate.x = x;
  323.       but.translate.y = y;
  324.       buttons[buttons.length] = but;
  325.      
  326.       row_height_prev = Math.max(row_height_prev, categories[i].img.height);
  327.       x += max_column_width + column_padding_x;
  328.     }
  329.     y += row_padding_y + row_height_prev;
  330.    
  331.     if(prev_category_page_num != null) {
  332.       prev_button.translate.x = left_edge_padding_x;
  333.       prev_button.translate.y = total_height - prev_button.height - bot_edge_padding_y;
  334.      
  335.       buttons[button.length] = prev_button;
  336.     }
  337.    
  338.     if(next_category_page_num != null) {
  339.       next_button.translate.x = total_width - next_button.width - right_edge_padding_x;
  340.       next_button.translate.y = total_height - next_button.height - bot_edge_padding_y;
  341.      
  342.       buttons[buttons.length] = next_button;
  343.     }
  344.    
  345.     return [ bknd_canv, bknd_ctx, buttons ];
  346.   }
  347.  
  348.   var create_recipe_page_categories_1 = function() {
  349.     var tmp = __create_recipe_page_categories([
  350.       { page_num: PAGES.PICKAXES, img: sprite[SPRITE.INV_PICK_WOOD][1], category_name: "Pickaxes" },
  351.       { page_num: PAGES.SWORDS, img: sprite[SPRITE.INV_SWORD][1], category_name: "Swords" },
  352.       { page_num: PAGES.SPEARS, img: sprite[SPRITE.INV_SPEAR][1], category_name: "Spears" },
  353.       { page_num: PAGES.HAMMERS, img: sprite[SPRITE.INV_HAMMER][1], category_name: "Hammers" },
  354.       { page_num: PAGES.PLACEABLES, img: sprite[SPRITE.INV_FIRE][1], category_name: "Placeables" },
  355.       { page_num: PAGES.WALLS, img: sprite[SPRITE.INV_WALL][1], category_name: "Walls" },
  356.       { page_num: PAGES.SPIKES, img: sprite[SPRITE.INV_SPIKE][1], category_name: "Spikes" },
  357.       { page_num: PAGES.DOORS, img: sprite[SPRITE.INV_DOOR_WOOD_CLOSE][1], category_name: "Doors" },
  358.       { page_num: PAGES.FOOD_HEALING, img: sprite[SPRITE.INV_COOKED_MEAT][1], category_name: "Food & Healing" },
  359.       { page_num: PAGES.HELMETS, img: sprite[SPRITE.INV_STONE_HELMET][1], category_name: "Helmets" },
  360.       { page_num: PAGES.WEARABLES, img: sprite[SPRITE.INV_EARMUFFS][1], category_name: "Wearables" },
  361.       { page_num: PAGES.MISCELLANEOUS, img: sprite[SPRITE.INV_LOCK][1], category_name: "Misc" },
  362.       { page_num: PAGES.CRAFTING_ITEMS, img: sprite[SPRITE.INV_PAPER][1], category_name: "Crafting Items" },
  363.     ]);
  364.    
  365.     var bknd_canv = tmp[0];
  366.     var bknd_ctx = tmp[1];
  367.     var buttons = tmp[2];
  368.    
  369.     return [ CTI(bknd_canv), buttons ];
  370.   }
  371.  
  372.   function get_amount_as_img(amount) {
  373.     if(!sprite[SPRITE.COUNTER][amount]) {
  374.       sprite[SPRITE.COUNTER][amount] = create_text(scale, "x" + amount, 20, "#FFF");
  375.     }
  376.     return sprite[SPRITE.COUNTER][amount];
  377.   }
  378.  
  379.   // accepts string, int, [ { ingredients: [ { img, amount }, ... ], result: { img, amount } ]
  380.   // returns [ canvas, context2d, buttons ]
  381.   function __create_recipe_page_leaf(title, category_page_num, recipes) {
  382.     var bknd_canv = document.createElement("canvas");
  383.     var bknd_ctx = bknd_canv.getContext("2d");
  384.    
  385.     var title_font = "bold 40px Baloo Paaji";
  386.     var title_font_height = 44;
  387.     var title_below_padding_y = 0;
  388.    
  389.     var plus_font = "45px Baloo Paaji";
  390.     var plus_y_offset = 12;
  391.     var plus_y_height = 24;
  392.     var plus_x_padding_left = 3;
  393.     var plus_x_padding_right = 3;
  394.     var plus_width = 26;
  395.    
  396.     var equal_font = plus_font;
  397.     var equal_y_offset = 12;
  398.     var equal_y_height = 16;
  399.     var equal_x_padding_left = 3;
  400.     var equal_x_padding_right = 3;
  401.     var equal_width = 22;
  402.    
  403.     var top_edge_padding_y = 15;
  404.     var left_edge_padding_x = 10;
  405.     var bot_edge_padding_y = 10;
  406.     var right_edge_padding_x = 5;
  407.    
  408.     var padding_above_arrow_back = 8;
  409.     var arrow_back_width = sprite[SPRITE.ARROW_BACK][0].width;
  410.     var arrow_back_height = sprite[SPRITE.ARROW_BACK][0].height;
  411.    
  412.     var row_padding_y = 5;
  413.    
  414.     var total_height = top_edge_padding_y + title_font_height + title_below_padding_y;
  415.     bknd_ctx.font = title_font;
  416.     var max_row_width = left_edge_padding_x + bknd_ctx.measureText(title).width + right_edge_padding_x;
  417.     var row_heights = []
  418.     for(var i = 0; i < recipes.length; i++) {
  419.       if(i != 0) {
  420.         total_height += row_padding_y;
  421.       }
  422.      
  423.       var row_height = 0;
  424.       var row_width = left_edge_padding_x;
  425.       for(var j = 0; j < recipes[i].ingredients.length; j++) {
  426.         if(j != 0) {
  427.           row_width += plus_x_padding_left + plus_width + plus_x_padding_right;
  428.         }
  429.         var ing = recipes[i].ingredients[j];
  430.         row_width += ing.img.width;
  431.         row_height = Math.max(row_height, ing.img.height);
  432.       }
  433.      
  434.       row_width += equal_x_padding_left + equal_width + equal_x_padding_right;
  435.       row_width += recipes[i].result.img.width + right_edge_padding_x;
  436.       row_height = Math.max(row_height, recipes[i].result.img.height);
  437.       total_height += row_height;
  438.       row_heights[i] = row_height;
  439.       max_row_width = Math.max(max_row_width, row_width);
  440.     }
  441.     total_height += padding_above_arrow_back + arrow_back_height + bot_edge_padding_y;
  442.    
  443.    
  444.     bknd_canv.width = max_row_width;
  445.     bknd_canv.height = total_height;
  446.    
  447.     bknd_ctx.globalAlpha = 0.5;
  448.     round_rect(bknd_ctx, 0, 0, bknd_canv.width, bknd_canv.height, 10);
  449.     fill_path(bknd_ctx, '#000');
  450.     bknd_ctx.globalAlpha = 1;
  451.    
  452.     bknd_ctx.font = title_font;
  453.     bknd_ctx.fillStyle = '#FFF';
  454.     bknd_ctx.fillText(title, bknd_canv.width / 2 - bknd_ctx.measureText(title).width / 2, top_edge_padding_y + title_font_height / 2);
  455.    
  456.     var y = top_edge_padding_y + title_font_height + title_below_padding_y;
  457.     for(var i = 0; i < recipes.length; i++) {
  458.       if(i != 0) {
  459.         y += row_padding_y;
  460.       }
  461.      
  462.       var row_height = row_heights[i];
  463.       var x = left_edge_padding_x;
  464.      
  465.       for(var j = 0; j < recipes[i].ingredients.length; j++) {
  466.         if(j != 0) {
  467.           x += plus_x_padding_left;
  468.           bknd_ctx.font = plus_font;
  469.           bknd_ctx.fillText("+", x, y + row_height / 2 + plus_y_offset);
  470.           x += plus_width + plus_x_padding_right;
  471.         }
  472.        
  473.         var ing = recipes[i].ingredients[j];
  474.         var ingImgY = y + (row_height - ing.img.height) / 2;
  475.         bknd_ctx.drawImage(ing.img, x, ingImgY)
  476.         if(ing.amount != 1) {
  477.           var amtAsImg = get_amount_as_img(ing.amount);
  478.           bknd_ctx.drawImage(amtAsImg, x + ing.img.width - amtAsImg.width - 5, ingImgY + ing.img.height - amtAsImg.height - 5);
  479.         }
  480.        
  481.         x += ing.img.width;
  482.       }
  483.      
  484.       bknd_ctx.font = equal_font;
  485.       x += equal_x_padding_left;
  486.       bknd_ctx.fillText("=", x, y + row_height / 2 + equal_y_offset);
  487.       x += equal_width + equal_x_padding_right;
  488.       var resImgY = y + (row_height - recipes[i].result.img.height) / 2;
  489.       bknd_ctx.drawImage(recipes[i].result.img, x, resImgY);
  490.       if(recipes[i].result.amount != 1) {
  491.         var resAmtAsImg = get_amount_as_img(recipes[i].result.amount);
  492.         bknd_ctx.drawImage(resAmtAsImg, x + recipes[i].result.img.width - resAmtAsImg.width - 5, resImgY + recipes[i].result.img.height - resAmtAsImg.height - 5);
  493.       }
  494.       y += row_height;
  495.     }
  496.    
  497.     var buttons = []
  498.     y += padding_above_arrow_back;
  499.     buttons[buttons.length] = {
  500.       page_num: category_page_num,
  501.       translate: { x: left_edge_padding_x, y: y + arrow_back_height/2 },
  502.       width: arrow_back_width,
  503.       height: arrow_back_height,
  504.       normal: sprite[SPRITE.ARROW_BACK][0],
  505.       hovered: sprite[SPRITE.ARROW_BACK][1],
  506.       pushed: sprite[SPRITE.ARROW_BACK][2],
  507.       contains: function(x, y) { return x >= this.translate.x && y >= this.translate.y && x <= this.translate.x + this.width && y <= this.translate.y + this.height; }
  508.     };
  509.     return [ bknd_canv, bknd_ctx, buttons ];
  510.   }
  511.  
  512.   var create_recipe_page_pickaxes = function() {
  513.     var tmp = __create_recipe_page_leaf('PICKAXES', PAGES.CATEGORIES_1, [
  514.       {
  515.         ingredients: [
  516.           { img: sprite[SPRITE.INV_WOOD][1], amount: 15 }
  517.         ],
  518.         result: { img: sprite[SPRITE.INV_PICK_WOOD][1], amount: 1 }
  519.       },
  520.       {
  521.         ingredients: [
  522.           { img: sprite[SPRITE.INV_WORK][1], amount: 1 },
  523.           { img: sprite[SPRITE.INV_PICK_WOOD][1], amount: 1 },
  524.           { img: sprite[SPRITE.INV_WOOD][1], amount: 60 },
  525.           { img: sprite[SPRITE.INV_STONE][1], amount: 20 }
  526.         ],
  527.         result: { img: sprite[SPRITE.INV_PICK][1], amount: 1 }
  528.       },
  529.       {
  530.         ingredients: [
  531.           { img: sprite[SPRITE.INV_WORK][1], amount: 1 },
  532.           { img: sprite[SPRITE.INV_PICK][1], amount: 1 },
  533.           { img: sprite[SPRITE.INV_WOOD][1], amount: 60 },
  534.           { img: sprite[SPRITE.INV_STONE][1], amount: 40 },
  535.           { img: sprite[SPRITE.INV_GOLD][1], amount: 30 }
  536.         ],
  537.         result: { img: sprite[SPRITE.INV_PICK_GOLD][1], amount: 1 }
  538.       },
  539.       {
  540.         ingredients: [
  541.           { img: sprite[SPRITE.INV_WORK][1], amount: 1 },
  542.           { img: sprite[SPRITE.INV_PICK_GOLD][1], amount: 1 },
  543.           { img: sprite[SPRITE.INV_STONE][1], amount: 100 },
  544.           { img: sprite[SPRITE.INV_GOLD][1], amount: 60 },
  545.           { img: sprite[SPRITE.INV_DIAMOND][1], amount: 30 }
  546.         ],
  547.         result: { img: sprite[SPRITE.INV_PICK_DIAMOND][1], amount: 1 }
  548.       },
  549.       {
  550.         ingredients: [
  551.           { img: sprite[SPRITE.INV_WORK][1], amount: 1 },
  552.           { img: sprite[SPRITE.INV_PICK_DIAMOND][1], amount: 1 },
  553.           { img: sprite[SPRITE.INV_GOLD][1], amount: 90 },
  554.           { img: sprite[SPRITE.INV_DIAMOND][1], amount: 60 },
  555.           { img: sprite[SPRITE.INV_AMETHYST][1], amount: 30 }
  556.         ],
  557.         result: { img: sprite[SPRITE.INV_PICK_AMETHYST][1], amount: 1 }
  558.       }
  559.     ])
  560.    
  561.     var bknd_canv = tmp[0];
  562.     var bknd_ctx = tmp[1];
  563.     var buttons = tmp[2];
  564.    
  565.     return [ CTI(bknd_canv), buttons ];
  566.   }
  567.  
  568.   var create_recipe_page_swords = function() {
  569.     var tmp = __create_recipe_page_leaf('SWORDS', PAGES.CATEGORIES_1, [
  570.       {
  571.         ingredients: [
  572.           { img: sprite[SPRITE.INV_WORK][1], amount: 1 },
  573.           { img: sprite[SPRITE.INV_WOOD][1], amount: 60 },
  574.           { img: sprite[SPRITE.INV_STONE][1], amount: 30 }
  575.         ],
  576.         result: { img: sprite[SPRITE.INV_SWORD][1], amount: 1 }
  577.       },
  578.       {
  579.         ingredients: [
  580.           { img: sprite[SPRITE.INV_WORK][1], amount: 1 },
  581.           { img: sprite[SPRITE.INV_SWORD][1], amount: 1 },
  582.           { img: sprite[SPRITE.INV_WOOD][1], amount: 80 },
  583.           { img: sprite[SPRITE.INV_STONE][1], amount: 60 },
  584.           { img: sprite[SPRITE.INV_GOLD][1], amount: 50 }
  585.         ],
  586.         result: { img: sprite[SPRITE.INV_SWORD_GOLD][1], amount: 1 }
  587.       },
  588.       {
  589.         ingredients: [
  590.           { img: sprite[SPRITE.INV_WORK][1], amount: 1 },
  591.           { img: sprite[SPRITE.INV_SWORD_GOLD][1], amount: 1 },
  592.           { img: sprite[SPRITE.INV_STONE][1], amount: 100 },
  593.           { img: sprite[SPRITE.INV_GOLD][1], amount: 80 },
  594.           { img: sprite[SPRITE.INV_DIAMOND][1], amount: 50 }
  595.         ],
  596.         result: { img: sprite[SPRITE.INV_SWORD_DIAMOND][1], amount: 1 }
  597.       },
  598.       {
  599.         ingredients: [
  600.           { img: sprite[SPRITE.INV_WORK][1], amount: 1 },
  601.           { img: sprite[SPRITE.INV_SWORD_DIAMOND][1], amount: 1 },
  602.           { img: sprite[SPRITE.INV_GOLD][1], amount: 130 },
  603.           { img: sprite[SPRITE.INV_DIAMOND][1], amount: 80 },
  604.           { img: sprite[SPRITE.INV_AMETHYST][1], amount: 50 }
  605.         ],
  606.         result: { img: sprite[SPRITE.INV_SWORD_AMETHYST][1], amount: 1 }
  607.       }
  608.     ]);
  609.    
  610.     var bknd_canv = tmp[0];
  611.     var bknd_ctx = tmp[1];
  612.     var buttons = tmp[2];
  613.    
  614.     return [ CTI(bknd_canv), buttons ];
  615.   }
  616.  
  617.   var create_recipe_page_spears = function() {
  618.     var tmp = __create_recipe_page_leaf('SPEARS', PAGES.CATEGORIES_1, [
  619.       {
  620.         ingredients: [
  621.           { img: sprite[SPRITE.INV_WORK][1], amount: 1 },
  622.           { img: sprite[SPRITE.INV_WOOD][1], amount: 80 },
  623.           { img: sprite[SPRITE.INV_STONE][1], amount: 20 }
  624.         ],
  625.         result: { img: sprite[SPRITE.INV_SPEAR][1], amount: 1 }
  626.       },
  627.       {
  628.         ingredients: [
  629.           { img: sprite[SPRITE.INV_WORK][1], amount: 1 },
  630.           { img: sprite[SPRITE.INV_SPEAR][1], amount: 1 },
  631.           { img: sprite[SPRITE.INV_WOOD][1], amount: 120 },
  632.           { img: sprite[SPRITE.INV_STONE][1], amount: 50 },
  633.           { img: sprite[SPRITE.INV_GOLD][1], amount: 40 }
  634.         ],
  635.         result: { img: sprite[SPRITE.INV_GOLD_SPEAR][1], amount: 1 }
  636.       },
  637.       {
  638.         ingredients: [
  639.           { img: sprite[SPRITE.INV_WORK][1], amount: 1 },
  640.           { img: sprite[SPRITE.INV_GOLD_SPEAR][1], amount: 1 },
  641.           { img: sprite[SPRITE.INV_WOOD][1], amount: 250 },
  642.           { img: sprite[SPRITE.INV_GOLD][1], amount: 80 },
  643.           { img: sprite[SPRITE.INV_DIAMOND][1], amount: 50 }
  644.         ],
  645.         result: { img: sprite[SPRITE.INV_DIAMOND_SPEAR][1], amount: 1 }
  646.       },
  647.       {
  648.         ingredients: [
  649.           { img: sprite[SPRITE.INV_WORK][1], amount: 1 },
  650.           { img: sprite[SPRITE.INV_DIAMOND_SPEAR][1], amount: 1 },
  651.           { img: sprite[SPRITE.INV_GOLD][1], amount: 120 },
  652.           { img: sprite[SPRITE.INV_DIAMOND][1], amount: 100 },
  653.           { img: sprite[SPRITE.INV_AMETHYST][1], amount: 50 }
  654.         ],
  655.         result: { img: sprite[SPRITE.INV_AMETHYST_SPEAR][1], amount: 1 }
  656.       }
  657.     ]);
  658.    
  659.     var bknd_canv = tmp[0];
  660.     var bknd_ctx = tmp[1];
  661.     var buttons = tmp[2];
  662.    
  663.     return [ CTI(bknd_canv), buttons ];
  664.   }
  665.  
  666.   var create_recipe_page_hammers = function() {
  667.     var tmp = __create_recipe_page_leaf('HAMMERS', PAGES.CATEGORIES_1, [
  668.       {
  669.         ingredients: [
  670.           { img: sprite[SPRITE.INV_WORK][1], amount: 1 },
  671.           { img: sprite[SPRITE.INV_WOOD][1], amount: 90 },
  672.           { img: sprite[SPRITE.INV_STONE][1], amount: 50 }
  673.         ],
  674.         result: { img: sprite[SPRITE.INV_HAMMER][1], amount: 1 }
  675.       },
  676.       {
  677.         ingredients: [
  678.           { img: sprite[SPRITE.INV_WORK][1], amount: 1 },
  679.           { img: sprite[SPRITE.INV_HAMMER][1], amount: 1 },
  680.           { img: sprite[SPRITE.INV_WOOD][1], amount: 160 },
  681.           { img: sprite[SPRITE.INV_STONE][1], amount: 120 },
  682.           { img: sprite[SPRITE.INV_GOLD][1], amount: 80 }
  683.         ],
  684.         result: { img: sprite[SPRITE.INV_HAMMER_GOLD][1], amount: 1 }
  685.       },
  686.       {
  687.         ingredients: [
  688.           { img: sprite[SPRITE.INV_WORK][1], amount: 1 },
  689.           { img: sprite[SPRITE.INV_HAMMER_GOLD][1], amount: 1 },
  690.           { img: sprite[SPRITE.INV_STONE][1], amount: 200 },
  691.           { img: sprite[SPRITE.INV_GOLD][1], amount: 150 },
  692.           { img: sprite[SPRITE.INV_DIAMOND][1], amount: 80 }
  693.         ],
  694.         result: { img: sprite[SPRITE.INV_HAMMER_DIAMOND][1], amount: 1 }
  695.       },
  696.       {
  697.         ingredients: [
  698.           { img: sprite[SPRITE.INV_WORK][1], amount: 1 },
  699.           { img: sprite[SPRITE.INV_HAMMER_DIAMOND][1], amount: 1 },
  700.           { img: sprite[SPRITE.INV_GOLD][1], amount: 250 },
  701.           { img: sprite[SPRITE.INV_DIAMOND][1], amount: 160 },
  702.           { img: sprite[SPRITE.INV_AMETHYST][1], amount: 60 }
  703.         ],
  704.         result: { img: sprite[SPRITE.INV_HAMMER_AMETHYST][1], amount: 1 }
  705.       }
  706.     ]);
  707.    
  708.     var bknd_canv = tmp[0];
  709.     var bknd_ctx = tmp[1];
  710.     var buttons = tmp[2];
  711.    
  712.     return [ CTI(bknd_canv), buttons ];
  713.   }
  714.  
  715.   var create_recipe_page_placeables = function() {
  716.     var tmp = __create_recipe_page_leaf('PLACEABLES', PAGES.CATEGORIES_1, [
  717.       {
  718.         ingredients: [
  719.           { img: sprite[SPRITE.INV_WOOD][1], amount: 30 },
  720.           { img: sprite[SPRITE.INV_STONE][1], amount: 5 }
  721.         ],
  722.         result: { img: sprite[SPRITE.INV_FIRE][1], amount: 1 }
  723.       },
  724.       {
  725.         ingredients: [
  726.           { img: sprite[SPRITE.INV_FIRE][1], amount: 1 },
  727.           { img: sprite[SPRITE.INV_WOOD][1], amount: 40 },
  728.           { img: sprite[SPRITE.INV_STONE][1], amount: 10 },
  729.         ],
  730.         result: { img: sprite[SPRITE.INV_BIG_FIRE][1], amount: 1 }
  731.       },
  732.       {
  733.         ingredients: [
  734.           { img: sprite[SPRITE.INV_WOOD][1], amount: 40 },
  735.           { img: sprite[SPRITE.INV_STONE][1], amount: 20 },
  736.         ],
  737.         result: { img: sprite[SPRITE.INV_WORK][1], amount: 1 }
  738.       },
  739.       {
  740.         ingredients: [
  741.           { img: sprite[SPRITE.INV_WORK][1], amount: 1 },
  742.           { img: sprite[SPRITE.INV_WOOD][1], amount: 60 },
  743.           { img: sprite[SPRITE.INV_STONE][1], amount: 20 },
  744.           { img: sprite[SPRITE.INV_GOLD][1], amount: 10 },
  745.         ],
  746.         result: { img: sprite[SPRITE.INV_CHEST][1], amount: 1 }
  747.       },
  748.       {
  749.         ingredients: [
  750.           { img: sprite[SPRITE.INV_WORK][1], amount: 1 },
  751.           { img: sprite[SPRITE.INV_WOOD][1], amount: 150 },
  752.           { img: sprite[SPRITE.INV_STONE][1], amount: 100 },
  753.           { img: sprite[SPRITE.INV_GOLD][1], amount: 50 },
  754.         ],
  755.         result: { img: sprite[SPRITE.INV_FURNACE][1], amount: 1 }
  756.       },
  757.       {
  758.         ingredients: [
  759.           { img: sprite[SPRITE.INV_WORK][1], amount: 1 },
  760.           { img: sprite[SPRITE.INV_STONE][1], amount: 50 },
  761.           { img: sprite[SPRITE.INV_DIAMOND][1], amount: 40 },
  762.         ],
  763.         result: { img: sprite[SPRITE.INV_RESURRECTION][1], amount: 1 }
  764.       },
  765.       {
  766.         ingredients: [
  767.           { img: sprite[SPRITE.INV_WOOD][1], amount: 200 },
  768.         ],
  769.         result: { img: sprite[SPRITE.INV_TOTEM][1], amount: 1 }
  770.       }
  771.     ]);
  772.    
  773.     var bknd_canv = tmp[0];
  774.     var bknd_ctx = tmp[1];
  775.     var buttons = tmp[2];
  776.    
  777.     return [ CTI(bknd_canv), buttons ];
  778.   }
  779.  
  780.   var create_recipe_page_walls = function() {
  781.     var tmp = __create_recipe_page_leaf('WALLS', PAGES.CATEGORIES_1, [
  782.       {
  783.         ingredients: [
  784.           { img: sprite[SPRITE.INV_WORK][1], amount: 1 },
  785.           { img: sprite[SPRITE.INV_WOOD][1], amount: 20 },
  786.         ],
  787.         result: { img: sprite[SPRITE.INV_WALL][1], amount: 1 }
  788.       },
  789.       {
  790.         ingredients: [
  791.           { img: sprite[SPRITE.INV_WORK][1], amount: 1 },
  792.           { img: sprite[SPRITE.INV_WALL][1], amount: 1 },
  793.           { img: sprite[SPRITE.INV_STONE][1], amount: 20 },
  794.         ],
  795.         result: { img: sprite[SPRITE.INV_STONE_WALL][1], amount: 1 }
  796.       },
  797.       {
  798.         ingredients: [
  799.           { img: sprite[SPRITE.INV_WORK][1], amount: 1 },
  800.           { img: sprite[SPRITE.INV_STONE_WALL][1], amount: 1 },
  801.           { img: sprite[SPRITE.INV_GOLD][1], amount: 20 },
  802.         ],
  803.         result: { img: sprite[SPRITE.INV_GOLD_WALL][1], amount: 1 }
  804.       },
  805.       {
  806.         ingredients: [
  807.           { img: sprite[SPRITE.INV_WORK][1], amount: 1 },
  808.           { img: sprite[SPRITE.INV_GOLD_WALL][1], amount: 1 },
  809.           { img: sprite[SPRITE.INV_DIAMOND][1], amount: 20 },
  810.         ],
  811.         result: { img: sprite[SPRITE.INV_DIAMOND_WALL][1], amount: 1 }
  812.       },
  813.       {
  814.         ingredients: [
  815.           { img: sprite[SPRITE.INV_WORK][1], amount: 1 },
  816.           { img: sprite[SPRITE.INV_DIAMOND_WALL][1], amount: 1 },
  817.           { img: sprite[SPRITE.INV_AMETHYST][1], amount: 20 },
  818.         ],
  819.         result: { img: sprite[SPRITE.INV_AMETHYST_WALL][1], amount: 1 }
  820.       },
  821.     ]);
  822.    
  823.     var bknd_canv = tmp[0];
  824.     var bknd_ctx = tmp[1];
  825.     var buttons = tmp[2];
  826.    
  827.     return [ CTI(bknd_canv), buttons ];
  828.   }
  829.  
  830.   var create_recipe_page_spikes = function() {
  831.     var tmp = __create_recipe_page_leaf('SPIKES', PAGES.CATEGORIES_1, [
  832.       {
  833.         ingredients: [
  834.           { img: sprite[SPRITE.INV_WORK][1], amount: 1 },
  835.           { img: sprite[SPRITE.INV_WALL][1], amount: 1 },
  836.           { img: sprite[SPRITE.INV_WOOD][1], amount: 20 },
  837.           { img: sprite[SPRITE.INV_STONE][1], amount: 15 }
  838.         ],
  839.         result: { img: sprite[SPRITE.INV_SPIKE][1], amount: 1 }
  840.       },
  841.       {
  842.         ingredients: [
  843.           { img: sprite[SPRITE.INV_WORK][1], amount: 1 },
  844.           { img: sprite[SPRITE.INV_STONE_WALL][1], amount: 1 },
  845.           { img: sprite[SPRITE.INV_STONE][1], amount: 35 }
  846.         ],
  847.         result: { img: sprite[SPRITE.INV_STONE_SPIKE][1], amount: 1 }
  848.       },
  849.       {
  850.         ingredients: [
  851.           { img: sprite[SPRITE.INV_WORK][1], amount: 1 },
  852.           { img: sprite[SPRITE.INV_GOLD_WALL][1], amount: 1 },
  853.           { img: sprite[SPRITE.INV_STONE][1], amount: 15 },
  854.           { img: sprite[SPRITE.INV_GOLD][1], amount: 20 }
  855.         ],
  856.         result: { img: sprite[SPRITE.INV_GOLD_SPIKE][1], amount: 1 }
  857.       },
  858.       {
  859.         ingredients: [
  860.           { img: sprite[SPRITE.INV_WORK][1], amount: 1 },
  861.           { img: sprite[SPRITE.INV_DIAMOND_WALL][1], amount: 1 },
  862.           { img: sprite[SPRITE.INV_STONE][1], amount: 15 },
  863.           { img: sprite[SPRITE.INV_DIAMOND][1], amount: 20 }
  864.         ],
  865.         result: { img: sprite[SPRITE.INV_DIAMOND_SPIKE][1], amount: 1 }
  866.       },
  867.       {
  868.         ingredients: [
  869.           { img: sprite[SPRITE.INV_WORK][1], amount: 1 },
  870.           { img: sprite[SPRITE.INV_AMETHYST_WALL][1], amount: 1 },
  871.           { img: sprite[SPRITE.INV_STONE][1], amount: 15 },
  872.           { img: sprite[SPRITE.INV_AMETHYST][1], amount: 20 }
  873.         ],
  874.         result: { img: sprite[SPRITE.INV_AMETHYST_SPIKE][1], amount: 1 }
  875.       },
  876.     ]);
  877.    
  878.     var bknd_canv = tmp[0];
  879.     var bknd_ctx = tmp[1];
  880.     var buttons = tmp[2];
  881.    
  882.     return [ CTI(bknd_canv), buttons ];
  883.   }
  884.  
  885.  
  886.   var create_recipe_page_doors = function() {
  887.     var tmp = __create_recipe_page_leaf('DOORS', PAGES.CATEGORIES_1, [
  888.       {
  889.         ingredients: [
  890.           { img: sprite[SPRITE.INV_WORK][1], amount: 1 },
  891.           { img: sprite[SPRITE.INV_WOOD][1], amount: 60 },
  892.         ],
  893.         result: { img: sprite[SPRITE.INV_DOOR_WOOD_CLOSE][1], amount: 1 }
  894.       },
  895.       {
  896.         ingredients: [
  897.           { img: sprite[SPRITE.INV_WORK][1], amount: 1 },
  898.           { img: sprite[SPRITE.INV_DOOR_WOOD_CLOSE][1], amount: 1 },
  899.           { img: sprite[SPRITE.INV_STONE][1], amount: 60 }
  900.         ],
  901.         result: { img: sprite[SPRITE.INV_DOOR_STONE_CLOSE][1], amount: 1 }
  902.       },
  903.       {
  904.         ingredients: [
  905.           { img: sprite[SPRITE.INV_WORK][1], amount: 1 },
  906.           { img: sprite[SPRITE.INV_DOOR_STONE_CLOSE][1], amount: 1 },
  907.           { img: sprite[SPRITE.INV_GOLD][1], amount: 60 }
  908.         ],
  909.         result: { img: sprite[SPRITE.INV_DOOR_GOLD_CLOSE][1], amount: 1 }
  910.       },
  911.       {
  912.         ingredients: [
  913.           { img: sprite[SPRITE.INV_WORK][1], amount: 1 },
  914.           { img: sprite[SPRITE.INV_DOOR_GOLD_CLOSE][1], amount: 1 },
  915.           { img: sprite[SPRITE.INV_DIAMOND][1], amount: 30 }
  916.         ],
  917.         result: { img: sprite[SPRITE.INV_DOOR_DIAMOND_CLOSE][1], amount: 1 }
  918.       },
  919.       {
  920.         ingredients: [
  921.           { img: sprite[SPRITE.INV_WORK][1], amount: 1 },
  922.           { img: sprite[SPRITE.INV_DOOR_DIAMOND_CLOSE][1], amount: 1 },
  923.           { img: sprite[SPRITE.INV_AMETHYST][1], amount: 30 }
  924.         ],
  925.         result: { img: sprite[SPRITE.INV_DOOR_AMETHYST_CLOSE][1], amount: 1 }
  926.       }
  927.     ]);
  928.    
  929.     var bknd_canv = tmp[0];
  930.     var bknd_ctx = tmp[1];
  931.     var buttons = tmp[2];
  932.    
  933.     return [ CTI(bknd_canv), buttons ];
  934.   }
  935.  
  936.   var create_recipe_page_food_healing = function() {
  937.     var tmp = __create_recipe_page_leaf('FOOD / HEALING', PAGES.CATEGORIES_1, [
  938.       {
  939.         ingredients: [
  940.           { img: sprite[SPRITE.INV_FIRE][1], amount: 1 },
  941.           { img: sprite[SPRITE.INV_MEAT][1], amount: 1 },
  942.         ],
  943.         result: { img: sprite[SPRITE.INV_COOKED_MEAT][1], amount: 1 }
  944.       },
  945.       {
  946.         ingredients: [
  947.           { img: sprite[SPRITE.INV_FIRE][1], amount: 1 },
  948.           { img: sprite[SPRITE.INV_PLANT][1], amount: 3 },
  949.           { img: sprite[SPRITE.INV_WOOD][1], amount: 20 }
  950.         ],
  951.         result: { img: sprite[SPRITE.INV_SEED][1], amount: 1 }
  952.       },
  953.       {
  954.         ingredients: [
  955.           { img: sprite[SPRITE.INV_WORK][1], amount: 1 },
  956.           { img: sprite[SPRITE.INV_CORD][1], amount: 3 },
  957.         ],
  958.         result: { img: sprite[SPRITE.INV_BANDAGE][1], amount: 1 }
  959.       }
  960.     ]);
  961.    
  962.     var bknd_canv = tmp[0];
  963.     var bknd_ctx = tmp[1];
  964.     var buttons = tmp[2];
  965.    
  966.     return [ CTI(bknd_canv), buttons ];
  967.   }
  968.  
  969.   var create_recipe_page_helmets = function() {
  970.     var tmp = __create_recipe_page_leaf('HELMETS', PAGES.CATEGORIES_1, [
  971.       {
  972.         ingredients: [
  973.           { img: sprite[SPRITE.INV_WORK][1], amount: 1 },
  974.           { img: sprite[SPRITE.INV_WOOD][1], amount: 100 },
  975.           { img: sprite[SPRITE.INV_STONE][1], amount: 150 },
  976.         ],
  977.         result: { img: sprite[SPRITE.INV_STONE_HELMET][1], amount: 1 }
  978.       },
  979.       {
  980.         ingredients: [
  981.           { img: sprite[SPRITE.INV_WORK][1], amount: 1 },
  982.           { img: sprite[SPRITE.INV_STONE_HELMET][1], amount: 1 },
  983.           { img: sprite[SPRITE.INV_WOOD][1], amount: 120 },
  984.           { img: sprite[SPRITE.INV_STONE][1], amount: 180 },
  985.           { img: sprite[SPRITE.INV_GOLD][1], amount: 100 },
  986.         ],
  987.         result: { img: sprite[SPRITE.INV_GOLD_HELMET][1], amount: 1 }
  988.       },
  989.       {
  990.         ingredients: [
  991.           { img: sprite[SPRITE.INV_WORK][1], amount: 1 },
  992.           { img: sprite[SPRITE.INV_GOLD_HELMET][1], amount: 1 },
  993.           { img: sprite[SPRITE.INV_STONE][1], amount: 200 },
  994.           { img: sprite[SPRITE.INV_GOLD][1], amount: 100 },
  995.           { img: sprite[SPRITE.INV_DIAMOND][1], amount: 160 },
  996.         ],
  997.         result: { img: sprite[SPRITE.INV_DIAMOND_HELMET][1], amount: 1 }
  998.       },
  999.       {
  1000.         ingredients: [
  1001.           { img: sprite[SPRITE.INV_WORK][1], amount: 1 },
  1002.           { img: sprite[SPRITE.INV_DIAMOND_HELMET][1], amount: 1 },
  1003.           { img: sprite[SPRITE.INV_GOLD][1], amount: 200 },
  1004.           { img: sprite[SPRITE.INV_DIAMOND][1], amount: 160 },
  1005.           { img: sprite[SPRITE.INV_AMETHYST][1], amount: 100 },
  1006.         ],
  1007.         result: { img: sprite[SPRITE.INV_AMETHYST_HELMET][0], amount: 1 }
  1008.       }
  1009.     ]);
  1010.    
  1011.     var bknd_canv = tmp[0];
  1012.     var bknd_ctx = tmp[1];
  1013.     var buttons = tmp[2];
  1014.    
  1015.     return [ CTI(bknd_canv), buttons ];
  1016.   }
  1017.  
  1018.   var create_recipe_page_wearables = function() {
  1019.     var tmp = __create_recipe_page_leaf('WEARABLES', PAGES.CATEGORIES_1, [
  1020.       {
  1021.         ingredients: [
  1022.           { img: sprite[SPRITE.INV_WORK][1], amount: 1 },
  1023.           { img: sprite[SPRITE.INV_FUR][1], amount: 8 },
  1024.           { img: sprite[SPRITE.INV_CORD][1], amount: 4 }
  1025.         ],
  1026.         result: { img: sprite[SPRITE.INV_EARMUFFS][1], amount: 1 }
  1027.       },
  1028.       {
  1029.         ingredients: [
  1030.           { img: sprite[SPRITE.INV_WORK][1], amount: 1 },
  1031.           { img: sprite[SPRITE.INV_EARMUFFS][1], amount: 1 },
  1032.           { img: sprite[SPRITE.INV_FUR][1], amount: 5 },
  1033.           { img: sprite[SPRITE.INV_FUR_WOLF][1], amount: 10 },
  1034.           { img: sprite[SPRITE.INV_CORD][1], amount: 6 }
  1035.         ],
  1036.         result: { img: sprite[SPRITE.INV_COAT][1], amount: 1 }
  1037.       },
  1038.       {
  1039.         ingredients: [
  1040.           { img: sprite[SPRITE.INV_WORK][1], amount: 1 },
  1041.           { img: sprite[SPRITE.INV_COAT][1], amount: 1 },
  1042.           { img: sprite[SPRITE.INV_FUR_WINTER][1], amount: 20 },
  1043.           { img: sprite[SPRITE.INV_BLUE_CORD][1], amount: 10 }
  1044.         ],
  1045.         result: { img: sprite[SPRITE.INV_CAP_SCARF][1], amount: 1 }
  1046.       },
  1047.       {
  1048.         ingredients: [
  1049.           { img: sprite[SPRITE.INV_WORK][1], amount: 1 },
  1050.           { img: sprite[SPRITE.INV_PAPER][1], amount: 5 },
  1051.           { img: sprite[SPRITE.INV_FUR][1], amount: 5, },
  1052.           { img: sprite[SPRITE.INV_CORD][1], amount: 4, }
  1053.         ],
  1054.         result: { img: sprite[SPRITE.INV_EXPLORER_HAT][1], amount: 1 }
  1055.       },
  1056.       {
  1057.         ingredients: [
  1058.           { img: sprite[SPRITE.INV_WORK][1], amount: 1 },
  1059.           { img: sprite[SPRITE.INV_FUR_WOLF][1], amount: 5 },
  1060.           { img: sprite[SPRITE.INV_CORD][1], amount: 10 }
  1061.         ],
  1062.         result: { img: sprite[SPRITE.INV_BAG][1], amount: 1 }
  1063.       },
  1064.       {
  1065.         ingredients: [
  1066.           { img: sprite[SPRITE.INV_WORK][1], amount: 1 },
  1067.           { img: sprite[SPRITE.INV_FUR_WOLF][1], amount: 5 },
  1068.           { img: sprite[SPRITE.INV_PAPER][1], amount: 5 },
  1069.           { img: sprite[SPRITE.INV_CORD][1], amount: 5 }
  1070.         ],
  1071.         result: { img: sprite[SPRITE.INV_BOOK][1], amount: 1 }
  1072.       },
  1073.     ]);
  1074.    
  1075.     var bknd_canv = tmp[0];
  1076.     var bknd_ctx = tmp[1];
  1077.     var buttons = tmp[2];
  1078.    
  1079.     return [ CTI(bknd_canv), buttons ];
  1080.   }
  1081.  
  1082.   var create_recipe_page_misc = function() {
  1083.     var tmp = __create_recipe_page_leaf('MISCELLANEOUS', PAGES.CATEGORIES_1, [
  1084.       {
  1085.         ingredients: [
  1086.           { img: sprite[SPRITE.INV_WORK][1], amount: 1 },
  1087.           { img: sprite[SPRITE.INV_GOLD][1], amount: 10 }
  1088.         ],
  1089.         result: { img: sprite[SPRITE.INV_LOCK][1], amount: 1 }
  1090.       },
  1091.       {
  1092.         ingredients: [
  1093.           { img: sprite[SPRITE.INV_WORK][1], amount: 1 },
  1094.           { img: sprite[SPRITE.INV_GOLD][1], amount: 40 }
  1095.         ],
  1096.         result: { img: sprite[SPRITE.INV_LOCKPICK][1], amount: 1 }
  1097.       }
  1098.     ]);
  1099.    
  1100.     var bknd_canv = tmp[0];
  1101.     var bknd_ctx = tmp[1];
  1102.     var buttons = tmp[2];
  1103.    
  1104.     return [ CTI(bknd_canv), buttons ];
  1105.   }
  1106.  
  1107.   var create_recipe_page_crafting_items = function() {
  1108.     var tmp = __create_recipe_page_leaf('CRAFTING ITEMS', PAGES.CATEGORIES_1, [
  1109.       {
  1110.         ingredients: [
  1111.           { img: sprite[SPRITE.INV_FIRE][1], amount: 1 },
  1112.           { img: sprite[SPRITE.INV_WOOD][1], amount: 30 }
  1113.         ],
  1114.         result: { img: sprite[SPRITE.INV_PAPER][1], amount: 1 }
  1115.       },
  1116.       {
  1117.         ingredients: [
  1118.           { img: sprite[SPRITE.INV_WORK][1], amount: 1 },
  1119.           { img: sprite[SPRITE.INV_DIAMOND][1], amount: 1 },
  1120.           { img: sprite[SPRITE.INV_CORD][1], amount: 1 }
  1121.         ],
  1122.         result: { img: sprite[SPRITE.INV_BLUE_CORD][1], amount: 1 }
  1123.       }
  1124.     ]);
  1125.    
  1126.     var bknd_canv = tmp[0];
  1127.     var bknd_ctx = tmp[1];
  1128.     var buttons = tmp[2];
  1129.    
  1130.     return [ CTI(bknd_canv), buttons ];
  1131.   }
  1132.  
  1133.  
  1134.  
  1135.   SPRITE["AUTO_BOOK"] = find_unique_index();
  1136.   sprite[SPRITE.AUTO_BOOK] = create_text(1, "Auto-Book", 25, "#FFF", void 0, void 0, "#000", 5, 140);
  1137.  
  1138.   SPRITE["EXT_HELP"] = find_unique_index();
  1139.   sprite[SPRITE.EXT_HELP] = CTI(create_help());
  1140.  
  1141.   SPRITE["ARROW_NEXT"] = find_unique_index();
  1142.   sprite[SPRITE.ARROW_NEXT] = [ CTI(create_arrow_next('#c3c3c3')), CTI(create_arrow_next('#d3d3d3')), CTI(create_arrow_next('#FFF')) ];
  1143.  
  1144.   SPRITE["ARROW_BACK"] = find_unique_index();
  1145.   sprite[SPRITE.ARROW_BACK] = [ CTI(create_arrow_back('#c3c3c3')), CTI(create_arrow_back('#d3d3d3')), CTI(create_arrow_back('#FFF')) ];
  1146.  
  1147.   SPRITE["RECIPE_LIST"] = find_unique_index();
  1148.   sprite[SPRITE.RECIPE_LIST] = [];
  1149.   sprite[SPRITE.RECIPE_LIST][PAGES.CATEGORIES_1] = create_recipe_page_categories_1();
  1150.   sprite[SPRITE.RECIPE_LIST][PAGES.PICKAXES] = create_recipe_page_pickaxes();
  1151.   sprite[SPRITE.RECIPE_LIST][PAGES.SWORDS] = create_recipe_page_swords();
  1152.   sprite[SPRITE.RECIPE_LIST][PAGES.SPEARS] = create_recipe_page_spears();
  1153.   sprite[SPRITE.RECIPE_LIST][PAGES.HAMMERS] = create_recipe_page_hammers();
  1154.   sprite[SPRITE.RECIPE_LIST][PAGES.PLACEABLES] = create_recipe_page_placeables();
  1155.   sprite[SPRITE.RECIPE_LIST][PAGES.WALLS] = create_recipe_page_walls();
  1156.   sprite[SPRITE.RECIPE_LIST][PAGES.SPIKES] = create_recipe_page_spikes();
  1157.   sprite[SPRITE.RECIPE_LIST][PAGES.DOORS] = create_recipe_page_doors();
  1158.   sprite[SPRITE.RECIPE_LIST][PAGES.FOOD_HEALING] = create_recipe_page_food_healing();
  1159.   sprite[SPRITE.RECIPE_LIST][PAGES.HELMETS] = create_recipe_page_helmets();
  1160.   sprite[SPRITE.RECIPE_LIST][PAGES.WEARABLES] = create_recipe_page_wearables();
  1161.   sprite[SPRITE.RECIPE_LIST][PAGES.MISCELLANEOUS] = create_recipe_page_misc();
  1162.   sprite[SPRITE.RECIPE_LIST][PAGES.CRAFTING_ITEMS] = create_recipe_page_crafting_items();
  1163.  
  1164.   user.ext_help = {
  1165.     enabled: false,
  1166.     translate: {
  1167.       x: 0,
  1168.       y: 0
  1169.     }
  1170.   }
  1171.  
  1172.   user.ext_recipes = {
  1173.     enabled: false,
  1174.     current_page: sprite[SPRITE.RECIPE_LIST][PAGES.CATEGORIES_1],
  1175.     hovered_button: false,
  1176.     mouse_is_down: false,
  1177.     translate: {
  1178.       x: 0,
  1179.       y: 0
  1180.     },
  1181.     on_disable: function() {
  1182.       this.hovered_button = false;
  1183.       this.current_page = sprite[SPRITE.RECIPE_LIST][PAGES.CATEGORIES_1];
  1184.     },
  1185.     trigger_mouseup: function(evt) {
  1186.       this.mouse_is_down = false;
  1187.       if(this.enabled && this.hovered_button) {
  1188.         this.current_page = sprite[SPRITE.RECIPE_LIST][this.hovered_button.page_num];
  1189.         this.translate.x = can.width / 2 - this.current_page[0].width / 2;
  1190.         this.translate.y = can.height / 2 - this.current_page[0].height / 2;
  1191.       }
  1192.     },
  1193.     trigger_mousedown: function(evt) {
  1194.       this.mouse_is_down = true;
  1195.     },
  1196.     trigger_mousemove: function(evt) {
  1197.       if(this.enabled) {
  1198.         this.hovered_button = false;
  1199.         var buttons = this.current_page[1];
  1200.         var mousepos = get_mouse_pos(game.can, evt);
  1201.         var adjX = mousepos.x - this.translate.x;
  1202.         var adjY = mousepos.y - this.translate.y;
  1203.         for(var i = 0; i < buttons.length; i++) {
  1204.           var but = buttons[i];
  1205.           if(but.contains(adjX, adjY)) {
  1206.             this.hovered_button = but;
  1207.             return;
  1208.           }
  1209.         }
  1210.       }
  1211.     },
  1212.     draw_buttons: function() {
  1213.       if(this.enabled) {
  1214.         var buttons = this.current_page[1];
  1215.         for(var i = 0; i < buttons.length; i++) {
  1216.           var img = buttons[i].normal;
  1217.           if(buttons[i] == this.hovered_button) {
  1218.             if(this.mouse_is_down) {
  1219.               img = buttons[i].pushed;
  1220.             }else {
  1221.               img = buttons[i].hovered;
  1222.             }
  1223.           }
  1224.           ctx.drawImage(img, this.translate.x + buttons[i].translate.x, this.translate.y + buttons[i].translate.y);
  1225.         }
  1226.       }
  1227.     },
  1228.     register_listeners: function() {
  1229.       var me = this;
  1230.       window.addEventListener("mouseup", function() { me.trigger_mouseup.apply(me, arguments) }, false);
  1231.       window.addEventListener("mousemove", function() { me.trigger_mousemove.apply(me, arguments) }, false);
  1232.       window.addEventListener("mousedown", function() { me.trigger_mousedown.apply(me, arguments) }, false);
  1233.     }
  1234.   };
  1235.  
  1236.   user.auto_book = {
  1237.     enabled: false,
  1238.     translate: {
  1239.       x: 0,
  1240.       y: 0
  1241.     },
  1242.     equip_book: function() {
  1243.       if(this.enabled) {
  1244.         if(user.inv.n[INV.BOOK]) {
  1245.           var thePlayer = world[WORLD_FAST_UNITS_ARR_NAME][user[USER_UID_VAR_NAME]];
  1246.           if(thePlayer.right != INV.BOOK) {
  1247.             client[CLIENT_SELECT_INV_FN_NAME](INV.BOOK, user.inv.find_item(INV.BOOK));
  1248.           }
  1249.         }
  1250.       }
  1251.     }
  1252.   }
  1253.  
  1254.   var oldGameUpdate = game.update;
  1255.   game.update = function() {
  1256.     oldGameUpdate.apply(this);
  1257.     user.auto_book.translate.x = game.leaderboard.translate.x - sprite[SPRITE.AUTO_BOOK].width - 10;
  1258.     user.auto_book.translate.y = user.show_spectators.translate.y + sprite[SPRITE.SHOW_SPECTATORS].height + 5;
  1259.     user.ext_fast_delete.translate.x = game.leaderboard.translate.x - sprite[SPRITE.EXT_FAST_DELETE].width - 10;
  1260.     user.ext_fast_delete.translate.y = user.auto_book.translate.y + sprite[SPRITE.AUTO_BOOK].height + 5;
  1261.     user.ext_help.translate.x = can.width / 2 - sprite[SPRITE.EXT_HELP].width / 2;
  1262.     user.ext_help.translate.y = can.height / 2 - sprite[SPRITE.EXT_HELP].height / 2;
  1263.     user.ext_recipes.translate.x = can.width / 2 - user.ext_recipes.current_page[0].width / 2;
  1264.     user.ext_recipes.translate.y = can.height / 2 - user.ext_recipes.current_page[0].height / 2;
  1265.    
  1266.     user.ext_clock.translate.x = can.width - user.ext_clock.radius * 2 - 10;
  1267.     user.ext_clock.translate.y = game.leaderboard.translate.y + game.leaderboard.img.height + 10;
  1268.   };
  1269.  
  1270.   function draw_ext_help() {
  1271.     if(user.ext_help.enabled) {
  1272.       ctx.drawImage(sprite[SPRITE.EXT_HELP], user.ext_help.translate.x, user.ext_help.translate.y);
  1273.     }
  1274.   }
  1275.  
  1276.   function draw_ext_auto_book() {
  1277.     if(user.auto_book.enabled) {
  1278.       ctx.drawImage(sprite[SPRITE.AUTO_BOOK], user.auto_book.translate.x, user.auto_book.translate.y);
  1279.     }
  1280.   }
  1281.  
  1282.   function draw_ext_recipes() {
  1283.     if(user.ext_recipes.enabled) {
  1284.       ctx.drawImage(user.ext_recipes.current_page[0], user.ext_recipes.translate.x, user.ext_recipes.translate.y);
  1285.       user.ext_recipes.draw_buttons();
  1286.     }
  1287.   }
  1288.  
  1289.   var oldGameDrawUI = game[GAME_DRAW_UI_FN_NAME];
  1290.   game[GAME_DRAW_UI_FN_NAME] = function() {
  1291.     oldGameDrawUI.apply(this, arguments);
  1292.     draw_ext_auto_book();
  1293.     draw_ext_fast_delete();
  1294.     draw_ext_help();
  1295.     draw_ext_recipes();
  1296.     draw_ext_clock();
  1297.   };
  1298.  
  1299.   var my_trigger_key_up = function(c) {
  1300.     var keycode = c.keyCode;
  1301.     if(user.keycodes_to_mapped_keycodes[keycode])
  1302.       keycode = user.keycodes_to_mapped_keycodes[keycode];
  1303.    
  1304.     if (!user.chat.open)  {
  1305.       if(keycode == 84) {
  1306.         user.auto_book.enabled = !user.auto_book.enabled;
  1307.       }else if(keycode == 72) {
  1308.         user.ext_help.enabled = !user.ext_help.enabled;  
  1309.         if(user.ext_help.enabled) {
  1310.           user.ext_recipes.enabled = false;
  1311.         }
  1312.       }else if(keycode == 85) {
  1313.         user.ext_recipes.enabled = !user.ext_recipes.enabled;
  1314.         if(user.ext_recipes.enabled) {
  1315.           user.ext_help.enabled = false;
  1316.         }else {
  1317.           user.ext_recipes.on_disable();
  1318.         }
  1319.       }else if(keycode == 67) {
  1320.         user.ext_clock.enabled = !user.ext_clock.enabled;
  1321.       }
  1322.     }
  1323.   };
  1324.  
  1325.   user.craft.do_craft = function(recipeID) {
  1326.     var recipe = RECIPES[recipeID];
  1327.     this.id = recipeID;
  1328.     this.crafting = true;
  1329.     if((user.auto_book.enabled && user.inv.n[INV.BOOK]) || world[WORLD_FAST_UNITS_ARR_NAME][user[USER_UID_VAR_NAME]].right == INV.BOOK) {
  1330.       this.timeout.max_speed = recipe.time * 3;
  1331.     }else {
  1332.       this.timeout.max_speed = recipe.time;
  1333.     }
  1334.     this.id2 = recipe.id2;
  1335.     for (var counter = 0; counter < recipe.r.length; counter++) {
  1336.       var resource = recipe.r[counter];
  1337.       user.inv.decrease(resource[0], resource[1], user.inv.find_item(resource[0]));
  1338.     }
  1339.     game[UPDATE_INV_BUTTONS_FN_NAME]()
  1340.   };
  1341.  
  1342.   window.addEventListener("keyup", my_trigger_key_up, false);
  1343.   user.ext_recipes.register_listeners();
  1344.  
  1345.   var oldSelectCraft = client[SELECT_CRAFT_FN_NAME];
  1346.   client[SELECT_CRAFT_FN_NAME] = function()
  1347.   {
  1348.     if(user.weapon.timeout.v != 0 && user.inv.n[INV.BOOK]) {
  1349.       var alertMsg = "You can't equip your book right now."
  1350.       user.alert.text ? user.alert.list.push(alertMsg) : user.alert.text = alertMsg;
  1351.       return;
  1352.     }
  1353.    
  1354.     user.auto_book.equip_book();
  1355.     oldSelectCraft.apply(this, arguments);
  1356.   };
  1357.  
  1358.   // rearrange inventory
  1359.   user.inventory_index_to_mapped_index = []
  1360.   for(var index = 0; index < 13; index++) {
  1361.     user.inventory_index_to_mapped_index[index] = index;
  1362.   }
  1363.  
  1364.   user.keycodes_to_mapped_keycodes = {} // contains things like: { 68: 96 }
  1365.   SPRITE["SLOT_NUMBERS_MAPPED"] = find_unique_index();
  1366.   sprite[SPRITE.SLOT_NUMBERS_MAPPED] = {};
  1367.   sprite[SPRITE.SLOT_NUMBERS_MAPPED][9] = create_text(1, '0', 12, "#FFF");
  1368.   sprite[SPRITE.SLOT_NUMBERS_MAPPED][10] = create_text(1, 'P', 12, "#FFF");
  1369.  
  1370.   user.load_keycode_mapping = function() {
  1371.     var keycode_mapping_cookie = Cookies.get("starveio_ext_keymap");
  1372.     if(keycode_mapping_cookie) {
  1373.       user.keycodes_to_mapped_keycodes = {};
  1374.       var tmp = keycode_mapping_cookie.split(",");
  1375.       for(var i = 0; i < tmp.length; i++) {
  1376.         var tmp_map = tmp[i].split("-");
  1377.         var mapped_from = parseInt(tmp_map[0])
  1378.         var mapped_to = parseInt(tmp_map[1]);
  1379.         user.keycodes_to_mapped_keycodes[mapped_from] = mapped_to;
  1380.        
  1381.         if(mapped_to >= '1'.charCodeAt(0) && mapped_to <= '9'.charCodeAt(0)) {
  1382.           var slot_index;
  1383.           if(mapped_to == 'P'.charCodeAt(0))
  1384.             slot_index = 10;
  1385.           else if(mapped_to == '0'.charCodeAt(0))
  1386.             slot_index = 9;
  1387.           else
  1388.             slot_index = mapped_to - '1'.charCodeAt(0);
  1389.           var mapped_from_char = String.fromCharCode(mapped_from);
  1390.           sprite[SPRITE.SLOT_NUMBERS_MAPPED][slot_index] = create_text(1, mapped_from_char, 12, "#FFF");
  1391.         }
  1392.       }
  1393.     }
  1394.   }
  1395.  
  1396.   user.save_keycode_mapping = function() {
  1397.     var res = "";
  1398.     var first = true;
  1399.     for(var key in user.keycodes_to_mapped_keycodes) {
  1400.       if(!first)
  1401.         res += ",";
  1402.       else
  1403.         first = false;
  1404.      
  1405.       var tmp = user.keycodes_to_mapped_keycodes[key];
  1406.       res += key.toString() + "-" + tmp.toString();
  1407.     }
  1408.    
  1409.     Cookies.set("starveio_ext_keymap", res);
  1410.   }
  1411.  
  1412.   user.load_keycode_mapping();
  1413.  
  1414.   function better_draw_amount(amount, loc, pushed) {
  1415.     var amount_as_img = get_amount_as_img(amount)
  1416.     var x = loc.x + 70 - amount_as_img.width - 5 * scale;
  1417.     var y = loc.y + 75 - amount_as_img.height - 5 * scale;
  1418.    
  1419.     if(pushed) {
  1420.       y += 5 * scale;
  1421.     }
  1422.    
  1423.     ctx.drawImage(amount_as_img, x, y);
  1424.   }
  1425.  
  1426.   function better_draw_slot(slot_index, loc, pushed) {
  1427.     var img;
  1428.     if(sprite[SPRITE.SLOT_NUMBERS_MAPPED][slot_index]) {
  1429.       img = sprite[SPRITE.SLOT_NUMBERS_MAPPED][slot_index];
  1430.     }else {
  1431.       img = sprite[SPRITE.SLOT_NUMBER][slot_index];
  1432.     }
  1433.    
  1434.    
  1435.     var x = loc.x + 5 * scale;
  1436.     var y = loc.y + 5 * scale;
  1437.     if(pushed) {
  1438.       y += 5 * scale;
  1439.     }
  1440.    
  1441.     ctx.drawImage(img, x, y);
  1442.   }
  1443.  
  1444.  
  1445.   user.inv.hotbar_button_locations = []
  1446.   for(var tmp_counter = 0; tmp_counter < 13; tmp_counter++) {
  1447.     user.inv.hotbar_button_locations[tmp_counter] = { x: 0, y: 0 };
  1448.   }
  1449.  
  1450.   game[UPDATE_INV_BUTTONS_FN_NAME] = function() {
  1451.     var user_inventory = user.inv;
  1452.     for(var index = 0; index < user_inventory.max; index++) {
  1453.       if(!user_inventory.hotbar_button_locations[index])
  1454.         user_inventory.hotbar_button_locations[index] = { x: 0, y: 0 }
  1455.      
  1456.       // it uses images width/height per element, which makes no sense if the elements
  1457.       // are ever not the same height and requires we already have items in our inventory.
  1458.       // we just use the constant width/height of 70x75
  1459.       user_inventory.hotbar_button_locations[index].x = (10 + 70) * index + game.gauges.img.width + 10;
  1460.       user_inventory.hotbar_button_locations[index].y = can.height - 75 - 10;
  1461.     }
  1462.    
  1463.     // now we update the can_select based on what we just determined. However the little
  1464.     // "plus" buttons are indexed by the item that they are "plusing" which means we
  1465.     // need to adjust based on our remapped items
  1466.     for(var index = 0; index < user_inventory.can_select.length; index++) {
  1467.       var true_index_of_this_index = -1; // for positioning the button
  1468.       for(var index2 = 0; index2 < user.inventory_index_to_mapped_index.length; index2++) {
  1469.         if(user.inventory_index_to_mapped_index[index2] == index) {
  1470.           true_index_of_this_index = index2;
  1471.           break;
  1472.         }
  1473.       }
  1474.      
  1475.       var cs_translate = user_inventory.can_select[index].info.translate;
  1476.       cs_translate.x = user_inventory.hotbar_button_locations[true_index_of_this_index].x;
  1477.       cs_translate.y = user_inventory.hotbar_button_locations[true_index_of_this_index].y;
  1478.      
  1479.       var pb_translate = this.plus_buttons[user_inventory.can_select[index].id].info.translate;
  1480.       var true_but_loc = user_inventory.hotbar_button_locations[true_index_of_this_index];
  1481.      
  1482.       pb_translate.x = true_but_loc.x + 18;
  1483.       pb_translate.y = true_but_loc.y - 35 - 6; // again 35 is height of plus button
  1484.     }
  1485.   }
  1486.  
  1487.   // force recalculate after building bag
  1488.   var oldClientBuildStop = client[CLIENT_BUILD_STOP_FN_NAME];
  1489.   client[CLIENT_BUILD_STOP_FN_NAME] = function(c) {
  1490.     oldClientBuildStop.apply(client, [ c ]);
  1491.    
  1492.     if(c == INV.BAG) {
  1493.       game[UPDATE_INV_BUTTONS_FN_NAME].apply(game, []);
  1494.     }
  1495.   }
  1496.  
  1497.   window[DRAW_UI_INVENTORY_FN_NAME] = function() {
  1498.     var user_inventory = user.inv;
  1499.     var user_fast_unit = world[WORLD_FAST_UNITS_ARR_NAME][user[USER_UID_VAR_NAME]];
  1500.     if(!user_fast_unit)
  1501.       return;
  1502.    
  1503.     var user_can_select = user_inventory.can_select;
  1504.    
  1505.     for(var index = 0; index < user_inventory.max; index++) {
  1506.       var item_to_draw = user_can_select[user.inventory_index_to_mapped_index[index]];
  1507.       var loc = user_inventory.hotbar_button_locations[index];
  1508.      
  1509.       if(!item_to_draw) {
  1510.         // draw the empty slot
  1511.         var empty_slot_img = sprite[SPRITE.EMPTY_SLOT][2];
  1512.         ctx.drawImage(empty_slot_img, loc.x, loc.y);
  1513.         continue;
  1514.       }
  1515.      
  1516.       var equipped_or_selected = false;
  1517.       if(user.right == item_to_draw.id || (user.clothe == item_to_draw.id && user.clothe > 0)) {
  1518.         equipped_or_selected = true;
  1519.         ctx.drawImage(item_to_draw.info.img[2], loc.x, loc.y);
  1520.       }else {
  1521.         ctx.drawImage(item_to_draw.info.img[item_to_draw.info.state], loc.x, loc.y);
  1522.       }
  1523.      
  1524.       var amount_of_item = user_inventory.n[item_to_draw.id];
  1525.       if(amount_of_item > 1) {
  1526.         better_draw_amount(amount_of_item, loc, equipped_or_selected);
  1527.       }
  1528.      
  1529.       if(amount_of_item > 0) {
  1530.         better_draw_slot(index, loc, equipped_or_selected);
  1531.       }
  1532.      
  1533.       var user_chest = user.chest;
  1534.       if(user_chest.open && (user_chest.id < 0 || user_chest.id == item_to_draw.id) && !(user_chest.lock && user_chest.pid != user.id)) {
  1535.         game.plus_buttons[item_to_draw.id].draw(ctx);
  1536.       }
  1537.      
  1538.       var user_furnace = user.furnace;
  1539.       if(user_furnace.open && item_to_draw.id == INV.WOOD) {
  1540.         game.plus_buttons[item_to_draw.id].draw(ctx);
  1541.       }
  1542.     }
  1543.   };
  1544.  
  1545.   function ext_try_command(spl_by_spaces) {
  1546.     if(spl_by_spaces[0] == "-swap") {
  1547.       if(spl_by_spaces.length != 3)
  1548.         return false;
  1549.      
  1550.       var num1 = parseInt(spl_by_spaces[1]);
  1551.       var num2 = parseInt(spl_by_spaces[2]);
  1552.       if(isNaN(num1) || isNaN(num2)) {
  1553.         return false;
  1554.       }
  1555.      
  1556.       if(num1 < 1 || num2 < 1 || num1 > user.inv.max || num2 > user.inv.max)
  1557.         return false;
  1558.      
  1559.       var num1_mapped = user.inventory_index_to_mapped_index[num1 - 1]
  1560.       var num2_mapped = user.inventory_index_to_mapped_index[num2 - 1]
  1561.      
  1562.       user.inventory_index_to_mapped_index[num1 - 1] = num2_mapped;
  1563.       user.inventory_index_to_mapped_index[num2 - 1] = num1_mapped;
  1564.       game[UPDATE_INV_BUTTONS_FN_NAME]();
  1565.       return true;
  1566.     }else if(spl_by_spaces[0] == "-remap")
  1567.     {
  1568.       if(spl_by_spaces.length != 3)
  1569.         return false;
  1570.      
  1571.       var let1 = spl_by_spaces[1].toUpperCase();
  1572.       var let2 = spl_by_spaces[2].toUpperCase();
  1573.      
  1574.       if(let1.length != 1 || let2.length != 1)
  1575.         return false;
  1576.      
  1577.       var mapped_from = let1.toUpperCase().charCodeAt(0);
  1578.       var mapped_to = let2.toUpperCase().charCodeAt(0);
  1579.      
  1580.       if((mapped_to >= '0'.charCodeAt(0) && mapped_to <= '9'.charCodeAt(0)) || mapped_to == 'P'.charCodeAt(0)) {
  1581.         var slot_index;
  1582.         if(mapped_to == 'P'.charCodeAt(0))
  1583.           slot_index = 10;
  1584.         else if(mapped_to == '0'.charCodeAt(0))
  1585.           slot_index = 9;
  1586.         else
  1587.           slot_index = mapped_to - '1'.charCodeAt(0);
  1588.        
  1589.         var mapped_from_char = String.fromCharCode(mapped_from);
  1590.         sprite[SPRITE.SLOT_NUMBERS_MAPPED][slot_index] = create_text(1, mapped_from_char, 12, "#FFF");
  1591.       }
  1592.      
  1593.       if(mapped_to == keyboard.LEFT) {
  1594.         keyboard.LEFT = mapped_from;
  1595.         return true;
  1596.       }else if(mapped_to == keyboard.RIGHT) {
  1597.         keyboard.RIGHT = mapped_from;
  1598.         return true;
  1599.       }else if(mapped_to == keyboard.TOP) {
  1600.         keyboard.TOP = mapped_from;
  1601.         return true;
  1602.       }else if(mapped_to == keyboard.BOTTOM) {
  1603.         keyboard.BOTTOM = mapped_from;
  1604.         return true;
  1605.       }
  1606.      
  1607.       user.keycodes_to_mapped_keycodes[mapped_from] = mapped_to;
  1608.       user.save_keycode_mapping();
  1609.       return true;
  1610.     }else if(spl_by_spaces[0] == "-unmapall") {
  1611.       if(spl_by_spaces.length != 1)
  1612.         return false;
  1613.      
  1614.       sprite[SPRITE.SLOT_NUMBERS_MAPPED] = {}
  1615.       user.keycodes_to_mapped_keycodes = {}
  1616.       user.save_keycode_mapping();
  1617.       return true;
  1618.     }
  1619.    
  1620.     return false;
  1621.   }
  1622.  
  1623.   window.removeEventListener("keyup", game[GAME_TRIGGER_KEYUP_FN_NAME], false)
  1624.   function new_game_trigger_keyup(c) {
  1625.     var keycode = c.keyCode;
  1626.     if(user.keycodes_to_mapped_keycodes[keycode])
  1627.       keycode = user.keycodes_to_mapped_keycodes[keycode];
  1628.    
  1629.    
  1630.     if (user.chat.open && keycode == 27) {
  1631.       user.chat.quit();
  1632.     }else if(keycode == 13) {
  1633.       var txt = user.chat.input.value;
  1634.       var spl = txt.split(" ");
  1635.       if(!ext_try_command(spl))
  1636.         user.chat.run();
  1637.       else
  1638.         user.chat.quit();
  1639.     }else if(!user.chat.open) {
  1640.       if(keycode === 82) {
  1641.         user.auto_feed.enabled = !user.auto_feed.enabled;
  1642.       }else if(80 === keycode && world.mode === WORLD.MODE_HUNGER_GAMES && !user.spectator)
  1643.       {
  1644.         user.show_spectators.enabled = !user.show_spectators.enabled;
  1645.       }else if(keycode == 'L'.charCodeAt(0)) {
  1646.         user.ext_fast_delete.enabled = !user.ext_fast_delete.enabled;
  1647.       }else
  1648.       {
  1649.         if(('0'.charCodeAt(0) <= keycode && '9'.charCodeAt(0) >= keycode) || keycode == 'P'.charCodeAt(0)) {
  1650.           if(user.craft.id < 0) {
  1651.             var slot_index;
  1652.             if(keycode == 'P'.charCodeAt(0))
  1653.               slot_index = 10;
  1654.             else if(keycode == '0'.charCodeAt(0))
  1655.               slot_index = 9;
  1656.             else
  1657.               slot_index = keycode - '1'.charCodeAt(0);
  1658.            
  1659.             var inv_index = user.inventory_index_to_mapped_index[slot_index];
  1660.             var item = user.inv.can_select[inv_index];
  1661.             if(item)
  1662.               client[CLIENT_SELECT_INV_FN_NAME](item.id, inv_index);
  1663.           }
  1664.         }else if(keycode == 89)
  1665.           user.bigmap = !user.bigmap;
  1666.          
  1667.       }
  1668.     }
  1669.     keyboard.up(c);
  1670.   }
  1671.   window.addEventListener("keyup", new_game_trigger_keyup, false);
  1672.  
  1673.  
  1674.   // this is a direct copy+paste of lines 15044-15058, except replacing this with game and commenting the one referencing keyup.  This way i dont have to deobfuscate as much
  1675.   game[_0x97e8("0x546")] = function() {
  1676.         window[_0x97e8("0x52d")](_0x97e8("0x551"), this[_0x97e8("0x54a")], !1);
  1677.         window[_0x97e8("0x52d")](_0x97e8("0x538"), this[_0x97e8("0x54f")], !1);
  1678.         window.addEventListener(_0x97e8("0x550"), this[_0x97e8("0x54d")], !1);
  1679.         //window[_0x97e8("0x52d")]("keyup", this[_0x97e8("0x588")], !1);
  1680.         window.addEventListener(_0x97e8("0x58d"), this[_0x97e8("0x589")], !1)
  1681.     }
  1682.     ;
  1683.   game[_0x97e8("0x547")] = function() {
  1684.         window.removeEventListener("mousedown", this[_0x97e8("0x54a")], !1);
  1685.         window[_0x97e8("0x552")](_0x97e8("0x538"), this[_0x97e8("0x54f")], !1);
  1686.         window[_0x97e8("0x552")](_0x97e8("0x550"), this[_0x97e8("0x54d")], !1);
  1687.         //window[_0x97e8("0x552")](_0x97e8("0x58e"), this.yolo1525, !1);
  1688.         window[_0x97e8("0x552")](_0x97e8("0x58d"), this[_0x97e8("0x589")], !1)
  1689.     }
  1690.  
  1691.   // alert on delete inventory
  1692.   SPRITE["EXT_FAST_DELETE"] = find_unique_index();
  1693.   sprite[SPRITE.EXT_FAST_DELETE] = create_text(1, "Fast-Delete", 25, "#FFF", void 0, void 0, "#000", 5, 140);
  1694.  
  1695.   user.ext_fast_delete = { enabled: false, translate: { x: 0, y: 0 } };
  1696.  
  1697.   function draw_ext_fast_delete() {
  1698.     if(user.ext_fast_delete.enabled) {
  1699.       ctx.drawImage(sprite[SPRITE.EXT_FAST_DELETE], user.ext_fast_delete.translate.x, user.ext_fast_delete.translate.y);
  1700.     }
  1701.   }
  1702.  
  1703.   var actual_delete_inv = client[CLIENT_DELETE_INV_FN_NAME];
  1704.   client[CLIENT_DELETE_INV_FN_NAME] = function(c, f) {
  1705.     if(user.ext_fast_delete.enabled) {
  1706.       actual_delete_inv.apply(client, [c, f])
  1707.       return;
  1708.     }
  1709.    
  1710.     // we use setTimeout to ensure the context menu isn't brought up
  1711.     setTimeout(function() {
  1712.       swal({
  1713.         title: "Are you sure?",
  1714.         text: "You will not be able to recover this item!",
  1715.         type: "warning",
  1716.         showCancelButton: true,
  1717.         confirmButtonColor: "#DD6B55",
  1718.         confirmButtonText: "Yes, delete it!",
  1719.         closeOnConfirm: true
  1720.       },
  1721.       function(){
  1722.         actual_delete_inv.apply(client, [ c, f ]);
  1723.       });
  1724.     }, 5);
  1725.   };
  1726.  
  1727.   // clock
  1728.   user.ext_clock = {
  1729.     enabled: true,
  1730.     translate: { x: 0, y: 0 },
  1731.     last_time: -1,
  1732.     last_transition_time: -1,
  1733.     extrapolated_transition_time: -1,
  1734.     radius: 50,
  1735.     time_per_half_day_ms: 1000 * 60 * 4
  1736.   }
  1737.  
  1738.   function init_clock() {
  1739.     var img = new Image();
  1740.     img.onload = function() {
  1741.       var clock_index = find_unique_index();
  1742.       SPRITE["EXT_CLOCK"] = clock_index;
  1743.       sprite[SPRITE.EXT_CLOCK] = img;
  1744.     }
  1745.     img.src = 'http://www.clker.com/cliparts/Y/F/q/S/J/O/dabnite-th.png';
  1746.    
  1747.     var canv = document.createElement("canvas");
  1748.     var ctx = canv.getContext("2d");
  1749.    
  1750.     canv.width = 8;
  1751.     canv.height = 8;
  1752.     ctx.fillStyle = "#FFF";
  1753.     ctx.strokeStyle = "#000";
  1754.     ctx.lineWidth = 1;
  1755.     ctx.beginPath();
  1756.     ctx.ellipse(4, 4, 3, 3, 0, 0, Math.PI * 2, false);
  1757.     ctx.fill();
  1758.     ctx.stroke();
  1759.    
  1760.     var img2 = new Image();
  1761.     img2.onload = function() {
  1762.       var my_index = find_unique_index();
  1763.       SPRITE["EXT_CLOCK_MARKER"] = my_index;
  1764.       sprite[SPRITE.EXT_CLOCK_MARKER] = img2;
  1765.     }
  1766.     img2.src = canv.toDataURL("image/png");
  1767.   }
  1768.  
  1769.   init_clock();
  1770.  
  1771.   var old_get_time = client[CLIENT_GET_TIME_FN_NAME];
  1772.   client[CLIENT_GET_TIME_FN_NAME] = function(c) {
  1773.     if(c != world.time) {
  1774.       var now = new Date().getTime();
  1775.       user.ext_clock.last_time = c;
  1776.       user.ext_clock.last_transition_time = now;
  1777.       user.ext_clock.extrapolated_transition_time = now + user.ext_clock.time_per_half_day_ms;
  1778.     }
  1779.    
  1780.     old_get_time.apply(this, [ c ]);
  1781.   };
  1782.  
  1783.   function draw_ext_clock() {
  1784.     if(!("EXT_CLOCK" in SPRITE))
  1785.       return; // clock not yet loaded
  1786.     if(!("EXT_CLOCK_MARKER" in SPRITE))
  1787.       return; // clock marker not yet loaded
  1788.     if(!user.ext_clock.enabled)
  1789.       return;
  1790.     if(user.ext_clock.extrapolated_transition_time < 0)
  1791.       return;
  1792.    
  1793.     var now = new Date().getTime();
  1794.     var time_since_transition = now - user.ext_clock.last_transition_time;
  1795.     var perc_progress_to_next;
  1796.     if(time_since_transition >= user.ext_clock.time_per_half_day_ms) {
  1797.       perc_progress_to_next = 1;
  1798.     }else {
  1799.       perc_progress_to_next = time_since_transition / user.ext_clock.time_per_half_day_ms;
  1800.     }
  1801.    
  1802.     var x = 0;
  1803.     var y = 0;
  1804.     if(user.ext_clock.last_time == SPRITE.DAY) {
  1805.       if(perc_progress_to_next < 0.5) {
  1806.         var ang = perc_progress_to_next * Math.PI;
  1807.         x = -Math.cos(ang);
  1808.         y = -Math.sin(ang);
  1809.       }else {
  1810.         var ang = (1.0 - perc_progress_to_next) * Math.PI;
  1811.         x = Math.cos(ang);
  1812.         y = -Math.sin(ang);
  1813.       }
  1814.     }else {
  1815.       if(perc_progress_to_next < 0.5) {
  1816.         var ang = perc_progress_to_next * Math.PI;
  1817.         x = Math.cos(ang);
  1818.         y = Math.sin(ang);
  1819.       }else {
  1820.         var ang = (1.0 - perc_progress_to_next) * Math.PI;
  1821.         x = -Math.cos(ang);
  1822.         y = Math.sin(ang);
  1823.       }
  1824.     }
  1825.    
  1826.     x = user.ext_clock.radius + x * user.ext_clock.radius - 4;
  1827.     y = user.ext_clock.radius + y * user.ext_clock.radius - 4;
  1828.    
  1829.     ctx.drawImage(sprite[SPRITE.EXT_CLOCK], user.ext_clock.translate.x, user.ext_clock.translate.y);
  1830.     ctx.drawImage(sprite[SPRITE.EXT_CLOCK_MARKER], user.ext_clock.translate.x + x, user.ext_clock.translate.y + y);
  1831.   }
  1832. }, 2000);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement