Guest User

Starve.io Extension Source Code v.0.0.2.5

a guest
Jul 21st, 2017
448
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. setTimeout(function() {
  2.   // DEOBFUSCATION
  3.   var SPRITE = Lapa13628Mauve;
  4.   var client = Lapa13612Mauve;
  5.   var RECIPES = Lapa13627Mauve;
  6.   var world = Lapa13693Mauve;
  7.   var WORLD = Lapa13574Mauve;
  8.   user.show_spectators = user.Lapa13746Mauve;
  9.   get_mouse_pos = Lapa13745Mauve;
  10.   ctx = Lapa13676Mauve;
  11.  
  12.   var OBFUSCATOR_FN = _0x88d0;
  13.   var USER_INV_VAR_NAME = "inv";
  14.   var USER_INV_DELETE_ITEM_FN_NAME = "delete_item";
  15.   var WORLD_FAST_UNITS_ARR_NAME = OBFUSCATOR_FN("0x495");
  16.   var USER_UID_VAR_NAME = "uid";
  17.   var UPDATE_INV_BUTTONS_FN_NAME = OBFUSCATOR_FN("0x59b");
  18.   var SELECT_CRAFT_FN_NAME = "Lapa13605Mauve" // OLD (JUL 8) OBFUSCATOR_FN("0x59e"); OLD
  19.   var CLIENT_SELECT_INV_FN_NAME = OBFUSCATOR_FN("0x5c3");
  20.   var DRAW_UI_INVENTORY_FN_NAME = "Lapa13569Mauve"; //
  21.   var GAME_TRIGGER_KEYUP_FN_NAME = OBFUSCATOR_FN("0x76d");
  22.   var CLIENT_BUILD_STOP_FN_NAME = OBFUSCATOR_FN("0x587");
  23.   var CLIENT_DELETE_INV_FN_NAME = "Lapa13586Mauve" // OBFUSCATOR_FN("0x5b5");
  24.   var CLIENT_SOCKET_VAR_NAME = OBFUSCATOR_FN("0x564");
  25.   var GAME_DRAW_UI_FN_NAME = OBFUSCATOR_FN("0x768"); //23907
  26.   var GAME_UPDATE_SCENE_FN_NAME = "Lapa13673Mauve" // just below game draw_UI
  27.   var CLIENT_GET_TIME_FN_NAME = OBFUSCATOR_FN("0x59e")
  28.   var UI_PLAY_GAME_FUNCTION_NAME = "play_game";
  29.  
  30.   var SPRITE_COUNTER_VAR_NAME = "Lapa13536Mauve" // look for "x" + c
  31.  
  32.   var INV_WHEAT_SEEDS_VAR_NAME = "INV_WHEAT_Lapa13797Mauve";
  33.   var INV_SEEDS_VAR_NAME = "INV_Lapa13797Mauve";
  34.   var USER_GAUGES_WATER_METER_VAR_NAME = 't';
  35.  
  36.   var CURRENT_FRAME_RATE_VAR_NAME = 'Lapa13681Mauve'; // under window
  37.   // END DEOBFUSCATION
  38.  
  39.   var unique_index_counter = 500;
  40.   var find_unique_index = function() {
  41.     while(sprite[unique_index_counter] != null) {
  42.       unique_index_counter++;
  43.     }
  44.     return unique_index_counter;
  45.   };
  46.  
  47.   var create_help = function() {
  48.     var title = 'HELP MENU';
  49.     var title_font = "bold 40px Baloo Paaji";
  50.     var letter_font = "bold 35px Baloo Paaji";
  51.     var msg_font = "30px Baloo Paaji";
  52.    
  53.     var title_font_height = 40 * 1.1;
  54.     var letter_font_height = 35 * 1.1;
  55.     var msg_font_height = 30 * 1.1;
  56.    
  57.     var help_messages = [
  58.      [ 'H', 'Open Help - open this help menu' ],
  59.      [ 'Y', 'Open Map - open the larger map' ],
  60.      [ 'R', 'Auto-Feed - auto-eat food when low' ],
  61.      [ 'T', 'Auto-Book - auto-equip book on craft' ],
  62.    [ 'K', 'Auto-Drink - auto-drink water when low' ],
  63.      [ 'P', 'Show Spectators - only in hunger games' ],
  64.      [ 'L', 'Fast-Delete - no warning on deleting items' ],
  65.      [ 'C', 'Clock - toggle the clock' ],
  66.      [ '*', 'Type "-swap 1 2" to swap slots 1 and 2' ],
  67.      [ '*', 'Type "-remap F 1" to have slot 1 bound to F' ],
  68.      [ '*', 'Type "-unmapall" to clear all remaps' ]
  69.     ];
  70.    
  71.     var edge_padding_x = 5;
  72.     var top_edge_padding_y = 15;
  73.     var bot_edge_padding_y = 3;
  74.     var title_padding_extra_y = 5;
  75.     var line_padding_y = 3;
  76.     var letter_msg_padding = 3;
  77.    
  78.     var temp_canv = document.createElement("canvas");
  79.     var temp_ctx = temp_canv.getContext("2d");
  80.    
  81.     var longest_letter = 0;
  82.     var longest_msg = 0;
  83.     var total_height = top_edge_padding_y + title_font_height + title_padding_extra_y;
  84.     for(var i = 0; i < help_messages.length; i++)
  85.     {
  86.       total_height += line_padding_y;
  87.      
  88.       temp_ctx.font = letter_font;
  89.       var letter_metrics = temp_ctx.measureText(help_messages[i][0]);
  90.      
  91.       temp_ctx.font = msg_font;
  92.       var msg_metrics = temp_ctx.measureText(help_messages[i][1]);
  93.       longest_letter = Math.max(longest_letter, letter_metrics.width);
  94.       longest_msg = Math.max(longest_msg, msg_metrics.width);
  95.       total_height += Math.max(msg_font_height, letter_font_height);
  96.     }
  97.     total_height += bot_edge_padding_y;
  98.    
  99.     var total_width = edge_padding_x + longest_letter + letter_msg_padding + longest_msg + edge_padding_x;
  100.    
  101.     temp_canv.width = total_width;
  102.     temp_canv.height = total_height;
  103.    
  104.     temp_ctx.globalAlpha = .5;
  105.     round_rect(temp_ctx, 0, 0, temp_canv.width, temp_canv.height, 10);
  106.     fill_path(temp_ctx, "#000");
  107.    
  108.     temp_ctx.globalAlpha = 1.0;
  109.    
  110.     temp_ctx.textAlign = 'left';
  111.     temp_ctx.fillStyle = '#FFF';
  112.     temp_ctx.font = title_font;
  113.     temp_ctx.fillText(title, (temp_canv.width / 2) - (temp_ctx.measureText(title).width / 2), top_edge_padding_y + title_font_height / 2);
  114.    
  115.     temp_ctx.textAlign = 'left';
  116.     var y = top_edge_padding_y + title_font_height + title_padding_extra_y;
  117.     for(var i = 0; i < help_messages.length; i++) {
  118.       y += line_padding_y;
  119.      
  120.       var x = edge_padding_x;
  121.       temp_ctx.font = letter_font;
  122.       temp_ctx.fillText(help_messages[i][0], x, y + letter_font_height / 2)
  123.       x += longest_letter + letter_msg_padding;
  124.      
  125.       temp_ctx.font = msg_font;
  126.       temp_ctx.fillText(help_messages[i][1], x, y + msg_font_height / 2);
  127.       y += Math.max(letter_font_height, msg_font_height)
  128.     }
  129.    
  130.     return temp_canv
  131.   }
  132.  
  133.   function create_arrow_back(color) {
  134.     var bknd_canv = document.createElement("canvas");
  135.     var bknd_ctx = bknd_canv.getContext("2d");
  136.    
  137.     // todo make an arrow
  138.     bknd_ctx.font = "20px Baloo Paaji";
  139.     bknd_canv.width = bknd_ctx.measureText("BACK").width + 2;
  140.     bknd_canv.height = 24;
  141.    
  142.     bknd_ctx.font = "20px Baloo Paaji";
  143.     bknd_ctx.textAlign = 'center';
  144.     bknd_ctx.fillStyle = color;
  145.     bknd_ctx.fillText('BACK', bknd_canv.width / 2, bknd_canv.height / 2);
  146.    
  147.     return bknd_canv;
  148.   }
  149.  
  150.   function create_arrow_next(color) {
  151.     var bknd_canv = document.createElement("canvas");
  152.     var bknd_ctx = bknd_canv.getContext("2d");
  153.    
  154.     // todo make an arrow
  155.     bknd_ctx.font = "20px Baloo Paaji";
  156.     bknd_canv.width = bknd_ctx.measureText("NEXT").width + 2;
  157.     bknd_canv.height = 24;
  158.    
  159.     bknd_ctx.font = "20px Baloo Paaji";
  160.     bknd_ctx.textAlign = 'center';
  161.     bknd_ctx.fillStyle = color;
  162.     bknd_ctx.fillText('NEXT', bknd_canv.width / 2, bknd_canv.height / 2);
  163.    
  164.     return bknd_canv;
  165.   }
  166.  
  167.   var cntr = 0;
  168.   var PAGES = [];
  169.   PAGES["CATEGORIES_1"] = cntr++;
  170.   PAGES["PICKAXES"] = cntr++;
  171.   PAGES["SWORDS"] = cntr++;
  172.   PAGES["SPEARS"] = cntr++;
  173.   PAGES["HAMMERS"] = cntr++;
  174.   PAGES["PLACEABLES"] = cntr++;
  175.   PAGES["PLACEABLES_2"] = cntr++;
  176.   PAGES["WALLS"] = cntr++;
  177.   PAGES["SPIKES"] = cntr++;
  178.   PAGES["DOORS"] = cntr++;
  179.   PAGES["FOOD_HEALING"] = cntr++;
  180.   PAGES["FOOD_HEALING_2"] = cntr++;
  181.   PAGES["HELMETS"] = cntr++;
  182.   PAGES["WEARABLES"] = cntr++;
  183.   PAGES["WEARABLES_2"] = cntr++;
  184.   PAGES["MISCELLANEOUS"] = cntr++;
  185.   PAGES["CRAFTING_ITEMS"] = cntr++;
  186.  
  187.   // All the create_recipe_page_ functions return [ canvas, buttons ]
  188.   // ex. [ img, [ { page_num, translate: {x, y}, width, height, normal, hovered, pushed, contains(x,y) }, ... ]
  189.  
  190.   // returns canvas
  191.   var __create_category_button = function(img, text, font, font_height, bknd_color, bknd_opacity, text_color) {
  192.     var edge_padding_x = 3;
  193.     var edge_padding_y = 3;
  194.     var img_text_spacing_x = 3;
  195.     var roundedness = 10;
  196.    
  197.     var bknd_canv = document.createElement("canvas");
  198.     var bknd_ctx = bknd_canv.getContext("2d");
  199.    
  200.     bknd_ctx.font = font
  201.     var text_metric = bknd_ctx.measureText(text);
  202.    
  203.     bknd_canv.width = edge_padding_x + img.width + img_text_spacing_x + text_metric.width + edge_padding_x;
  204.     bknd_canv.height = edge_padding_y + Math.max(font_height, img.height) + edge_padding_y;
  205.    
  206.     if(bknd_color != null) {
  207.       bknd_ctx.globalAlpha = bknd_opacity;
  208.       round_rect(bknd_ctx, 0, 0, bknd_canv.width, bknd_canv.height, roundedness);
  209.       fill_path(bknd_ctx, bknd_color);
  210.       bknd_ctx.globalAlpha = 1;
  211.     }
  212.    
  213.     bknd_ctx.font = font;
  214.     bknd_ctx.fillStyle = text_color;
  215.     bknd_ctx.drawImage(img, edge_padding_x, edge_padding_y);
  216.     bknd_ctx.fillText(text, edge_padding_x + img.width + img_text_spacing_x, edge_padding_y + img.height / 2);
  217.    
  218.     return bknd_canv;
  219.   }
  220.  
  221.   function __ext_create_button(normal, hovered, pushed) {
  222.     var res = { translate: { x: 0, y: 0 } }
  223.     res.normal = normal;
  224.     res.hovered = hovered;
  225.     res.pushed = pushed;
  226.     res.width = res.normal.width;
  227.     res.height = res.normal.height;
  228.     res.contains = function(x, y) {
  229.       return x >= this.translate.x && y >= this.translate.y && x <= (this.translate.x + this.width) && y <= (this.translate.y + this.height);
  230.     };
  231.     return res;
  232.   }
  233.   // returns { translate: {x, y}, width, height, normal, hovered, pushed, contains(x,y) }
  234.   var create_category_button = function(img, text) {
  235.     var font = '24px Baloo Paaji';
  236.     var font_height = 24;
  237.     var text_color = '#FFF';
  238.     var hovered_background_color = '#000';
  239.     var pushed_background_color = '#000';
  240.     var hovered_background_opacity = 0.4;
  241.     var pushed_background_opacity = 0.8;
  242.    
  243.     var res = {
  244.       translate: { x: 0, y: 0 }  
  245.     }
  246.    
  247.     res.normal = CTI(__create_category_button(img, text, font, font_height, null, 0, text_color));
  248.     res.width = res.normal.width;
  249.     res.height = res.normal.height;
  250.     res.hovered = CTI(__create_category_button(img, text, font, font_height, hovered_background_color, hovered_background_opacity, text_color));
  251.     res.pushed = CTI(__create_category_button(img, text, font, font_height, pushed_background_color, pushed_background_opacity, text_color));
  252.     res.contains = function(x, y) {
  253.       return x >= this.translate.x && y >= this.translate.y && x <= (this.translate.x + this.width) && y <= (this.translate.y + this.height);
  254.     };
  255.    
  256.     return res;
  257.   }
  258.  
  259.   // categories, in the form [ { page_num, img, category_name }, ... ]
  260.   // returns [ canvas, context2d, buttons ]
  261.   var __create_recipe_page_categories = function(categories, prev_category_page_num, next_category_page_num) {
  262.     var columns = 3;
  263.     var left_edge_padding_x = 5;
  264.     var right_edge_padding_x = 5;
  265.     var top_edge_padding_y = 15;
  266.     var bot_edge_padding_y = 10;
  267.     var title_below_padding_y = 5;
  268.     var row_padding_y = 5;
  269.     var title_font = "bold 40px Baloo Paaji";
  270.     var title_font_height = 44;
  271.     var category_font = "24px Baloo Paaji";
  272.     var category_font_height = 24;
  273.     var category_img_text_padding_x = 5;
  274.     var padding_y_before_pagination = 8;
  275.     var column_padding_x = 5;
  276.    
  277.     var prev_button = __ext_create_button(sprite[SPRITE.ARROW_BACK][0], sprite[SPRITE.ARROW_BACK][1], sprite[SPRITE.ARROW_BACK][2]);
  278.     var next_button = __ext_create_button(sprite[SPRITE.ARROW_NEXT][0], sprite[SPRITE.ARROW_NEXT][1], sprite[SPRITE.ARROW_NEXT][2]);
  279.    
  280.     var title = 'CATEGORIES';
  281.    
  282.     var bknd_canv = document.createElement("canvas");
  283.     var bknd_ctx = bknd_canv.getContext("2d");
  284.    
  285.     var title = 'CATEGORIES'
  286.    
  287.     bknd_ctx.font = title_font;
  288.     var title_width = bknd_ctx.measureText(title).width;
  289.    
  290.     bknd_ctx.font = category_font;
  291.     var row_height_prev = 0;
  292.     var max_column_width = 0;
  293.     var total_height = top_edge_padding_y + title_font_height + title_below_padding_y;
  294.     for(var i = 0; i < categories.length; i++) {
  295.       if(i != 0 && i % columns == 0) {
  296.         total_height += row_padding_y + row_height_prev;
  297.         row_height_prev = 0;
  298.       }
  299.      
  300.       var cat_width = categories[i].img.width + category_img_text_padding_x + bknd_ctx.measureText(categories[i].category_name).width;
  301.       max_column_width = Math.max(max_column_width, cat_width);
  302.       row_height_prev = Math.max(row_height_prev, categories[i].img.height);
  303.     }
  304.     total_height += row_padding_y + row_height_prev;
  305.     if(prev_category_page_num != null || next_category_page_num != null) {
  306.       total_height += padding_y_before_pagination + Math.max(prev_button.height, next_button.height);
  307.     }
  308.     total_height += bot_edge_padding_y;
  309.     var total_width = left_edge_padding_x + max_column_width * columns + column_padding_x * (columns - 1) + right_edge_padding_x;
  310.    
  311.     bknd_canv.width = total_width;
  312.     bknd_canv.height = total_height;
  313.    
  314.     bknd_ctx.globalAlpha = 0.5;
  315.     round_rect(bknd_ctx, 0, 0, bknd_canv.width, bknd_canv.height, 10);
  316.     fill_path(bknd_ctx, '#000');
  317.     bknd_ctx.globalAlpha = 1;
  318.    
  319.     bknd_ctx.font = title_font;
  320.     bknd_ctx.fillStyle = '#FFF';
  321.     var title_metr = bknd_ctx.measureText(title);
  322.     bknd_ctx.fillText(title, bknd_canv.width / 2 - title_metr.width / 2, top_edge_padding_y + title_font_height / 2);
  323.    
  324.     var buttons = []
  325.     bknd_ctx.font = category_font;
  326.     var y = top_edge_padding_y + title_font_height + title_below_padding_y;
  327.     var x = left_edge_padding_x;
  328.     row_height_prev = 0;
  329.     for(var i = 0; i < categories.length; i++) {
  330.       if(i != 0 && i % columns == 0) {
  331.         y += row_padding_y + row_height_prev;
  332.         x = left_edge_padding_x;
  333.       }
  334.      
  335.       var but = create_category_button(categories[i].img, categories[i].category_name);
  336.       but.page_num = categories[i].page_num;
  337.       but.translate.x = x;
  338.       but.translate.y = y;
  339.       buttons[buttons.length] = but;
  340.      
  341.       row_height_prev = Math.max(row_height_prev, categories[i].img.height);
  342.       x += max_column_width + column_padding_x;
  343.     }
  344.     y += row_padding_y + row_height_prev;
  345.    
  346.     if(prev_category_page_num != null) {
  347.       prev_button.translate.x = left_edge_padding_x;
  348.       prev_button.translate.y = total_height - prev_button.height - bot_edge_padding_y;
  349.      
  350.       buttons[button.length] = prev_button;
  351.     }
  352.    
  353.     if(next_category_page_num != null) {
  354.       next_button.translate.x = total_width - next_button.width - right_edge_padding_x;
  355.       next_button.translate.y = total_height - next_button.height - bot_edge_padding_y;
  356.      
  357.       buttons[buttons.length] = next_button;
  358.     }
  359.    
  360.     return [ bknd_canv, bknd_ctx, buttons ];
  361.   }
  362.  
  363.   var create_recipe_page_categories_1 = function() {
  364.     var tmp = __create_recipe_page_categories([
  365.       { page_num: PAGES.PICKAXES, img: sprite[SPRITE.INV_PICK_WOOD][1], category_name: "Pickaxes" },
  366.       { page_num: PAGES.SWORDS, img: sprite[SPRITE.INV_SWORD][1], category_name: "Swords" },
  367.       { page_num: PAGES.SPEARS, img: sprite[SPRITE.INV_SPEAR][1], category_name: "Spears" },
  368.       { page_num: PAGES.HAMMERS, img: sprite[SPRITE.INV_HAMMER][1], category_name: "Hammers" },
  369.       { page_num: PAGES.PLACEABLES, img: sprite[SPRITE.INV_FIRE][1], category_name: "Placeables" },
  370.       { page_num: PAGES.WALLS, img: sprite[SPRITE.INV_WALL][1], category_name: "Walls" },
  371.       { page_num: PAGES.SPIKES, img: sprite[SPRITE.INV_SPIKE][1], category_name: "Spikes" },
  372.       { page_num: PAGES.DOORS, img: sprite[SPRITE.INV_DOOR_WOOD_CLOSE][1], category_name: "Doors" },
  373.       { page_num: PAGES.FOOD_HEALING, img: sprite[SPRITE.INV_COOKED_MEAT][1], category_name: "Food & Healing" },
  374.       { page_num: PAGES.HELMETS, img: sprite[SPRITE.INV_STONE_HELMET][1], category_name: "Helmets" },
  375.       { page_num: PAGES.WEARABLES, img: sprite[SPRITE.INV_EARMUFFS][1], category_name: "Wearables" },
  376.       { page_num: PAGES.MISCELLANEOUS, img: sprite[SPRITE.INV_LOCK][1], category_name: "Misc" },
  377.       { page_num: PAGES.CRAFTING_ITEMS, img: sprite[SPRITE.INV_PAPER][1], category_name: "Crafting Items" },
  378.     ]);
  379.    
  380.     var bknd_canv = tmp[0];
  381.     var bknd_ctx = tmp[1];
  382.     var buttons = tmp[2];
  383.    
  384.     return [ CTI(bknd_canv), buttons ];
  385.   }
  386.  
  387.   function get_amount_as_img(amount) {
  388.     if(!sprite[SPRITE[SPRITE_COUNTER_VAR_NAME]][amount]) {
  389.       sprite[SPRITE[SPRITE_COUNTER_VAR_NAME]][amount] = create_text(scale, "x" + amount, 20, "#FFF");
  390.     }
  391.     return sprite[SPRITE[SPRITE_COUNTER_VAR_NAME]][amount];
  392.   }
  393.  
  394.   SPRITE["AUTO_BOOK"] = find_unique_index();
  395.   sprite[SPRITE.AUTO_BOOK] = create_text(1, "Auto-Book", 25, "#FFF", void 0, void 0, "#000", 5, 140);
  396.  
  397.   SPRITE["EXT_HELP"] = find_unique_index();
  398.   sprite[SPRITE.EXT_HELP] = CTI(create_help());
  399.  
  400.   SPRITE["EXT_AUTO_DRINK"] = find_unique_index();
  401.   sprite[SPRITE.EXT_AUTO_DRINK] = create_text(1, "Auto-Drink", 25, "#FFF", void 0, void 0, "#000", 5, 140);
  402.  
  403.   SPRITE["ARROW_NEXT"] = find_unique_index();
  404.   sprite[SPRITE.ARROW_NEXT] = [ CTI(create_arrow_next('#c3c3c3')), CTI(create_arrow_next('#d3d3d3')), CTI(create_arrow_next('#FFF')) ];
  405.  
  406.   SPRITE["ARROW_BACK"] = find_unique_index();
  407.   sprite[SPRITE.ARROW_BACK] = [ CTI(create_arrow_back('#c3c3c3')), CTI(create_arrow_back('#d3d3d3')), CTI(create_arrow_back('#FFF')) ];
  408.  
  409.   user.ext_help = {
  410.     enabled: false,
  411.     translate: {
  412.       x: 0,
  413.       y: 0
  414.     }
  415.   }
  416.  
  417.   user.auto_book = {
  418.     enabled: false,
  419.     translate: {
  420.       x: 0,
  421.       y: 0
  422.     },
  423.     equip_book: function() {
  424.       if(this.enabled) {
  425.         if(user.inv.n[INV.BOOK]) {
  426.           var thePlayer = world[WORLD_FAST_UNITS_ARR_NAME][user[USER_UID_VAR_NAME]];
  427.           if(thePlayer.right != INV.BOOK) {
  428.             client[CLIENT_SELECT_INV_FN_NAME](INV.BOOK, user.inv.find_item(INV.BOOK));
  429.           }
  430.         }
  431.       }
  432.     }
  433.   }
  434.  
  435.   var oldGameUpdate = game.update;
  436.   game.update = function() {
  437.     oldGameUpdate.apply(this);
  438.     user.auto_book.translate.x = game.leaderboard.translate.x - sprite[SPRITE.AUTO_BOOK].width - 10;
  439.     user.auto_book.translate.y = user.show_spectators.translate.y + sprite[SPRITE.SHOW_SPECTATORS].height + 5;
  440.     user.ext_fast_delete.translate.x = game.leaderboard.translate.x - sprite[SPRITE.EXT_FAST_DELETE].width - 10;
  441.     user.ext_fast_delete.translate.y = user.auto_book.translate.y + sprite[SPRITE.AUTO_BOOK].height + 5;
  442.     user.ext_auto_drink.translate.x = game.leaderboard.translate.x - sprite[SPRITE.EXT_AUTO_DRINK].width - 10;
  443.     user.ext_auto_drink.translate.y = user.ext_fast_delete.translate.y + sprite[SPRITE.EXT_AUTO_DRINK].height + 5;
  444.     user.ext_help.translate.x = can.width / 2 - sprite[SPRITE.EXT_HELP].width / 2;
  445.     user.ext_help.translate.y = can.height / 2 - sprite[SPRITE.EXT_HELP].height / 2;
  446.    
  447.     user.ext_clock.translate.x = can.width - user.ext_clock.radius * 2 - 10;
  448.     user.ext_clock.translate.y = game.leaderboard.translate.y + game.leaderboard.img.height + 10;
  449.   };
  450.  
  451.   function draw_ext_help() {
  452.     if(user.ext_help.enabled) {
  453.       ctx.drawImage(sprite[SPRITE.EXT_HELP], user.ext_help.translate.x, user.ext_help.translate.y);
  454.     }
  455.   }
  456.  
  457.   function draw_ext_auto_book() {
  458.     if(user.auto_book.enabled) {
  459.       ctx.drawImage(sprite[SPRITE.AUTO_BOOK], user.auto_book.translate.x, user.auto_book.translate.y);
  460.     }
  461.   }
  462.  
  463.   var oldGameDrawUI = game[GAME_DRAW_UI_FN_NAME];
  464.   game[GAME_DRAW_UI_FN_NAME] = function() {
  465.     oldGameDrawUI.apply(this, arguments);
  466.     draw_ext_auto_book();
  467.     draw_ext_fast_delete();
  468.     draw_ext_auto_drink();
  469.     draw_ext_help();
  470.     draw_ext_clock();
  471.   };
  472.  
  473.   var my_trigger_key_up = function(c) {
  474.     var keycode = c.keyCode;
  475.     if(user.keycodes_to_mapped_keycodes[keycode])
  476.       keycode = user.keycodes_to_mapped_keycodes[keycode];
  477.    
  478.     if (!user.chat.open)  {
  479.       if(keycode == 84) {
  480.         user.auto_book.enabled = !user.auto_book.enabled;
  481.       }else if(keycode == 72) {
  482.         user.ext_help.enabled = !user.ext_help.enabled;  
  483.       }else if(keycode == 67) {
  484.         user.ext_clock.enabled = !user.ext_clock.enabled;
  485.       }
  486.     }
  487.   };
  488.  
  489.   user.craft.do_craft = function(recipeID) {
  490.     var recipe = RECIPES[recipeID];
  491.     this.id = recipeID;
  492.     this.crafting = true;
  493.     if((user.auto_book.enabled && user.inv.n[INV.BOOK]) || world[WORLD_FAST_UNITS_ARR_NAME][user[USER_UID_VAR_NAME]].right == INV.BOOK) {
  494.       this.timeout.max_speed = recipe.time * 3;
  495.     }else {
  496.       this.timeout.max_speed = recipe.time;
  497.     }
  498.     this.id2 = recipe.id2;
  499.     for (var counter = 0; counter < recipe.r.length; counter++) {
  500.       var resource = recipe.r[counter];
  501.       user.inv.decrease(resource[0], resource[1], user.inv.find_item(resource[0]));
  502.     }
  503.     game[UPDATE_INV_BUTTONS_FN_NAME]()
  504.   };
  505.  
  506.   window.addEventListener("keyup", my_trigger_key_up, false);
  507.  
  508.   var oldSelectCraft = client[SELECT_CRAFT_FN_NAME];
  509.   client[SELECT_CRAFT_FN_NAME] = function()
  510.   {
  511.     if(user.weapon.timeout.v != 0 && user.inv.n[INV.BOOK]) {
  512.       var alertMsg = "You can't equip your book right now."
  513.       user.alert.text ? user.alert.list.push(alertMsg) : user.alert.text = alertMsg;
  514.       return;
  515.     }
  516.    
  517.     if(user.ext_auto_drink > 0.02) // don't redo it if we literally checked last frame
  518.       user.ext_auto_drink.delay = 5; // this ensures it will try to check
  519.     user.ext_auto_drink.consider_drink(true); // this helps prevent us from accidentally dehydrating
  520.     if(user.auto_feed > 0.02) // don't redo it if we literally checked last frame
  521.       user.auto_feed.delay = 5; // this ensures it will try to check
  522.     user.auto_feed.update();
  523.     user.auto_book.equip_book();
  524.     oldSelectCraft.apply(this, arguments);
  525.   };
  526.  
  527.   // rearrange inventory
  528.   function reset_inventory_indexes() {
  529.     user.inventory_index_to_mapped_index = []
  530.     for(var index = 0; index < 15; index++) {
  531.       user.inventory_index_to_mapped_index[index] = index;
  532.     }
  533.   }
  534.  
  535.   reset_inventory_indexes();
  536.  
  537.   var __old_ui_play_game = ui[UI_PLAY_GAME_FUNCTION_NAME];
  538.   ui[UI_PLAY_GAME_FUNCTION_NAME] = function() {
  539.     reset_inventory_indexes();
  540.     __old_ui_play_game.apply(this, arguments);
  541.   };
  542.  
  543.   user.keycodes_to_mapped_keycodes = {} // contains things like: { 68: 96 }
  544.   SPRITE["SLOT_NUMBERS_MAPPED"] = find_unique_index();
  545.   sprite[SPRITE.SLOT_NUMBERS_MAPPED] = {};
  546.   sprite[SPRITE.SLOT_NUMBERS_MAPPED][9] = create_text(1, '0', 12, "#FFF");
  547.   sprite[SPRITE.SLOT_NUMBERS_MAPPED][10] = create_text(1, 'P', 12, "#FFF");
  548.  
  549.   user.load_keycode_mapping = function() {
  550.     var keycode_mapping_cookie = Cookies.get("starveio_ext_keymap");
  551.     if(keycode_mapping_cookie) {
  552.       user.keycodes_to_mapped_keycodes = {};
  553.       var tmp = keycode_mapping_cookie.split(",");
  554.       for(var i = 0; i < tmp.length; i++) {
  555.         var tmp_map = tmp[i].split("-");
  556.         var mapped_from = parseInt(tmp_map[0])
  557.         var mapped_to = parseInt(tmp_map[1]);
  558.         user.keycodes_to_mapped_keycodes[mapped_from] = mapped_to;
  559.        
  560.         if(mapped_to >= '1'.charCodeAt(0) && mapped_to <= '9'.charCodeAt(0)) {
  561.           var slot_index;
  562.           if(mapped_to == 'P'.charCodeAt(0))
  563.             slot_index = 10;
  564.           else if(mapped_to == '0'.charCodeAt(0))
  565.             slot_index = 9;
  566.           else
  567.             slot_index = mapped_to - '1'.charCodeAt(0);
  568.           var mapped_from_char = String.fromCharCode(mapped_from);
  569.           sprite[SPRITE.SLOT_NUMBERS_MAPPED][slot_index] = create_text(1, mapped_from_char, 12, "#FFF");
  570.         }
  571.       }
  572.     }
  573.   }
  574.  
  575.   user.save_keycode_mapping = function() {
  576.     var res = "";
  577.     var first = true;
  578.     for(var key in user.keycodes_to_mapped_keycodes) {
  579.       if(!first)
  580.         res += ",";
  581.       else
  582.         first = false;
  583.      
  584.       var tmp = user.keycodes_to_mapped_keycodes[key];
  585.       res += key.toString() + "-" + tmp.toString();
  586.     }
  587.    
  588.     Cookies.set("starveio_ext_keymap", res);
  589.   }
  590.  
  591.   user.load_keycode_mapping();
  592.  
  593.   function better_draw_amount(amount, loc, pushed) {
  594.     var amount_as_img = get_amount_as_img(amount)
  595.     var x = loc.x + 70 - amount_as_img.width - 5 * scale;
  596.     var y = loc.y + 75 - amount_as_img.height - 5 * scale;
  597.    
  598.     if(pushed) {
  599.       y += 5 * scale;
  600.     }
  601.    
  602.     ctx.drawImage(amount_as_img, x, y);
  603.   }
  604.  
  605.   function better_draw_slot(slot_index, loc, pushed) {
  606.     var img;
  607.     if(sprite[SPRITE.SLOT_NUMBERS_MAPPED][slot_index]) {
  608.       img = sprite[SPRITE.SLOT_NUMBERS_MAPPED][slot_index];
  609.     }else {
  610.       img = sprite[SPRITE.SLOT_NUMBER][slot_index];
  611.     }
  612.    
  613.    
  614.     var x = loc.x + 5 * scale;
  615.     var y = loc.y + 5 * scale;
  616.     if(pushed) {
  617.       y += 5 * scale;
  618.     }
  619.    
  620.     ctx.drawImage(img, x, y);
  621.   }
  622.  
  623.  
  624.   user.inv.hotbar_button_locations = []
  625.   for(var tmp_counter = 0; tmp_counter < 13; tmp_counter++) {
  626.     user.inv.hotbar_button_locations[tmp_counter] = { x: 0, y: 0 };
  627.   }
  628.  
  629.   game[UPDATE_INV_BUTTONS_FN_NAME] = function() {
  630.     var user_inventory = user.inv;
  631.     var total_button_width = (10 + 70) * 13;
  632.     var left_button_x = window.innerWidth / 2 - total_button_width / 2;
  633.     for(var index = 0; index < user_inventory.max; index++) {
  634.       if(!user_inventory.hotbar_button_locations[index])
  635.         user_inventory.hotbar_button_locations[index] = { x: 0, y: 0 }
  636.      
  637.       // it uses images width/height per element, which makes no sense if the elements
  638.       // are ever not the same height and requires we already have items in our inventory.
  639.       // we just use the constant width/height of 70x75
  640.       user_inventory.hotbar_button_locations[index].x = (10 + 70) * index + left_button_x + 10;
  641.       user_inventory.hotbar_button_locations[index].y = can.height - 75 - 8;
  642.     }
  643.    
  644.     // now we update the can_select based on what we just determined. However the little
  645.     // "plus" buttons are indexed by the item that they are "plusing" which means we
  646.     // need to adjust based on our remapped items
  647.     for(var index = 0; index < user_inventory.can_select.length; index++) {
  648.       var true_index_of_this_index = -1; // for positioning the button
  649.       for(var index2 = 0; index2 < user.inventory_index_to_mapped_index.length; index2++) {
  650.         if(user.inventory_index_to_mapped_index[index2] == index) {
  651.           true_index_of_this_index = index2;
  652.           break;
  653.         }
  654.       }
  655.      
  656.       var cs_translate = user_inventory.can_select[index].info.translate;
  657.       cs_translate.x = user_inventory.hotbar_button_locations[true_index_of_this_index].x;
  658.       cs_translate.y = user_inventory.hotbar_button_locations[true_index_of_this_index].y;
  659.      
  660.       var pb_translate = this.plus_buttons[user_inventory.can_select[index].id].info.translate;
  661.       var true_but_loc = user_inventory.hotbar_button_locations[true_index_of_this_index];
  662.      
  663.       pb_translate.x = true_but_loc.x + 18;
  664.       pb_translate.y = true_but_loc.y - 35 - 6; // again 35 is height of plus button
  665.     }
  666.   }
  667.  
  668.   // force recalculate after building bag
  669.   var oldClientBuildStop = client[CLIENT_BUILD_STOP_FN_NAME];
  670.   client[CLIENT_BUILD_STOP_FN_NAME] = function(c) {
  671.     oldClientBuildStop.apply(client, [ c ]);
  672.    
  673.     if(c == INV.BAG) {
  674.       game[UPDATE_INV_BUTTONS_FN_NAME].apply(game, []);
  675.     }
  676.   }
  677.  
  678.   window[DRAW_UI_INVENTORY_FN_NAME] = function() {
  679.     var user_inventory = user.inv;
  680.     var user_fast_unit = world[WORLD_FAST_UNITS_ARR_NAME][user[USER_UID_VAR_NAME]];
  681.     if(!user_fast_unit)
  682.       return;
  683.    
  684.     var user_can_select = user_inventory.can_select;
  685.    
  686.     if(!user_can_select[0])
  687.       return;
  688.    
  689.     for(var index = 0; index < user_inventory.max; index++) {
  690.       var item_to_draw = user_can_select[user.inventory_index_to_mapped_index[index]];
  691.       var loc = user_inventory.hotbar_button_locations[index];
  692.      
  693.       if(!item_to_draw) {
  694.         // draw the empty slot
  695.         var empty_slot_img = sprite[SPRITE.EMPTY_SLOT][2];
  696.         ctx.drawImage(empty_slot_img, loc.x, loc.y);
  697.         continue;
  698.       }
  699.      
  700.       var equipped_or_selected = false;
  701.       if(user.right == item_to_draw.id || (user.clothe == item_to_draw.id && user.clothe > 0)) {
  702.         equipped_or_selected = true;
  703.         ctx.drawImage(item_to_draw.info.img[2], loc.x, loc.y);
  704.       }else {
  705.         ctx.drawImage(item_to_draw.info.img[item_to_draw.info.state], loc.x, loc.y);
  706.       }
  707.      
  708.       var amount_of_item = user_inventory.n[item_to_draw.id];
  709.       if(amount_of_item > 1) {
  710.         better_draw_amount(amount_of_item, loc, equipped_or_selected);
  711.       }
  712.      
  713.       if(amount_of_item > 0) {
  714.         better_draw_slot(index, loc, equipped_or_selected);
  715.       }
  716.      
  717.       var user_chest = user.chest;
  718.       if(user_chest.open && (user_chest.id < 0 || user_chest.id == item_to_draw.id) && !(user_chest.lock && user_chest.pid != user.id)) {
  719.         game.plus_buttons[item_to_draw.id].draw(ctx);
  720.       }
  721.      
  722.       var user_furnace = user.furnace;
  723.       if(user_furnace.open && item_to_draw.id == INV.WOOD) {
  724.         game.plus_buttons[item_to_draw.id].draw(ctx);
  725.       }
  726.      
  727.       var user_windmill = user.windmill;
  728.       if(user_windmill.open && item_to_draw.id == INV.WILD_WHEAT) {
  729.         game.plus_buttons[item_to_draw.id].draw(ctx);
  730.       }
  731.     }
  732.   };
  733.  
  734.   var __old_inv_delete_item_fn = user[USER_INV_VAR_NAME][USER_INV_DELETE_ITEM_FN_NAME];
  735.   user[USER_INV_VAR_NAME][USER_INV_DELETE_ITEM_FN_NAME] = function(itemType, index) {
  736.     var firstEmptySlot = user.inv.can_select.length - 1;
  737.     var emptySlotCounter = firstEmptySlot;
  738.     for(var visualIndex = 0; visualIndex < user.inventory_index_to_mapped_index.length; visualIndex++) {
  739.       var actualIndex = user.inventory_index_to_mapped_index[visualIndex];
  740.      
  741.       if(actualIndex == index) {
  742.         user.inventory_index_to_mapped_index[visualIndex] = emptySlotCounter;
  743.         emptySlotCounter += 1;
  744.       }else if(actualIndex > index) {
  745.         if(actualIndex <= firstEmptySlot) {
  746.           user.inventory_index_to_mapped_index[visualIndex] = actualIndex - 1;
  747.         }else {
  748.           user.inventory_index_to_mapped_index[visualIndex] = emptySlotCounter;
  749.           emptySlotCounter += 1;
  750.         }
  751.       }
  752.     }
  753.    
  754.     __old_inv_delete_item_fn.apply(this, [ itemType, index ]);
  755.   };
  756.  
  757.   // returns the visible index (1-indexed) of given by the specified user input or NaN
  758.   function parse_inventory_index_from_string(str)
  759.   {
  760.     if(str == 'P') {
  761.       return 11;
  762.     }else if(str == '0') {
  763.       return 10;
  764.     }
  765.    
  766.     return parseInt(str);
  767.   }
  768.  
  769.   function ext_try_command(spl_by_spaces) {
  770.     if(spl_by_spaces[0] == "-swap") {
  771.       if(spl_by_spaces.length != 3)
  772.         return false;
  773.      
  774.      
  775.       var num1 = parse_inventory_index_from_string(spl_by_spaces[1]);
  776.       var num2 = parse_inventory_index_from_string(spl_by_spaces[2]);
  777.       if(isNaN(num1) || isNaN(num2)) {
  778.         return false;
  779.       }
  780.      
  781.       if(num1 < 1 || num2 < 1 || num1 > user.inv.max || num2 > user.inv.max)
  782.         return false;
  783.      
  784.       var num1_mapped = user.inventory_index_to_mapped_index[num1 - 1]
  785.       var num2_mapped = user.inventory_index_to_mapped_index[num2 - 1]
  786.      
  787.       user.inventory_index_to_mapped_index[num1 - 1] = num2_mapped;
  788.       user.inventory_index_to_mapped_index[num2 - 1] = num1_mapped;
  789.       game[UPDATE_INV_BUTTONS_FN_NAME]();
  790.       return true;
  791.     }else if(spl_by_spaces[0] == "-remap")
  792.     {
  793.       if(spl_by_spaces.length != 3)
  794.         return false;
  795.      
  796.       var let1 = spl_by_spaces[1].toUpperCase();
  797.       var let2 = spl_by_spaces[2].toUpperCase();
  798.      
  799.       var mapped_from = let1.toUpperCase().charCodeAt(0);
  800.       var mapped_to = let2.toUpperCase().charCodeAt(0);
  801.      
  802.       var let1_asnum = parseInt(let1);
  803.       var let2_asnum = parseInt(let2);
  804.      
  805.       if((let2_asnum >= 0 && let2_asnum <= 13) || mapped_to == 'P'.charCodeAt(0)) {
  806.         var slot_index;
  807.         if(mapped_to == 'P'.charCodeAt(0))
  808.           slot_index = 10;
  809.         else if(mapped_to == '0'.charCodeAt(0))
  810.           slot_index = 9;
  811.         else
  812.           slot_index = let2_asnum - 1;
  813.        
  814.         var mapped_from_char = String.fromCharCode(mapped_from);
  815.         sprite[SPRITE.SLOT_NUMBERS_MAPPED][slot_index] = create_text(1, mapped_from_char, 12, "#FFF");
  816.         user.keycodes_to_mapped_keycodes[mapped_from] = "slot_" + slot_index;
  817.         user.save_keycode_mapping();
  818.         return true;
  819.       }
  820.      
  821.       if(mapped_to == keyboard.LEFT) {
  822.         keyboard.LEFT = mapped_from;
  823.         return true;
  824.       }else if(mapped_to == keyboard.RIGHT) {
  825.         keyboard.RIGHT = mapped_from;
  826.         return true;
  827.       }else if(mapped_to == keyboard.TOP) {
  828.         keyboard.TOP = mapped_from;
  829.         return true;
  830.       }else if(mapped_to == keyboard.BOTTOM) {
  831.         keyboard.BOTTOM = mapped_from;
  832.         return true;
  833.       }
  834.      
  835.       user.keycodes_to_mapped_keycodes[mapped_from] = mapped_to;
  836.       user.save_keycode_mapping();
  837.       return true;
  838.     }else if(spl_by_spaces[0] == "-unmapall") {
  839.       if(spl_by_spaces.length != 1)
  840.         return false;
  841.      
  842.       sprite[SPRITE.SLOT_NUMBERS_MAPPED] = {}
  843.       user.keycodes_to_mapped_keycodes = {}
  844.       user.save_keycode_mapping();
  845.       return true;
  846.     }
  847.    
  848.     return false;
  849.   }
  850.  
  851.   window.removeEventListener("keyup", game[GAME_TRIGGER_KEYUP_FN_NAME], false)
  852.   function new_game_trigger_keyup(c) {
  853.     var keycode = c.keyCode;
  854.     if(user.keycodes_to_mapped_keycodes[keycode])
  855.       keycode = user.keycodes_to_mapped_keycodes[keycode];
  856.    
  857.    
  858.     if (user.chat.open && keycode == 27) {
  859.       user.chat.quit();
  860.     }else if(keycode == 13) {
  861.       var txt = user.chat.input.value;
  862.       var spl = txt.split(" ");
  863.       if(!ext_try_command(spl))
  864.         user.chat.run();
  865.       else
  866.         user.chat.quit();
  867.     }else if(!user.chat.open) {
  868.       if(keycode === 82) {
  869.         user.auto_feed.enabled = !user.auto_feed.enabled;
  870.       }else if(80 === keycode && world.mode === WORLD.MODE_HUNGER_GAMES && !user.spectator)
  871.       {
  872.         user.show_spectators.enabled = !user.show_spectators.enabled;
  873.       }else if(keycode == 'L'.charCodeAt(0)) {
  874.         user.ext_fast_delete.enabled = !user.ext_fast_delete.enabled;
  875.       }else if(keycode == 'K'.charCodeAt(0)) {
  876.         user.ext_auto_drink.enabled = !user.ext_auto_drink.enabled;
  877.       }else
  878.       {
  879.         var is_slot_index = typeof(keycode) === 'string' && keycode.startsWith('slot_');
  880.        
  881.         var is_slot_index_alt = keycode >= '0'.charCodeAt(0) && keycode <= '9'.charCodeAt(0) || keycode == 'P';
  882.        
  883.         if(is_slot_index) {
  884.           if(user.craft.id < 0) {
  885.             var slot_index_str = keycode.substr(5);
  886.             var slot_index = parseInt(slot_index_str);
  887.            
  888.             var inv_index = user.inventory_index_to_mapped_index[slot_index];
  889.             var item = user.inv.can_select[inv_index];
  890.             if(item)
  891.               client[CLIENT_SELECT_INV_FN_NAME](item.id, inv_index);
  892.           }
  893.         }else if(is_slot_index_alt) {
  894.           if(user.craft.id < 0) {
  895.             var slot_index = -1;
  896.             if(keycode == '0'.charCodeAt(0))
  897.               slot_index = 9;
  898.             else if(keycode == 'P'.charCodeAt(0))
  899.               slot_index = 10;
  900.             else
  901.               slot_index = keycode - '1'.charCodeAt(0);
  902.            
  903.             var inv_index = user.inventory_index_to_mapped_index[slot_index];
  904.             var item = user.inv.can_select[inv_index];
  905.             if(item)
  906.               client[CLIENT_SELECT_INV_FN_NAME](item.id, inv_index);
  907.           }
  908.         }else if(keycode == 89)
  909.           user.bigmap = !user.bigmap;
  910.          
  911.       }
  912.     }
  913.     keyboard.up(c);
  914.   }
  915.   window.addEventListener("keyup", new_game_trigger_keyup, false);
  916.  
  917.  
  918.   // this is a direct copy+paste of lines 24092-24106, except replacing this with game and commenting the one referencing keyup.  This way i dont have to deobfuscate as much
  919.   game[_0x88d0("0x6f6")] = function() {
  920.         window[_0x88d0("0x6d7")](_0x88d0("0x701"), game[_0x88d0("0x6fc")], !1);
  921.         window[_0x88d0("0x6d7")]("mouseup", game[_0x88d0("0x6fe")], !1);
  922.         window[_0x88d0("0x6d7")](_0x88d0("0x702"), game[_0x88d0("0x6ff")], !1);
  923.         //window[_0x88d0("0x6d7")](_0x88d0("0x6d8"), this[_0x88d0("0x76d")], !1);
  924.         window[_0x88d0("0x6d7")](_0x88d0("0x778"), game[_0x88d0("0x779")], !1)
  925.     }
  926.     ;
  927.     game[_0x88d0("0x6f7")] = function() {
  928.         window[_0x88d0("0x703")]("mousedown", game[_0x88d0("0x6fc")], !1);
  929.         window[_0x88d0("0x703")](_0x88d0("0x6e2"), game[_0x88d0("0x6fe")], !1);
  930.         window[_0x88d0("0x703")](_0x88d0("0x702"), game.Lapa13663Mauve, !1);
  931.         //window.removeEventListener(_0x88d0("0x6d8"), this[_0x88d0("0x76d")], !1);
  932.         window.removeEventListener("keydown", game[_0x88d0("0x779")], !1)
  933.     }
  934.  
  935.   // alert on delete inventory
  936.   SPRITE["EXT_FAST_DELETE"] = find_unique_index();
  937.   sprite[SPRITE.EXT_FAST_DELETE] = create_text(1, "Fast-Delete", 25, "#FFF", void 0, void 0, "#000", 5, 140);
  938.  
  939.   user.ext_fast_delete = { enabled: false, translate: { x: 0, y: 0 } };
  940.  
  941.   function draw_ext_fast_delete() {
  942.     if(user.ext_fast_delete.enabled) {
  943.       ctx.drawImage(sprite[SPRITE.EXT_FAST_DELETE], user.ext_fast_delete.translate.x, user.ext_fast_delete.translate.y);
  944.     }
  945.   }
  946.  
  947.   var actual_delete_inv = client[CLIENT_DELETE_INV_FN_NAME];
  948.   client[CLIENT_DELETE_INV_FN_NAME] = function(c, f) {
  949.     if(user.ext_fast_delete.enabled) {
  950.       actual_delete_inv.apply(client, [c, f])
  951.       return;
  952.     }
  953.    
  954.     // we use setTimeout to ensure the context menu isn't brought up
  955.     setTimeout(function() {
  956.       swal({
  957.         title: "Are you sure?",
  958.         text: "You will not be able to recover this item!",
  959.         type: "warning",
  960.         showCancelButton: true,
  961.         confirmButtonColor: "#DD6B55",
  962.         confirmButtonText: "Yes, delete it!",
  963.         closeOnConfirm: true
  964.       },
  965.       function(){
  966.         actual_delete_inv.apply(client, [ c, f ]);
  967.       });
  968.     }, 5);
  969.   };
  970.  
  971.   // clock
  972.   user.ext_clock = {
  973.     enabled: true,
  974.     translate: { x: 0, y: 0 },
  975.     last_time: -1,
  976.     last_transition_time: -1,
  977.     extrapolated_transition_time: -1,
  978.     radius: 50,
  979.     time_per_half_day_ms: 1000 * 60 * 4
  980.   }
  981.  
  982.   function init_clock() {
  983.     var img = new Image();
  984.     img.onload = function() {
  985.       var clock_index = find_unique_index();
  986.       SPRITE["EXT_CLOCK"] = clock_index;
  987.       sprite[SPRITE.EXT_CLOCK] = img;
  988.     }
  989.     img.src = 'http://www.clker.com/cliparts/Y/F/q/S/J/O/dabnite-th.png';
  990.    
  991.     var canv = document.createElement("canvas");
  992.     var ctx = canv.getContext("2d");
  993.    
  994.     canv.width = 8;
  995.     canv.height = 8;
  996.     ctx.fillStyle = "#FFF";
  997.     ctx.strokeStyle = "#000";
  998.     ctx.lineWidth = 1;
  999.     ctx.beginPath();
  1000.     ctx.ellipse(4, 4, 3, 3, 0, 0, Math.PI * 2, false);
  1001.     ctx.fill();
  1002.     ctx.stroke();
  1003.    
  1004.     var img2 = new Image();
  1005.     img2.onload = function() {
  1006.       var my_index = find_unique_index();
  1007.       SPRITE["EXT_CLOCK_MARKER"] = my_index;
  1008.       sprite[SPRITE.EXT_CLOCK_MARKER] = img2;
  1009.     }
  1010.     img2.src = canv.toDataURL("image/png");
  1011.   }
  1012.  
  1013.   init_clock();
  1014.  
  1015.   var old_get_time = client[CLIENT_GET_TIME_FN_NAME];
  1016.   client[CLIENT_GET_TIME_FN_NAME] = function(c) {
  1017.     if(c != world.time) {
  1018.       var now = new Date().getTime();
  1019.       user.ext_clock.last_time = c;
  1020.       user.ext_clock.last_transition_time = now;
  1021.       user.ext_clock.extrapolated_transition_time = now + user.ext_clock.time_per_half_day_ms;
  1022.     }
  1023.    
  1024.     old_get_time.apply(this, [ c ]);
  1025.   };
  1026.  
  1027.   function draw_ext_clock() {
  1028.     if(!("EXT_CLOCK" in SPRITE))
  1029.       return; // clock not yet loaded
  1030.     if(!("EXT_CLOCK_MARKER" in SPRITE))
  1031.       return; // clock marker not yet loaded
  1032.     if(!user.ext_clock.enabled)
  1033.       return;
  1034.     if(user.ext_clock.extrapolated_transition_time < 0)
  1035.       return;
  1036.    
  1037.     var now = new Date().getTime();
  1038.     var time_since_transition = now - user.ext_clock.last_transition_time;
  1039.     var perc_progress_to_next;
  1040.     if(time_since_transition >= user.ext_clock.time_per_half_day_ms) {
  1041.       perc_progress_to_next = 1;
  1042.     }else {
  1043.       perc_progress_to_next = time_since_transition / user.ext_clock.time_per_half_day_ms;
  1044.     }
  1045.    
  1046.     var x = 0;
  1047.     var y = 0;
  1048.     if(user.ext_clock.last_time == SPRITE.DAY) {
  1049.       if(perc_progress_to_next < 0.5) {
  1050.         var ang = perc_progress_to_next * Math.PI;
  1051.         x = -Math.cos(ang);
  1052.         y = -Math.sin(ang);
  1053.       }else {
  1054.         var ang = (1.0 - perc_progress_to_next) * Math.PI;
  1055.         x = Math.cos(ang);
  1056.         y = -Math.sin(ang);
  1057.       }
  1058.     }else {
  1059.       if(perc_progress_to_next < 0.5) {
  1060.         var ang = perc_progress_to_next * Math.PI;
  1061.         x = Math.cos(ang);
  1062.         y = Math.sin(ang);
  1063.       }else {
  1064.         var ang = (1.0 - perc_progress_to_next) * Math.PI;
  1065.         x = -Math.cos(ang);
  1066.         y = Math.sin(ang);
  1067.       }
  1068.     }
  1069.    
  1070.     x = user.ext_clock.radius + x * user.ext_clock.radius - 4;
  1071.     y = user.ext_clock.radius + y * user.ext_clock.radius - 4;
  1072.    
  1073.     ctx.drawImage(sprite[SPRITE.EXT_CLOCK], user.ext_clock.translate.x, user.ext_clock.translate.y);
  1074.     ctx.drawImage(sprite[SPRITE.EXT_CLOCK_MARKER], user.ext_clock.translate.x + x, user.ext_clock.translate.y + y);
  1075.   }
  1076.  
  1077.   // AUTO-DRINK
  1078.   user.ext_auto_drink = {
  1079.     enabled: false,
  1080.     translate: {
  1081.       x: 0,
  1082.       y: 0
  1083.     },
  1084.     delay: 0,
  1085.     consider_drink: function(trying_to_craft_or_nil) {
  1086.       if(this.enabled && user.craft.id < 0) {
  1087.         if(this.delay < 10)
  1088.           this.delay += window[CURRENT_FRAME_RATE_VAR_NAME]
  1089.         var current_water = user.gauges[USER_GAUGES_WATER_METER_VAR_NAME];
  1090.        
  1091.         var max_water_to_drink = 0.05;
  1092.         if(trying_to_craft_or_nil)
  1093.           max_water_to_drink = 0.2;
  1094.         if(this.delay > 2 && current_water < max_water_to_drink) {
  1095.           if(user.inv.n[INV.BOTTLE_FULL]) {
  1096.             client[CLIENT_SELECT_INV_FN_NAME](INV.BOTTLE_FULL, user.inv.find_item(INV.BOTTLE_FULL));
  1097.           }
  1098.           this.delay = 0;
  1099.         }
  1100.       }
  1101.     }
  1102.   };
  1103.   function draw_ext_auto_drink() {
  1104.     if(user.ext_auto_drink.enabled) {
  1105.       ctx.drawImage(sprite[SPRITE.EXT_AUTO_DRINK], user.ext_auto_drink.translate.x, user.ext_auto_drink.translate.y);
  1106.     }
  1107.   }
  1108.  
  1109.   var old_game_update_scene = game[GAME_UPDATE_SCENE_FN_NAME];
  1110.   game[GAME_UPDATE_SCENE_FN_NAME] = function() {
  1111.     old_game_update_scene.apply(this, arguments);
  1112.     user.ext_auto_drink.consider_drink(false);
  1113.   }
  1114. }, 2000);
Add Comment
Please, Sign In to add comment