IdlePixel+ Teams QoL

Various teams quality of life additions, quick deposit/withdraw fight points, better interface when clicking on stored items, storage organisation

  1. // ==UserScript==
  2. // @name IdlePixel+ Teams QoL
  3. // @namespace com.zlef.idlepixel
  4. // @version 2.1.1
  5. // @description Various teams quality of life additions, quick deposit/withdraw fight points, better interface when clicking on stored items, storage organisation
  6. // @author Zlef
  7. // @license MIT
  8. // @match *://idle-pixel.com/login/play*
  9. // @grant none
  10. // @icon https://cdn.idle-pixel.com/images/teams_sigil.png
  11. // @require https://greasyfork.org/scripts/441206-idlepixel/code/IdlePixel+.js?anticache=20220905
  12. // @require https://update.greasyfork.org/scripts/484046/1307183/IdlePixel%2B%20Custom%20Handling.js
  13. // ==/UserScript==
  14.  
  15. (function() {
  16. 'use strict';
  17.  
  18. class TeamsQoL extends IdlePixelPlusPlugin {
  19. constructor() {
  20. super("teamsqol", {
  21. about: {
  22. name: GM_info.script.name,
  23. version: GM_info.script.version,
  24. author: GM_info.script.author,
  25. description: GM_info.script.description
  26. },
  27. });
  28. this.queue = [];
  29. this.processingQueue = false;
  30.  
  31. this.settings = {
  32. fight_points_buffer: -10,
  33. show_fight_points_buttons: true,
  34. show_energy_buttons: false,
  35. show_quick_deposit_all_button: false,
  36. include_equipped_gear_in_quick_deposit: false,
  37. quick_deposit_visibility: {
  38. 'quick_deposit_ores': true,
  39. 'quick_deposit_bars': true,
  40. 'quick_deposit_seeds': true,
  41. 'quick_deposit_brewing_ingredients': true,
  42. 'quick_deposit_logs': true,
  43. 'quick_deposit_raw': true,
  44. 'quick_deposit_cooked': true,
  45. 'quick_deposit_cooking': true,
  46. 'quick_deposit_combat': true
  47. },
  48. quick_deposit_ores: {
  49. 'stone': true, 'copper': true, 'iron': true, 'silver': true, 'gold': true,
  50. 'promethium': true, 'titanium': true, 'ancient_ore': true, 'dragon_ore': true,
  51. 'sapphire': false, 'emerald': false, 'ruby': false, 'diamond': false,
  52. 'blue_marble_mineral': true, 'amethyst_mineral': true, 'sea_crystal_mineral': true,
  53. 'dense_marble_mineral': true, 'fluorite_mineral': true, 'clear_marble_mineral': true,
  54. 'jade_mineral': true, 'lime_quartz_mineral': true, 'opal_mineral': true,
  55. 'purple_quartz_mineral': true, 'amber_mineral': true, 'smooth_pearl_mineral': true,
  56. 'sulfer_mineral': true, 'topaz_mineral': true, 'tanzanite_mineral': true,
  57. 'magnesium_mineral': true, 'frozen_mineral': true, 'blood_crystal_mineral': true
  58. },
  59. quick_deposit_bars: {
  60. 'bronze_bar': true, 'iron_bar': true, 'silver_bar': true, 'gold_bar': true,
  61. 'promethium_bar': true, 'titanium_bar': true, 'ancient_bar': true, 'dragon_bar': true,
  62. 'charcoal': false, 'lava': false, 'plasma': false,
  63. },
  64. quick_deposit_seeds: {
  65. 'dotted_green_leaf_seeds': true, 'green_leaf_seeds': true, 'lime_leaf_seeds': true,
  66. 'gold_leaf_seeds': true, 'crystal_leaf_seeds': true, 'red_mushroom_seeds': true,
  67. 'stardust_seeds': true, 'tree_seeds': true, 'oak_tree_seeds': true, 'willow_tree_seeds': true,
  68. 'maple_tree_seeds': true, 'stardust_tree_seeds': true, 'pine_tree_seeds': true,
  69. 'redwood_tree_seeds': true, 'apple_tree_seeds': true, 'banana_tree_seeds': true,
  70. 'orange_tree_seeds': true, 'palm_tree_seeds': true, 'dragon_fruit_tree_seeds': true,
  71. 'lava_tree_seeds': true, 'bone_tree_seeds': true, 'strange_tree_seeds': true,
  72. 'bones': false, 'big_bones': false, 'ashes': false, 'ice_bones': false, 'blood_bones': false
  73. },
  74. quick_deposit_brewing_ingredients: {
  75. 'dotted_green_leaf': true, 'green_leaf': true, 'lime_leaf': true,
  76. 'gold_leaf': true, 'crystal_leaf': true, 'red_mushroom': true,
  77. 'strange_leaf': true, 'stranger_leaf': true, 'strangest_leaf': true
  78. },
  79. quick_deposit_logs: {
  80. 'logs': true, 'oak_logs': true, 'willow_logs': true, 'maple_logs': true,
  81. 'stardust_logs': true, 'pine_logs': true, 'redwood_logs': true, 'dense_logs': true
  82. },
  83. quick_deposit_raw: {
  84. 'raw_chicken': true, 'raw_bird_meat': true, 'raw_meat': true,
  85. 'raw_shrimp': true, 'raw_anchovy': true, 'raw_sardine': true, 'raw_crab': true,
  86. 'raw_piranha': true, 'raw_salmon': true, 'raw_trout': true, 'raw_pike': true,
  87. 'raw_eel': true, 'raw_rainbow_fish': true, 'raw_tuna': true, 'raw_swordfish': true,
  88. 'raw_manta_raw': true, 'raw_shark': true, 'raw_whale': true,
  89. 'raw_small_stardust_fish': true, 'raw_medium_stardust_fish': true, 'raw_large_stardust_fish': true,
  90. 'raw_angler_fish': true, 'bait': false, 'super_bait': false, 'mega_bait': false, 'seaweed': false
  91. },
  92. quick_deposit_cooked: {
  93. 'cooked_chicken': true, 'cooked_bird_meat': true, 'cooked_meat': true, 'honey': true, 'cheese': true,
  94. 'cooked_shrimp': true, 'cooked_anchovy': true, 'cooked_sardine': true, 'cooked_crab': true, 'cooked_piranha': true,
  95. 'cooked_salmon': true, 'cooked_trout': true, 'cooked_pike': true, 'cooked_cooked_eel': true, 'cooked_rainbow_fish': true,
  96. 'cooked_tuna': true, 'cooked_swordfish': true, 'cooked_manta_raw': true, 'cooked_shark': true, 'cooked_whale': true,
  97. 'cooked_small_stardust_fish': true, 'cooked_medium_stardust_fish': true, 'cooked_large_stardust_fish': true,
  98. 'cooked_angler_fish': true
  99. },
  100. quick_deposit_cooking: {
  101. 'egg': true, 'flour': true, 'chocolate': true, 'maggots': true, 'apple': true, 'banana': true,
  102. 'orange': true, 'maple_syrup': true, 'coconut': true, 'dragon_fruit': true, 'potato': true,
  103. 'carrot': true, 'beet': true, 'broccoli': true,
  104. 'dotted_salad': false, 'chocolate_cake': false, 'lime_leaf_salad': false, 'golden_apple': false,
  105. 'banana_jello': false, 'orange_pie': false, 'pancakes': false, 'coconut_stew': false, 'dragon_fruit_salad': false,
  106. 'potato_shake': false, 'carrot_shake': false, 'beet_shake': false, 'broccoli_shake': false
  107. },
  108. quick_deposit_combat: {
  109. "fighting_dust_potion": false, "feathers": true, "fire_feathers": true, "ice_feathers": true, "ancient_feathers": true,
  110. "string": true, "poison": true, "ant_needles": true, "molten_glass": true, "lantern": true,
  111. "flippers": true,"bone_amulet": true,"ashes_amulet": true,"ice_amulet": true,"blood_amulet": false,"amulet_of_healing_rain": true,
  112. "lizard_skin": true, "bat_skin": true, "bear_fur": true, "reaper_silk": true, "crocodile_hide": true, "frozen_crocodile_hide": false,
  113. "stinger": true, "iron_dagger": true, "skeleton_sword": true, "club": true, "spiked_club": true, "dense_club": false,
  114. "spiked_dense_club": false, "scythe": true, "double_scythe": false, "trident": true, "long_trident": false, "rapier": true,
  115. "gold_rapier": false, "skeleton_shield": true, "stinger_dagger": true, "long_spear": true,
  116. "long_bow": true, "haunted_bow": true, "balista": false, "toy_slingshot": true,
  117. "wooden_arrows": true, "fire_arrows": true, "ice_arrows": true, "ancient_arrows": false,
  118. "lizard_mask": true, "lizard_body": true, "lizard_legs": true, "lizard_gloves": true,"lizard_boots": true,
  119. "bat_mask": true,"bat_body": true,"bat_legs": true,"bat_gloves": true,"bat_boots": true,
  120. "bear_mask": true,"bear_body": true,"bear_legs": true,"bear_gloves": true,"bear_boots": true,
  121. "moonstone_mask": true,"moonstone_body": true,"moonstone_legs": true,"moonstone_gloves": true,"moonstone_boots": true,
  122. "crocodile_mask": true,"crocodile_body": true,"crocodile_legs": true,"crocodile_gloves": true,"crocodile_boots": true,
  123. "frozen_crocodile_mask": true,"frozen_crocodile_body": true,"frozen_crocodile_legs": true,"frozen_crocodile_gloves": true,"frozen_crocodile_boots": true,
  124. "dragon_helmet": false,"dragon_body": false,"dragon_legs": false,"dragon_gloves": false,"dragon_boots": false,
  125. "undead_staff": false,"undead_hp_staff": false,"undead_mana_staff": false,"undead_defence_staff": false,"undead_full_staff": false
  126. }
  127. }
  128. this.defaultSettings = this.settings
  129.  
  130. this.quickDepositIcons = {
  131. quick_deposit_ores: "https://cdn.idle-pixel.com/images/stone.png",
  132. quick_deposit_bars: "https://cdn.idle-pixel.com/images/bronze_bar.png",
  133. quick_deposit_seeds: "https://cdn.idle-pixel.com/images/dotted_green_leaf_seeds.png",
  134. quick_deposit_brewing_ingredients: "https://cdn.idle-pixel.com/images/dotted_green_leaf.png",
  135. quick_deposit_logs: "https://cdn.idle-pixel.com/images/logs.png",
  136. quick_deposit_raw: "https://cdn.idle-pixel.com/images/raw_chicken.png",
  137. quick_deposit_cooked: "https://cdn.idle-pixel.com/images/cooked_chicken.png",
  138. quick_deposit_cooking: "https://cdn.idle-pixel.com/images/chefs_hat.png",
  139. quick_deposit_combat: "https://cdn.idle-pixel.com/images/skeleton_sword.png",
  140. }
  141.  
  142. this.currentPopup = null;
  143.  
  144. this.overlay = document.createElement('div');
  145. this.overlay.id = 'newCardOverlayTeams';
  146. this.overlay.style.position = 'fixed';
  147. this.overlay.style.top = '0';
  148. this.overlay.style.left = '0';
  149. this.overlay.style.width = '100%';
  150. this.overlay.style.height = '100%';
  151. this.overlay.style.backgroundColor = 'rgba(0, 0, 0, 0.7)';
  152. this.overlay.style.zIndex = '1000';
  153. this.overlay.style.display = 'flex';
  154. this.overlay.style.justifyContent = 'center';
  155. this.overlay.style.alignItems = 'center';
  156. this.overlay.addEventListener('click', (event) => {
  157. if (event.target === this.overlay) {
  158. this.closePopup();
  159. }
  160. });
  161.  
  162. window.addEventListener('resize', this.adjustPopupPosition.bind(this));
  163.  
  164. this.storable_items = {'coins': 'Special', 'stardust': 'Special', 'fight_points': 'Special', 'energy': 'Special', 'criptoe': 'Special', 'donor_coins': 'Special', 'treasure_chest': 'Special', 'green_treasure_chest': 'Special', 'red_treasure_chest': 'Special', 'blue_pickaxe_orb': 'Special', 'blue_hammer_orb': 'Special', 'blue_woodcutting_orb': 'Special', 'blue_oil_storage_orb': 'Special', 'blue_oil_well_orb': 'Special', 'blue_farming_orb': 'Special', 'green_arrow_orb': 'Special', 'green_boat_orb': 'Special', 'green_bone_orb': 'Special', 'green_charcoal_orb': 'Special', 'green_log_orb': 'Special', 'red_farming_orb': 'Special', 'red_woodcutting_orb': 'Special', 'red_combat_orb': 'Special', 'red_oil_factory_orb': 'Special', 'red_stardust_watch_orb': 'Special', 'stone': 'Mining', 'copper': 'Mining', 'iron': 'Mining', 'silver': 'Mining', 'gold': 'Mining', 'promethium': 'Mining', 'titanium': 'Mining', 'ancient_ore': 'Mining', 'dragon_ore': 'Mining', 'moonstone': 'Mining', 'grey_geode': 'Mining', 'blue_geode': 'Mining', 'green_geode': 'Mining', 'red_geode': 'Mining', 'cyan_geode': 'Mining', 'ancient_geode': 'Mining', 'blue_marble_mineral': 'Mining', 'amethyst_mineral': 'Mining', 'sea_crystal_mineral': 'Mining', 'dense_marble_mineral': 'Mining', 'fluorite_mineral': 'Mining', 'clear_marble_mineral': 'Mining', 'jade_mineral': 'Mining', 'lime_quartz_mineral': 'Mining', 'opal_mineral': 'Mining', 'purple_quartz_mineral': 'Mining', 'amber_mineral': 'Mining', 'smooth_pearl_mineral': 'Mining', 'sulfer_mineral': 'Mining', 'topaz_mineral': 'Mining', 'tanzanite_mineral': 'Mining', 'magnesium_mineral': 'Mining', 'frozen_mineral': 'Mining', 'blood_crystal_mineral': 'Mining', 'sapphire': 'Mining', 'emerald': 'Mining', 'ruby': 'Mining', 'diamond': 'Mining', 'gathering_sapphire_fragments': 'Mining', 'gathering_emerald_fragments': 'Mining', 'gathering_ruby_fragments': 'Mining', 'gathering_diamond_fragments': 'Mining', 'bronze_bar': 'Crafting', 'iron_bar': 'Crafting', 'silver_bar': 'Crafting', 'gold_bar': 'Crafting', 'promethium_bar': 'Crafting', 'titanium_bar': 'Crafting', 'ancient_bar': 'Crafting', 'dragon_bar': 'Crafting', 'charcoal': 'Crafting', 'lava': 'Crafting', 'plasma': 'Crafting', 'junk': 'Gathering', 'gathering_loot_bag_mines': 'Gathering', 'gathering_loot_bag_fields': 'Gathering', 'gathering_loot_bag_forest': 'Gathering', 'gathering_loot_bag_fishing_pond': 'Gathering', 'gathering_loot_bag_gem_mine': 'Gathering', 'gathering_loot_bag_kitchen': 'Gathering', 'gathering_loot_bag_castle': 'Gathering', 'bones': 'Farming', 'big_bones': 'Farming', 'ashes': 'Farming', 'ice_bones': 'Farming', 'blood_bones': 'Farming', 'dotted_green_leaf_seeds': 'Farming', 'green_leaf_seeds': 'Farming', 'lime_leaf_seeds': 'Farming', 'gold_leaf_seeds': 'Farming', 'crystal_leaf_seeds': 'Farming', 'red_mushroom_seeds': 'Farming', 'stardust_seeds': 'Farming', 'mega_dotted_green_leaf_seeds': 'Farming', 'mega_green_leaf_seeds': 'Farming', 'mega_lime_leaf_seeds': 'Farming', 'mega_gold_leaf_seeds': 'Farming', 'mega_crystal_leaf_seeds': 'Farming', 'mega_red_mushroom_seeds': 'Farming', 'tree_seeds': 'Farming', 'oak_tree_seeds': 'Farming', 'willow_tree_seeds': 'Farming', 'apple_tree_seeds': 'Farming', 'maple_tree_seeds': 'Farming', 'banana_tree_seeds': 'Farming', 'stardust_tree_seeds': 'Farming', 'orange_tree_seeds': 'Farming', 'pine_tree_seeds': 'Farming', 'redwood_tree_seeds': 'Farming', 'palm_tree_seeds': 'Farming', 'dragon_fruit_tree_seeds': 'Farming', 'bone_tree_seeds': 'Farming', 'lava_tree_seeds': 'Farming', 'strange_tree_seeds': 'Farming', 'potato_seeds': 'Farming', 'carrot_seeds': 'Farming', 'beet_seeds': 'Farming', 'broccoli_seeds': 'Farming', 'dotted_green_leaf': 'Brewing', 'green_leaf': 'Brewing', 'lime_leaf': 'Brewing', 'gold_leaf': 'Brewing', 'crystal_leaf': 'Brewing', 'red_mushroom': 'Brewing', 'strange_leaf': 'Brewing', 'stranger_leaf': 'Brewing', 'strangest_leaf': 'Brewing', 'shooting_star': 'Brewing', 'blue_shooting_star': 'Brewing', 'green_shooting_star': 'Brewing', 'red_shooting_star': 'Brewing', 'seaweed': 'Brewing', 'logs': 'Woodcutting', 'oak_logs': 'Woodcutting', 'willow_logs': 'Woodcutting', 'maple_logs': 'Woodcutting', 'stardust_logs': 'Woodcutting', 'pine_logs': 'Woodcutting', 'redwood_logs': 'Woodcutting', 'dense_logs': 'Woodcutting', 'raw_chicken': 'Raw', 'raw_bird_meat': 'Raw', 'raw_meat': 'Raw', 'raw_shrimp': 'Raw', 'raw_anchovy': 'Raw', 'raw_sardine': 'Raw', 'raw_crab': 'Raw', 'raw_piranha': 'Raw', 'raw_salmon': 'Raw', 'raw_trout': 'Raw', 'raw_pike': 'Raw', 'raw_eel': 'Raw', 'raw_rainbow_fish': 'Raw', 'raw_tuna': 'Raw', 'raw_swordfish': 'Raw', 'raw_manta_ray': 'Raw', 'raw_shark': 'Raw', 'raw_whale': 'Raw', 'raw_small_stardust_fish': 'Raw', 'raw_medium_stardust_fish': 'Raw', 'raw_large_stardust_fish': 'Raw', 'raw_angler_fish': 'Raw', 'cooked_shrimp': 'Food', 'cooked_anchovy': 'Food', 'cooked_sardine': 'Food', 'cooked_crab': 'Food', 'cooked_piranha': 'Food', 'cooked_salmon': 'Food', 'cooked_trout': 'Food', 'cooked_pike': 'Food', 'cooked_eel': 'Food', 'cooked_rainbow_fish': 'Food', 'cooked_tuna': 'Food', 'cooked_swordfish': 'Food', 'cooked_manta_ray': 'Food', 'cooked_shark': 'Food', 'cooked_whale': 'Food', 'cooked_small_stardust_fish': 'Food', 'cooked_medium_stardust_fish': 'Food', 'cooked_large_stardust_fish': 'Food', 'cooked_angler_fish': 'Food', 'cooked_chicken': 'Food', 'cooked_bird_meat': 'Food', 'cooked_meat': 'Food', 'honey': 'Food', 'cheese': 'Food', 'apple': 'Food', 'maple_syrup': 'Food', 'banana': 'Food', 'orange': 'Food', 'maggots': 'Food', 'potato': 'Food', 'carrot': 'Food', 'beet': 'Food', 'broccoli': 'Food', 'coconut': 'Food', 'dragon_fruit': 'Food', 'egg': 'Food', 'chocolate': 'Food', 'dotted_salad': 'Food', 'chocolate_cake': 'Food', 'lime_leaf_salad': 'Food', 'golden_apple': 'Food', 'banana_jello': 'Food', 'orange_pie': 'Food', 'pancakes': 'Food', 'bait': 'Bait', 'super_bait': 'Bait', 'mega_bait': 'Bait', 'string': 'Drops', 'poison': 'Drops', 'ant_needles': 'Drops', 'molten_glass': 'Drops', 'lizard_skin': 'Drops', 'bat_skin': 'Drops', 'bear_fur': 'Drops', 'reaper_silk': 'Drops', 'crocodile_hide': 'Drops', 'frozen_crocodile_hide': 'Drops', 'green_gaurdian_key': 'Drops', 'blue_gaurdian_key': 'Drops', 'purple_gaurdian_key': 'Drops', 'mixed_gaurdian_key': 'Drops', 'feathers': 'Combat', 'fire_feathers': 'Combat', 'ice_feathers': 'Combat', 'ancient_feathers': 'Combat', 'wooden_arrows': 'Combat', 'fire_arrows': 'Combat', 'ice_arrows': 'Combat', 'ancient_arrows': 'Combat', 'stinger': 'Combat', 'iron_dagger': 'Combat', 'skeleton_sword': 'Combat', 'club': 'Combat', 'spiked_club': 'Combat', 'dense_club': 'Combat', 'spiked_dense_club': 'Combat', 'scythe': 'Combat', 'double_scythe': 'Combat', 'rapier': 'Combat', 'gold_rapier': 'Combat', 'stinger_dagger': 'Combat', 'long_spear': 'Combat', 'trident': 'Combat', 'long_trident': 'Combat', 'long_bow': 'Combat', 'toy_slingshot': 'Combat', 'haunted_bow': 'Combat', 'balista': 'Combat', 'skeleton_shield': 'Combat', 'lantern': 'Combat', 'undead_staff': 'Combat', 'undead_hp_staff': 'Combat', 'undead_mana_staff': 'Combat', 'undead_defence_staff': 'Combat', 'undead_full_staff': 'Combat', 'lizard_mask': 'Armour', 'lizard_body': 'Armour', 'lizard_legs': 'Armour', 'lizard_gloves': 'Armour', 'lizard_boots': 'Armour', 'bat_mask': 'Armour', 'bat_body': 'Armour', 'bat_legs': 'Armour', 'bat_gloves': 'Armour', 'bat_boots': 'Armour', 'bear_mask': 'Armour', 'bear_body': 'Armour', 'bear_legs': 'Armour', 'bear_gloves': 'Armour', 'bear_boots': 'Armour', 'moonstone_mask': 'Armour', 'moonstone_body': 'Armour', 'moonstone_legs': 'Armour', 'moonstone_gloves': 'Armour', 'moonstone_boots': 'Armour', 'crocodile_mask': 'Armour', 'crocodile_body': 'Armour', 'crocodile_legs': 'Armour', 'crocodile_gloves': 'Armour', 'crocodile_boots': 'Armour', 'frozen_crocodile_mask': 'Armour', 'frozen_crocodile_body': 'Armour', 'frozen_crocodile_legs': 'Armour', 'frozen_crocodile_gloves': 'Armour', 'frozen_crocodile_boots': 'Armour', 'dragon_helmet': 'Armour', 'dragon_body': 'Armour', 'dragon_legs': 'Armour', 'dragon_gloves': 'Armour', 'dragon_boots': 'Armour', 'flippers': 'Armour', 'bone_amulet': 'Armour', 'ashes_amulet': 'Armour', 'ice_amulet': 'Armour', 'blood_amulet': 'Armour', 'amulet_of_healing_rain': 'Armour', 'stardust_potion': 'Potions', 'energy_potion': 'Potions', 'anti_disease_potion': 'Potions', 'tree_speed_potion': 'Potions', 'smelting_upgrade_potion': 'Potions', 'great_stardust_potion': 'Potions', 'farming_speed_potion': 'Potions', 'rare_monster_potion': 'Potions', 'super_stardust_potion': 'Potions', 'gathering_unique_potion': 'Potions', 'heat_potion': 'Potions', 'bait_potion': 'Potions', 'bone_potion': 'Potions', 'furnace_speed_potion': 'Potions', 'promethium_potion': 'Potions', 'super_rare_monster_potion': 'Potions', 'ultra_stardust_potion': 'Potions', 'cooks_dust_potion': 'Potions', 'fighting_dust_potion': 'Potions', 'tree_dust_potion': 'Potions', 'farm_dust_potion': 'Potions', 'magic_shiny_crystal_ball_potion': 'Potions', 'birdhouse_potion': 'Potions', 'rocket_potion': 'Potions', 'titanium_potion': 'Potions', 'raids_hp_potion': 'Potions', 'blue_orb_potion': 'Potions', 'geode_potion': 'Potions', 'magic_crystal_ball_potion': 'Potions', 'stone_converter_potion': 'Potions', 'rain_potion': 'Potions', 'combat_loot_potion': 'Potions', 'raids_mana_potion': 'Potions', 'gathering_worker_potion': 'Potions', 'rotten_potion': 'Potions', 'merchant_speed_potion': 'Potions', 'ancient_potion': 'Potions', 'green_orb_potion': 'Potions', 'raids_crits_potion': 'Potions', 'guardian_key_potion': 'Potions', 'red_orb_potion': 'Potions'};
  165. this.storage_sections = ['Special', 'Mining', 'Crafting', 'Gathering', 'Farming', 'Brewing', 'Woodcutting', 'Raw', 'Food', 'Bait', 'Drops', 'Combat', 'Armour', 'Potions', 'Uncategorized'];
  166. this.initCustomCSS();
  167. }
  168.  
  169. initCustomCSS() {
  170. const css = `
  171. .teamsqol-storage-section {
  172. border: 1px solid black;
  173. background-color: white;
  174. padding: 10px 10px 0px 10px;
  175. margin-bottom: 10px;
  176. }
  177. .teamsqol-storage-section-title {
  178. margin-bottom: 10px;
  179. margin-left: 2px;
  180. font-weight: bold;
  181. cursor: pointer;
  182. }
  183. .teamsqol-storage-section-content {
  184. display: block;
  185. }
  186. .teamsqol-storage-section-content.zlefs-hidden {
  187. display: none;
  188. }
  189. `;
  190. const style = document.createElement('style');
  191. style.type = 'text/css';
  192. style.appendChild(document.createTextNode(css));
  193. document.head.appendChild(style);
  194. }
  195.  
  196. storableAsSections(items) {
  197. const organized = {};
  198.  
  199. for (const [item, type] of Object.entries(items)) {
  200. if (!organized[type]) {
  201. organized[type] = [];
  202. }
  203. organized[type].push(item);
  204. }
  205.  
  206. return organized;
  207. }
  208.  
  209. toggleSectionContent(event) {
  210. const sectionTitle = event.target;
  211. const sectionContent = sectionTitle.nextElementSibling;
  212. sectionContent.classList.toggle('zlefs-hidden');
  213. }
  214.  
  215. replaceRefreshTeamStorageData(){
  216. const self = this;
  217. Modals.refreshTeamStorageData = function(raw) {
  218. var dataArray = raw.split("~");
  219. var itemData = {};
  220. for (var i = 0; i < dataArray.length; i += 2) {
  221. var itemName = dataArray[i];
  222. var itemAmount = parseInt(dataArray[i + 1]);
  223. if (itemAmount > 0) {
  224. itemData[itemName] = itemAmount;
  225. }
  226. }
  227.  
  228. var sectionsHtml = {};
  229. self.storage_sections.forEach(section => {
  230. sectionsHtml[section] = `<div class='teamsqol-storage-section' id='section-${section}'><div class='teamsqol-storage-section-title'>${section}</div><div class='teamsqol-storage-section-content'>`;
  231. });
  232.  
  233. const organizedItems = self.storableAsSections(self.storable_items);
  234.  
  235. for (const [category, items] of Object.entries(organizedItems)) {
  236. items.forEach(itemName => {
  237. if (itemData[itemName]) {
  238. sectionsHtml[category] += `
  239. <div data-item-team-storage='${itemName}' onclick='Modals.clicksTeamStorageItem("${itemName}", ${itemData[itemName]})' class='team-trading-box-entry hover'>
  240. <img src='https://cdn.idle-pixel.com/images/${itemName}.png' />
  241. <span>${format_number(itemData[itemName])}</span>
  242. </div>`;
  243. }
  244. });
  245. }
  246.  
  247. // Handle uncategorized items
  248. Object.keys(itemData).forEach(itemName => {
  249. if (!self.storable_items[itemName]) {
  250. sectionsHtml['Uncategorized'] += `
  251. <div data-item-team-storage='${itemName}' onclick='Modals.clicksTeamStorageItem("${itemName}", ${itemData[itemName]})' class='team-trading-box-entry hover'>
  252. <img src='https://cdn.idle-pixel.com/images/${itemName}.png' />
  253. <span>${format_number(itemData[itemName])}</span>
  254. </div>`;
  255. }
  256. });
  257.  
  258. // Close all section divs and filter out empty sections
  259. var html = '';
  260. self.storage_sections.forEach(section => {
  261. sectionsHtml[section] += '</div></div>';
  262. if (sectionsHtml[section].includes('data-item-team-storage')) {
  263. html += sectionsHtml[section];
  264. }
  265. });
  266.  
  267. document.getElementById("team-storage-box-content").innerHTML = html;
  268.  
  269. // Add event listeners for toggling visibility
  270. const sectionTitles = document.querySelectorAll('.teamsqol-storage-section-title');
  271. sectionTitles.forEach(title => {
  272. title.addEventListener('click', self.toggleSectionContent);
  273. });
  274. };
  275. }
  276.  
  277.  
  278. onMessageReceived(message) {
  279. if(message.startsWith("TEAMS_STORAGE_DATA")){
  280. this.parseStorage(message.split("=")[1])
  281. }
  282. }
  283.  
  284. parseStorage(storage_string){
  285. this.team_storage = {}
  286. const data_array = storage_string.split("~")
  287. for (let i = 0; i<data_array.length - 1; i+=2) {
  288. this.team_storage[data_array[i]] = data_array[i+1]
  289. }
  290. }
  291.  
  292. onLogin() {
  293. this.teamStorageTopBar();
  294. this.replaceItemClickModal();
  295. this.loadSettings();
  296. this.applySettings();
  297. this.replaceRefreshTeamStorageData();
  298.  
  299. // Add scrollbar to storage log until Smitty fixes
  300. const storeLog = document.getElementById("team-stoage-logger-context");
  301. storeLog.style.maxHeight = "150px";
  302. storeLog.style.overflowY = "auto";
  303.  
  304. let autoScroll = true;
  305. let userScrolled = false;
  306. let reenableAutoScrollTimeout = null;
  307.  
  308. function teamLogScroll() {
  309. if (autoScroll && !userScrolled) {
  310. storeLog.scrollTop = storeLog.scrollHeight;
  311. }
  312. }
  313.  
  314. storeLog.addEventListener('scroll', () => {
  315. if (storeLog.scrollTop + storeLog.clientHeight >= storeLog.scrollHeight) {
  316. userScrolled = false;
  317. autoScroll = true;
  318. clearTimeout(reenableAutoScrollTimeout);
  319. } else {
  320. userScrolled = true;
  321. autoScroll = false;
  322. clearTimeout(reenableAutoScrollTimeout);
  323. reenableAutoScrollTimeout = setTimeout(() => {
  324. userScrolled = false;
  325. autoScroll = true;
  326. }, 5000);
  327. }
  328. });
  329.  
  330. const observer = new MutationObserver(() => {
  331. if (autoScroll && !userScrolled) {
  332. teamLogScroll();
  333. } else if (!userScrolled) {
  334. // When user scrolls manually, autoscroll will be disabled for the next 5 seconds
  335. setTimeout(teamLogScroll, 5000);
  336. }
  337. });
  338. observer.observe(storeLog, { childList: true });
  339. }
  340.  
  341.  
  342. replaceItemClickModal(){
  343. const self = this;
  344. Modals.clicksTeamStorageItem = function(item_var, amount) {
  345. const player_amount = window[`var_${item_var}`] || 0;
  346. self.newWithdrawPopup(item_var, amount, player_amount);
  347.  
  348. };
  349. }
  350.  
  351. loadSettings() {
  352. const user = window.var_username;
  353. const savedSettings = localStorage.getItem(`${user}_teamsqol_settings`);
  354. let needsSave = false;
  355.  
  356. if (savedSettings) {
  357. const parsedSettings = JSON.parse(savedSettings);
  358.  
  359. needsSave = this.updateQuickDepositSettings(parsedSettings) || needsSave;
  360.  
  361. const updateSettings = (defaultSettings, userSettings) => {
  362. const mergedSettings = {};
  363. for (const key in defaultSettings) {
  364. if (typeof defaultSettings[key] === 'object' && defaultSettings[key] !== null) {
  365. if (!userSettings[key] || typeof userSettings[key] !== 'object') {
  366. userSettings[key] = {};
  367. needsSave = true;
  368. }
  369. mergedSettings[key] = updateSettings(defaultSettings[key], userSettings[key]);
  370. } else {
  371. if (userSettings[key] === undefined) {
  372. userSettings[key] = defaultSettings[key];
  373. needsSave = true;
  374. }
  375. mergedSettings[key] = userSettings[key];
  376. }
  377. }
  378.  
  379. for (const key in userSettings) {
  380. if (!defaultSettings.hasOwnProperty(key)) {
  381. delete userSettings[key];
  382. needsSave = true;
  383. console.log(`Removing obsolete setting: ${key}`);
  384. }
  385. }
  386. return mergedSettings;
  387. };
  388.  
  389. this.settings = updateSettings(this.settings, parsedSettings);
  390.  
  391. if (needsSave) {
  392. this.saveSettings();
  393. }
  394. }
  395. }
  396.  
  397. updateQuickDepositSettings(parsedSettings) {
  398. const quickDepositKeys = Object.keys(this.settings).filter(key => key.startsWith('quick_deposit'));
  399. let needsSave = false;
  400.  
  401. quickDepositKeys.forEach(key => {
  402. const defaultQuickDepositSettings = this.settings[key];
  403. const userQuickDepositSettings = parsedSettings[key] || {};
  404.  
  405. for (const item in defaultQuickDepositSettings) {
  406. if (userQuickDepositSettings[item] === undefined) {
  407. userQuickDepositSettings[item] = defaultQuickDepositSettings[item];
  408. needsSave = true;
  409. }
  410. }
  411.  
  412. for (const item in userQuickDepositSettings) {
  413. if (!defaultQuickDepositSettings.hasOwnProperty(item)) {
  414. delete userQuickDepositSettings[item];
  415. needsSave = true;
  416. }
  417. }
  418.  
  419. parsedSettings[key] = userQuickDepositSettings;
  420. });
  421.  
  422. return needsSave;
  423. }
  424.  
  425. saveSettings() {
  426. const user = window.var_username;
  427. const saveSettingsOrdered = (defaultSettings, userSettings) => {
  428. const orderedSettings = {};
  429. for (const key in defaultSettings) {
  430. if (typeof defaultSettings[key] === 'object' && defaultSettings[key] !== null) {
  431. orderedSettings[key] = saveSettingsOrdered(defaultSettings[key], userSettings[key]);
  432. } else {
  433. orderedSettings[key] = userSettings[key];
  434. }
  435. }
  436. return orderedSettings;
  437. };
  438.  
  439. const orderedSettings = saveSettingsOrdered(this.settings, this.settings);
  440. localStorage.setItem(`${user}_teamsqol_settings`, JSON.stringify(orderedSettings));
  441. this.applySettings();
  442. }
  443.  
  444. resetSettings() {
  445. const user = window.var_username;
  446. localStorage.setItem(`${user}_teamsqol_settings`, JSON.stringify(this.defaultSettings));
  447. this.loadSettings();
  448. this.applySettings();
  449. }
  450.  
  451. applySettings() {
  452. const buttonMapping = {
  453. show_fight_points_buttons: 'fpQuickButtons',
  454. show_energy_buttons: 'energyQuickButtons',
  455. show_quick_deposit_all_button: 'quickDepositAllButton',
  456. };
  457.  
  458. for (const [setting, buttonId] of Object.entries(buttonMapping)) {
  459. const buttonElement = document.getElementById(buttonId);
  460. if (buttonElement) {
  461. buttonElement.style.display = this.settings[setting] ? 'flex' : 'none';
  462. }
  463. }
  464.  
  465. let anyTrue = false;
  466.  
  467. for (const category in this.settings.quick_deposit_visibility) {
  468. const button = document.getElementById(category);
  469. if (button) {
  470. button.style.display = this.settings.quick_deposit_visibility[category] ? 'block' : 'none';
  471. }
  472.  
  473. if (this.settings.quick_deposit_visibility[category]) {
  474. anyTrue = true;
  475. }
  476. }
  477.  
  478. const quickDepositButtons = document.getElementById('quickDepositButtons');
  479. if (quickDepositButtons) {
  480. quickDepositButtons.style.display = anyTrue ? 'flex' : 'none';
  481. }
  482. }
  483.  
  484. teamsSettingPopup() {
  485. const settingsPopupStyles = `
  486. <style>
  487. #teamqol-settingsPopup {
  488. display: flex;
  489. flex-direction: column;
  490. align-items: center;
  491. width: 100%;
  492. max-width: 440px;
  493. margin: 0 auto;
  494. background-color: #fff;
  495. border-radius: 8px;
  496. box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
  497. padding: 20px;
  498. box-sizing: border-box;
  499. position: relative;
  500. overflow-y: auto;
  501. max-height: 75vh;
  502. }
  503. #teamqol-settingsPopup .teamqol-settings-row {
  504. display: flex;
  505. width: 100%;
  506. margin-bottom: 10px;
  507. flex-wrap: wrap;
  508. }
  509. #teamqol-settingsPopup .teamqol-settings-col {
  510. flex: 1;
  511. box-sizing: border-box;
  512. padding: 10px;
  513. display: flex;
  514. flex-direction: column;
  515. align-items: center;
  516. }
  517. #teamqol-settingsPopup .teamqol-settings-button-container {
  518. display: flex;
  519. justify-content: center;
  520. width: 100%;
  521. }
  522. #teamqol-settingsPopup button {
  523. padding: 10px 20px;
  524. cursor: pointer;
  525. margin-top: 10px;
  526. }
  527. #teamqol-settingsPopup .teamqol-close-button {
  528. position: absolute;
  529. top: 10px;
  530. right: 10px;
  531. background: none;
  532. border: none;
  533. font-size: 10px;
  534. cursor: pointer;
  535. padding: 5px;
  536. }
  537. #teamqol-settingsPopup .teamqol-section-title {
  538. width: 100%;
  539. text-align: left;
  540. font-weight: bold;
  541. cursor: pointer;
  542. }
  543. #teamqol-settingsPopup .teamqol-setting-item {
  544. width: 100%;
  545. display: flex;
  546. justify-content: space-between;
  547. align-items: center;
  548. margin-bottom: 5px;
  549. }
  550. .teamqol-settings-section {
  551. border:1px solid black;
  552. background-color: white;
  553. padding: 10px 10px;
  554. width:400px;
  555. margin-top: 10px;
  556. }
  557. .teamqol-hidden {
  558. display: none;
  559. }
  560. </style>
  561. `;
  562.  
  563. document.head.insertAdjacentHTML('beforeend', settingsPopupStyles);
  564.  
  565. const popupBox = document.createElement('div');
  566. popupBox.id = 'teamqol-settingsPopup';
  567.  
  568. const titleDiv = document.createElement('div');
  569. titleDiv.className = "teamqol-settings-row";
  570. popupBox.appendChild(titleDiv);
  571.  
  572. const title = document.createElement('h5');
  573. title.textContent = 'Settings';
  574. title.className = "modal-title";
  575. title.style.textAlign = 'center';
  576. titleDiv.appendChild(title);
  577.  
  578. const closeButton = document.createElement('button');
  579. closeButton.textContent = '✖';
  580. closeButton.className = 'teamqol-close-button';
  581. closeButton.type = 'button';
  582. popupBox.appendChild(closeButton);
  583.  
  584. const settingsContent = document.createElement('div');
  585. settingsContent.className = 'teamqol-settings-row';
  586. popupBox.appendChild(settingsContent);
  587.  
  588. // Generate settings inputs
  589. for (const setting in this.settings) {
  590. if (typeof this.settings[setting] === 'object' && this.settings[setting] !== null) {
  591. const sectionDiv = document.createElement('div');
  592. sectionDiv.className = 'teamqol-settings-section';
  593.  
  594. const sectionTitle = document.createElement('div');
  595. sectionTitle.textContent = setting.replace(/_/g, ' ').replace(/\b\w/g, char => char.toUpperCase());
  596. sectionTitle.className = 'teamqol-section-title';
  597. sectionDiv.appendChild(sectionTitle);
  598.  
  599. const sectionContent = document.createElement('div');
  600. sectionContent.className = 'teamqol-section-content teamqol-hidden';
  601.  
  602. for (const item in this.settings[setting]) {
  603. const settingItemDiv = document.createElement('div');
  604. settingItemDiv.className = 'teamqol-setting-item';
  605.  
  606. const settingLabel = document.createElement('label');
  607. settingLabel.textContent = item.replace(/_/g, ' ').replace(/\b\w/g, char => char.toUpperCase());
  608. settingLabel.style.cursor = 'pointer'; // Add this line
  609. settingItemDiv.appendChild(settingLabel);
  610.  
  611. const settingInput = document.createElement('input');
  612. settingInput.type = 'checkbox';
  613. settingInput.checked = this.settings[setting][item];
  614. settingItemDiv.appendChild(settingInput);
  615.  
  616. settingLabel.addEventListener('click', () => {
  617. settingInput.checked = !settingInput.checked;
  618. this.settings[setting][item] = settingInput.checked;
  619. this.saveSettings();
  620. this.applySettings();
  621. });
  622.  
  623. settingInput.addEventListener('change', () => {
  624. this.settings[setting][item] = settingInput.checked;
  625. this.saveSettings();
  626. this.applySettings();
  627. });
  628.  
  629. sectionContent.appendChild(settingItemDiv);
  630. }
  631.  
  632. sectionDiv.appendChild(sectionContent);
  633.  
  634. sectionTitle.addEventListener('click', () => {
  635. sectionContent.classList.toggle('teamqol-hidden');
  636. });
  637.  
  638. settingsContent.appendChild(sectionDiv);
  639. } else {
  640. const settingItemDiv = document.createElement('div');
  641. settingItemDiv.className = 'teamqol-setting-item';
  642.  
  643. const settingLabel = document.createElement('label');
  644. settingLabel.textContent = setting.replace(/_/g, ' ').replace(/\b\w/g, char => char.toUpperCase());
  645. settingLabel.style.cursor = 'pointer'; // Add this line
  646. settingItemDiv.appendChild(settingLabel);
  647.  
  648. const settingInput = document.createElement('input');
  649. settingInput.type = typeof this.settings[setting] === 'boolean' ? 'checkbox' : 'number';
  650. if (typeof this.settings[setting] === 'boolean') {
  651. settingInput.checked = this.settings[setting];
  652. } else {
  653. settingInput.value = this.settings[setting];
  654. }
  655. if (typeof this.settings[setting] === 'number'){
  656. settingInput.max = 0;
  657. }
  658. settingItemDiv.appendChild(settingInput);
  659.  
  660. settingLabel.addEventListener('click', () => {
  661. if (settingInput.type === 'checkbox') {
  662. settingInput.checked = !settingInput.checked;
  663. this.settings[setting] = settingInput.checked;
  664. } else {
  665. settingInput.focus();
  666. }
  667. this.saveSettings();
  668. });
  669.  
  670. settingInput.addEventListener('change', () => {
  671. if (settingInput.type === 'checkbox') {
  672. this.settings[setting] = settingInput.checked;
  673. } else {
  674. this.settings[setting] = settingInput.value;
  675. }
  676. this.saveSettings();
  677. });
  678.  
  679. settingsContent.appendChild(settingItemDiv);
  680. }
  681. }
  682.  
  683. const actions = [
  684. {
  685. button: closeButton,
  686. handler: () => {
  687. this.closePopup();
  688. },
  689. closeOnAction: true
  690. }
  691. ];
  692.  
  693. this.launchPopup(popupBox, actions);
  694. }
  695.  
  696. newWithdrawPopup(item_var, amount, player_amount) {
  697. const teamsPopupStyles = `
  698. <style>
  699. #teamsPopup {
  700. display: flex;
  701. flex-direction: column;
  702. align-items: center;
  703. width: 100%;
  704. max-width: 500px;
  705. margin: 0 auto;
  706. background-color: #fff;
  707. border-radius: 8px;
  708. box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
  709. padding: 20px;
  710. box-sizing: border-box;
  711. position: relative;
  712. }
  713. #teamsPopup .teamsPopup-row {
  714. display: flex;
  715. width: 100%;
  716. margin-bottom: 10px;
  717. }
  718. #teamsPopup .teamsPopup-col {
  719. flex: 1;
  720. box-sizing: border-box;
  721. padding: 10px;
  722. display: flex;
  723. flex-direction: column;
  724. align-items: center;
  725. }
  726. #teamsPopup .teamsPopup-deposit-container,
  727. #teamsPopup .teamsPopup-withdraw-container {
  728. display: flex;
  729. flex-direction: column;
  730. align-items: center;
  731. }
  732. #teamsPopup .teamsPopup-button-container {
  733. display: flex;
  734. justify-content: center;
  735. width: 100%;
  736. }
  737. #teamsPopup button {
  738. padding: 10px 20px;
  739. cursor: pointer;
  740. margin-top: 10px;
  741. }
  742. #teamsPopup .deposit-button {
  743. background-color: red;
  744. color: white;
  745. }
  746. #teamsPopup .withdraw-button {
  747. background-color: green;
  748. color: white;
  749. }
  750. #teamsPopup input {
  751. margin: 10px 0;
  752. }
  753. #teamsPopup .vertical-divider {
  754. width: 1px;
  755. background-color: #ccc;
  756. margin: 0 20px;
  757. }
  758. #teamsPopup .close-button {
  759. position: absolute;
  760. top: 10px;
  761. right: 10px;
  762. background: none;
  763. border: none;
  764. font-size: 10x;
  765. cursor: pointer;
  766. padding: 5px;
  767. }
  768. </style>
  769. `;
  770.  
  771. document.head.insertAdjacentHTML('beforeend', teamsPopupStyles);
  772.  
  773. const popupBox = document.createElement('div');
  774. popupBox.id = 'teamsPopup';
  775.  
  776. const titleDiv = document.createElement('div');
  777. titleDiv.className = "teamsPopup-row";
  778. popupBox.appendChild(titleDiv);
  779.  
  780. const title = document.createElement('h5');
  781. title.textContent = item_var.replace(/_/g, ' ').replace(/\b\w/g, char => char.toUpperCase());
  782. title.className = "modal-title";
  783. title.style.textAlign = 'center';
  784. titleDiv.appendChild(title);
  785.  
  786. const closeButton = document.createElement('button');
  787. closeButton.textContent = '✖';
  788. closeButton.className = 'close-button';
  789. closeButton.type = 'button';
  790. popupBox.appendChild(closeButton);
  791.  
  792. const rowDiv = document.createElement('div');
  793. rowDiv.className = 'teamsPopup-row';
  794. popupBox.appendChild(rowDiv);
  795.  
  796. const depositColDiv = document.createElement('div');
  797. depositColDiv.className = 'teamsPopup-col teamsPopup-deposit-container';
  798. rowDiv.appendChild(depositColDiv);
  799.  
  800. const divider = document.createElement('div');
  801. divider.className = 'vertical-divider';
  802. rowDiv.appendChild(divider);
  803.  
  804. const withdrawColDiv = document.createElement('div');
  805. withdrawColDiv.className = 'teamsPopup-col teamsPopup-withdraw-container';
  806. rowDiv.appendChild(withdrawColDiv);
  807.  
  808. const depositLabel = document.createElement('label');
  809. depositLabel.textContent = 'Deposit Amount';
  810. depositColDiv.appendChild(depositLabel);
  811.  
  812. const depositInput = document.createElement('input');
  813. depositInput.type = 'number';
  814. depositInput.max = player_amount;
  815. depositInput.min = 0;
  816. depositInput.className = 'storage-control';
  817. depositInput.id = 'depositAmount';
  818. depositInput.value = player_amount;
  819. depositColDiv.appendChild(depositInput);
  820.  
  821. const depositButton = document.createElement('button');
  822. depositButton.textContent = 'DEPOSIT';
  823. depositButton.className = 'btn btn-secondary deposit-button';
  824. depositColDiv.appendChild(depositButton);
  825.  
  826. const withdrawLabel = document.createElement('label');
  827. withdrawLabel.textContent = 'Withdraw Amount';
  828. withdrawColDiv.appendChild(withdrawLabel);
  829.  
  830. let withdraw_amount = amount;
  831. if (item_var == "fight_points"){
  832. const fight_points = window.var_fight_points || 0;
  833. const max_fight_points = window.var_max_fight_points || 0;
  834. withdraw_amount = Math.max(0, (max_fight_points - fight_points) - 10);
  835.  
  836. }
  837.  
  838. const withdrawInput = document.createElement('input');
  839. withdrawInput.type = 'number';
  840. withdrawInput.max = amount;
  841. withdrawInput.min = 0;
  842. withdrawInput.className = 'storage-control';
  843. withdrawInput.id = 'withdrawAmount';
  844. withdrawInput.value = withdraw_amount;
  845. withdrawColDiv.appendChild(withdrawInput);
  846.  
  847. const withdrawButton = document.createElement('button');
  848. withdrawButton.textContent = 'WITHDRAW';
  849. withdrawButton.className = 'btn btn-secondary withdraw-button';
  850. withdrawColDiv.appendChild(withdrawButton);
  851.  
  852. const actions = [
  853. {
  854. button: depositButton,
  855. handler: () => {
  856. // console.log("Pressed deposit button");
  857. const store_amount = depositInput.value;
  858. websocket.send(`TEAM_STORE_ITEM=${item_var}~${store_amount}`);
  859. }
  860. },
  861. {
  862. button: withdrawButton,
  863. handler: () => {
  864. // console.log("Pressed withdraw button");
  865. let take_amount = withdrawInput.value;
  866. websocket.send(`TEAM_TAKE_ITEM=${item_var}~${take_amount}`);
  867. }
  868. },
  869. {
  870. button: closeButton,
  871. handler: () => {
  872. this.closePopup();
  873. },
  874. closeOnAction: true
  875. }
  876. ];
  877.  
  878. this.launchPopup(popupBox, actions);
  879. }
  880.  
  881. launchPopup(popup, actions) {
  882. if (this.currentPopup) {
  883. if (this.overlay.contains(this.currentPopup)) {
  884. this.overlay.removeChild(this.currentPopup);
  885. }
  886. this.currentPopup = null;
  887. }
  888.  
  889. this.currentPopup = popup;
  890.  
  891. this.overlay.appendChild(popup);
  892. document.body.appendChild(this.overlay);
  893.  
  894. this.adjustPopupPosition();
  895.  
  896. actions.forEach(action => {
  897. const button = action.button;
  898. button.addEventListener('click', () => {
  899. action.handler();
  900. if (action.closeOnAction !== false) {
  901. this.closePopup();
  902. }
  903. });
  904. });
  905. }
  906.  
  907. adjustPopupPosition() {
  908. if (!this.currentPopup) return;
  909.  
  910. const viewportHeight = window.innerHeight;
  911. const popupHeight = this.currentPopup.offsetHeight;
  912. const scrollOffset = window.pageYOffset || document.documentElement.scrollTop;
  913. const topPosition = (viewportHeight - popupHeight) / 2 + scrollOffset;
  914. this.currentPopup.style.position = 'absolute';
  915. this.currentPopup.style.top = `${topPosition > 0 ? topPosition : 0}px`;
  916. }
  917.  
  918. closePopup() {
  919. if (this.currentPopup && this.overlay.contains(this.currentPopup)) {
  920. this.overlay.removeChild(this.currentPopup);
  921. this.currentPopup = null;
  922. }
  923. if (document.body.contains(this.overlay)) {
  924. document.body.removeChild(this.overlay);
  925. }
  926. }
  927.  
  928. teamStorageTopBar(){
  929. const teamTradingBox = document.querySelector('.team-trading-box');
  930.  
  931. const container = document.createElement('div');
  932. container.className = 'container';
  933.  
  934. const row1 = document.createElement('div');
  935. row1.className = 'row';
  936. row1.style.marginBottom = '5px';
  937.  
  938. // Column 1 - "Team Storage" & "Add items"
  939. const col1 = document.createElement('div');
  940. col1.className = 'col';
  941. col1.style.flex = "0 0 auto";
  942. col1.style.width = "auto";
  943. col1.innerHTML = `
  944. <div class="font-large" style="color: rgb(175, 131, 14);">Team Storage</div>
  945. <div><u id="add-item-teams-label" onclick="Modals.clicksAddItemTeamStorage()" class="color-grey hover" style="color: rgb(56, 41, 241);">Add Item</u></div>
  946. <div id="remember-storage-take-div" class="color-grey hover" style="float: right; color: rgb(56, 41, 241);" onclick="Modals.clicksRememberTakeFromStore()"></div>
  947. `;
  948.  
  949. // Column 2 - Everything plugin related
  950. const col2 = document.createElement('div');
  951. col2.className = 'col';
  952. col2.style.display = "flex";
  953. col2.style.alignItems = "center";
  954. col2.style.marginLeft = "10px";
  955.  
  956. this.quickButtons(col2);
  957.  
  958. // Column 3 - Search bar and settings button
  959. const col3 = document.createElement('div');
  960. col3.className = 'col';
  961. col3.style.maxWidth = "150px";
  962. col3.style.minWidth = "150px";
  963. col3.style.display = "flex";
  964. col3.style.flexDirection = "column";
  965. col3.style.alignItems = "flex-end";
  966.  
  967. // Settings button
  968. const settingsButton = document.createElement('button');
  969. settingsButton.textContent = 'Teams QoL Settings';
  970. settingsButton.style.border = 'none';
  971. settingsButton.style.background = 'none';
  972. settingsButton.style.cursor = 'pointer';
  973. settingsButton.style.padding = '0';
  974. settingsButton.style.width = '150px';
  975. settingsButton.style.height = '30px';
  976. settingsButton.style.alignSelf = 'flex-end';
  977.  
  978. settingsButton.addEventListener('click', () => this.teamsSettingPopup());
  979. col3.appendChild(settingsButton);
  980.  
  981. // Search bar
  982. const searchBar = document.createElement('input');
  983. searchBar.type = "text";
  984. searchBar.onkeyup = function() { Modals.searchTeamStorageKeyPress(this) };
  985. searchBar.style.maxWidth = "150px";
  986. searchBar.style.maxHeight = "28px";
  987. searchBar.style.marginTop = '10px'; // Adds some space between the button and search bar
  988. searchBar.placeholder = "Search Storage";
  989.  
  990. col3.appendChild(searchBar);
  991.  
  992.  
  993. row1.appendChild(col1);
  994. row1.appendChild(col2);
  995. row1.appendChild(col3);
  996.  
  997. container.appendChild(row1);
  998.  
  999. const row2 = document.createElement('div');
  1000. row2.className = 'row';
  1001.  
  1002. const teamStorageBoxContent = document.getElementById('team-storage-box-content');
  1003. if (teamStorageBoxContent) {
  1004. row2.appendChild(teamStorageBoxContent);
  1005. }
  1006.  
  1007. container.appendChild(row2);
  1008.  
  1009. teamTradingBox.innerHTML = '';
  1010. teamTradingBox.appendChild(container);
  1011. }
  1012.  
  1013. quickButtons(col2) {
  1014. // FP Buttons
  1015. const fpButtonContainer = document.createElement('div');
  1016. fpButtonContainer.style.display = 'flex';
  1017. fpButtonContainer.style.alignItems = 'center';
  1018. fpButtonContainer.id = 'fpQuickButtons'
  1019.  
  1020. const fpUrl = "https://cdn.idle-pixel.com/images/fight_points.png";
  1021. const withdrawFPButton = this.createLargeButton('Withdraw fight points', fpUrl, 'green', () => this.withdrawFightPoints());
  1022. const depositFPButton = this.createLargeButton('Deposit fight points', fpUrl, 'red', () => this.depositFightPoints(), true);
  1023.  
  1024. fpButtonContainer.appendChild(depositFPButton);
  1025. fpButtonContainer.appendChild(withdrawFPButton);
  1026. col2.appendChild(fpButtonContainer);
  1027.  
  1028. // Energy Buttons
  1029. const energyButtonContainer = document.createElement('div');
  1030. energyButtonContainer.style.display = 'flex';
  1031. energyButtonContainer.style.alignItems = 'center';
  1032. energyButtonContainer.id = 'energyQuickButtons'
  1033.  
  1034. const energyUrl = "https://cdn.idle-pixel.com/images/energy.png";
  1035. const withdrawEnergyButton = this.createLargeButton('Withdraw energy points', energyUrl, 'green', () => this.withdrawEnergy());
  1036. const depositEnergyButton = this.createLargeButton('Deposit energy points', energyUrl, 'red', () => this.depositEnergy(), true);
  1037.  
  1038. energyButtonContainer.appendChild(depositEnergyButton);
  1039. energyButtonContainer.appendChild(withdrawEnergyButton);
  1040. col2.appendChild(energyButtonContainer);
  1041.  
  1042. // Quick Deposit All Button
  1043. const quickDepositButtonContainer = document.createElement('div');
  1044. quickDepositButtonContainer.style.display = 'flex';
  1045. quickDepositButtonContainer.style.alignItems = 'center';
  1046. quickDepositButtonContainer.id = 'quickDepositAllButtonContainer';
  1047.  
  1048. const quickDepositUrl = "https://cdn.idle-pixel.com/images/treasure_chest.png";
  1049. const quickDepositAllButton = this.createLargeButton('Quick Deposit All', quickDepositUrl, 'red', () => this.quickDepositAll(), true);
  1050. quickDepositAllButton.id = 'quickDepositAllButton';
  1051.  
  1052. quickDepositButtonContainer.appendChild(quickDepositAllButton);
  1053. col2.appendChild(quickDepositButtonContainer);
  1054.  
  1055. // Quick Deposit Buttons
  1056. const quickDepositContainer = document.createElement('div');
  1057. quickDepositContainer.style.display = 'flex';
  1058. quickDepositContainer.style.flexDirection = 'column';
  1059. quickDepositContainer.style.alignItems = 'center';
  1060. quickDepositContainer.style.marginLeft = '10px';
  1061. quickDepositContainer.style.paddingBottom = '10px';
  1062. quickDepositContainer.style.alignItems = 'flex-start';
  1063. quickDepositContainer.id = "quickDepositButtons";
  1064.  
  1065. const quickDepositTitle = document.createElement('div');
  1066. quickDepositTitle.textContent = 'Quick Deposit';
  1067. quickDepositTitle.style.marginBottom = '5px';
  1068. quickDepositTitle.style.textAlign = 'left';
  1069. quickDepositContainer.appendChild(quickDepositTitle);
  1070.  
  1071. const quickDepositIconsContainer = document.createElement('div');
  1072. quickDepositIconsContainer.style.display = 'flex';
  1073. quickDepositIconsContainer.style.flexWrap = 'wrap';
  1074. quickDepositIconsContainer.style.gap = '5px';
  1075.  
  1076. for (const [category, iconUrl] of Object.entries(this.quickDepositIcons)) {
  1077. const iconButton = this.createQuickDepositButton(category, iconUrl);
  1078. quickDepositIconsContainer.appendChild(iconButton);
  1079. }
  1080.  
  1081. quickDepositContainer.appendChild(quickDepositIconsContainer);
  1082. col2.appendChild(quickDepositContainer);
  1083. }
  1084.  
  1085.  
  1086. createLargeButton(altText, image_url, arrowColor, clickHandler, isDeposit = false) {
  1087. const button = document.createElement("button");
  1088. button.alt = altText;
  1089. button.style.border = "none";
  1090. button.style.background = "none";
  1091. button.style.cursor = "pointer";
  1092. button.style.position = "relative";
  1093. button.style.marginRight = isDeposit ? '5px' : '0';
  1094. button.title = altText;
  1095. // Giving up on trying to display alt text on buttons, image takes over like a prick
  1096. const img = document.createElement("img");
  1097. img.src = image_url;
  1098. img.style.width = "50px";
  1099. img.style.height = "50px";
  1100.  
  1101. const arrow = document.createElement("div");
  1102. arrow.innerHTML = this.svgArrow(arrowColor, 30, isDeposit ? "down" : "up");
  1103. arrow.style.position = "absolute";
  1104. arrow.style.bottom = "0";
  1105. arrow.style.right = "0";
  1106. arrow.title = altText;
  1107.  
  1108. button.appendChild(img);
  1109. button.appendChild(arrow);
  1110. button.addEventListener("click", clickHandler);
  1111.  
  1112. return button;
  1113. }
  1114.  
  1115. createQuickDepositButton(category, iconUrl) {
  1116. const button = document.createElement("button");
  1117. button.alt = `Quick deposit ${category}`;
  1118. button.style.border = "none";
  1119. button.style.background = "none";
  1120. button.style.cursor = "pointer";
  1121. button.style.position = "relative";
  1122. button.id = category;
  1123.  
  1124. if (!this.settings.quick_deposit_visibility[category]) {
  1125. button.style.display = 'none';
  1126. }
  1127.  
  1128. let imgWidth = "30px";
  1129. let imgHeight = "30px";
  1130.  
  1131. if (category == "quick_deposit_cooking"){
  1132. imgWidth = "22px";
  1133. imgHeight = "22px";
  1134. }
  1135.  
  1136. const img = document.createElement("img");
  1137. img.src = iconUrl;
  1138. img.style.width = imgWidth;
  1139. img.style.height = imgHeight;
  1140.  
  1141. const arrow = document.createElement("div");
  1142. arrow.innerHTML = this.svgArrow("red", 20, "down");
  1143. arrow.style.position = "absolute";
  1144. arrow.style.bottom = "0";
  1145. arrow.style.right = "0";
  1146.  
  1147. button.appendChild(img);
  1148. button.appendChild(arrow);
  1149. button.addEventListener("click", () => this.quickDeposit(category));
  1150.  
  1151. return button;
  1152. }
  1153.  
  1154. quickDeposit(category) {
  1155. const items = this.settings[category];
  1156. let bulkStoreString = '';
  1157. if (category == "quick_deposit_combat" && this.settings.include_equipped_gear_in_quick_deposit){
  1158. websocket.send("UNEQUIP_ALL");
  1159. }
  1160.  
  1161. for (const item in items) {
  1162. if (items[item]) {
  1163. const amount = window[`var_${item}`] || 0;
  1164. if (amount > 0) {
  1165. bulkStoreString += `${item}~${amount}~`;
  1166. }
  1167. }
  1168. }
  1169.  
  1170. if (bulkStoreString) {
  1171. this.queue.push(bulkStoreString.slice(0, -1)); // Remove trailing '~' and add to queue
  1172. this.processQueue();
  1173. }
  1174. }
  1175.  
  1176. processQueue() {
  1177. if (this.processingQueue) return;
  1178.  
  1179. const processNext = () => {
  1180. if (this.queue.length === 0) {
  1181. this.processingQueue = false;
  1182. return;
  1183. }
  1184.  
  1185. this.processingQueue = true;
  1186. const bulkStoreString = this.queue.shift();
  1187. websocket.send(`TEAM_BULK_STORE_ITEMS=${bulkStoreString}`);
  1188. // console.log(`TEAM_BULK_STORE_ITEMS=${bulkStoreString}`);
  1189.  
  1190. // Minimum delay of 200ms
  1191. setTimeout(() => {
  1192. processNext();
  1193. }, 200);
  1194. };
  1195.  
  1196. processNext();
  1197. }
  1198.  
  1199. quickDepositAll() {
  1200. const button = document.getElementById('quickDepositAllButton');
  1201. button.disabled = true;
  1202. setTimeout(() => {
  1203. button.disabled = false;
  1204. }, 2000);
  1205.  
  1206. let bulkStoreString = '';
  1207. const categories = Object.keys(this.settings.quick_deposit_visibility);
  1208. for (const category of categories) {
  1209. const items = this.settings[category];
  1210. for (const item in items) {
  1211. if (items[item]) {
  1212. const amount = window[`var_${item}`] || 0;
  1213. if (amount > 0) {
  1214. bulkStoreString += `${item}~${amount}~`;
  1215. }
  1216. }
  1217. }
  1218. }
  1219.  
  1220. if (bulkStoreString) {
  1221. websocket.send(`TEAM_BULK_STORE_ITEMS=${bulkStoreString.slice(0, -1)}`);
  1222. // console.log(`TEAM_BULK_STORE_ITEMS=${bulkStoreString.slice(0, -1)}`);
  1223. }
  1224. }
  1225.  
  1226.  
  1227. withdrawFightPoints() {
  1228. const fight_points = window.var_fight_points || 0;
  1229. const max_fight_points = window.var_max_fight_points || 0;
  1230. const fight_points_needed = Math.max(0, (max_fight_points - fight_points) - Math.abs(this.settings.fight_points_buffer));
  1231. if (this.team_storage.fight_points >= fight_points_needed){
  1232. // console.log(`TEAM_TAKE_ITEM=fight_points~${fight_points_needed}`)
  1233. websocket.send(`TEAM_TAKE_ITEM=fight_points~${fight_points_needed}`);
  1234. } else if (this.team_storage.fight_points > 0){
  1235. // console.log(`TEAM_TAKE_ITEM=fight_points~${this.team_storage.fight_points}`)
  1236. websocket.send(`TEAM_TAKE_ITEM=fight_points~${this.team_storage.fight_points}`);
  1237. }
  1238. }
  1239.  
  1240. depositFightPoints() {
  1241. const fight_points = window.var_fight_points || 0;
  1242. websocket.send(`TEAM_STORE_ITEM=fight_points~${fight_points}`);
  1243. }
  1244.  
  1245. withdrawEnergy() {
  1246. websocket.send(`TEAM_TAKE_ITEM=energy~${this.team_storage.energy}`);
  1247. }
  1248.  
  1249. depositEnergy() {
  1250. const energy = window.var_energy || 0;
  1251. websocket.send(`TEAM_STORE_ITEM=energy~${energy}`);
  1252. }
  1253.  
  1254. svgArrow(color, size, direction = "up") {
  1255. let rotation;
  1256. switch (direction) {
  1257. case "up":
  1258. case 0:
  1259. rotation = 0;
  1260. break;
  1261. case "down":
  1262. case 180:
  1263. rotation = 180;
  1264. break;
  1265. case "left":
  1266. case 270:
  1267. rotation = 270;
  1268. break;
  1269. case "right":
  1270. case 90:
  1271. rotation = 90;
  1272. break;
  1273. default:
  1274. rotation = parseInt(direction) || 0;
  1275. }
  1276.  
  1277. return `
  1278. <svg width="${size}" height="${size}" viewBox="0 0 16 16" fill="${color}" xmlns="http://www.w3.org/2000/svg" style="transform: rotate(${rotation}deg);">
  1279. <path d="M14.13 9.11h-12l6-7 6 7z"/>
  1280. <path d="M6.12 8h4v6h-4z" fill="${color}"/>
  1281. </svg>`;
  1282. }
  1283.  
  1284. }
  1285.  
  1286. const plugin = new TeamsQoL();
  1287. IdlePixelPlus.registerPlugin(plugin);
  1288.  
  1289. })();