diff --git a/SETTINGS.lua b/SETTINGS.lua index 48f2d1d..fcaaeee 100644 --- a/SETTINGS.lua +++ b/SETTINGS.lua @@ -37,6 +37,7 @@ skywars_settings.build_permission = "build" -- HUDS SETTINGS -- + -- Real coordinates: -- a unit of measurement which is roughly around 64 pixels, but -- varies based on the screen density and scaling settings of the client. @@ -71,6 +72,44 @@ skywars_settings.buttons_width = 1.8 -- The buttons height in real coordinates. skywars_settings.buttons_height = 1.6 +-- The items importances that are used by the auto equip system: +-- when a player takes an item from a chest, if it has a greater +-- importance and it's in the same group of the one in the hotbar, +-- the latter gets replaced. +skywars_settings.items_importances = { + pickaxe = { + ["default:pick_wood"] = 0, + ["default:pick_stone"] = 1, + ["default:pick_bronze"] = 2, + ["default:pick_steel"] = 3, + ["default:pick_diamond"] = 4, + ["default:pick_mese"] = 5, + }, + sword = { + ["default:sword_wood"] = 0, + ["default:sword_stone"] = 1, + ["default:sword_bronze"] = 2, + ["default:sword_steel"] = 3, + ["default:sword_diamond"] = 4, + ["default:sword_mese"] = 5, + }, + shovel = { + ["default:shovel_wood"] = 0, + ["default:shovel_stone"] = 1, + ["default:shovel_bronze"] = 2, + ["default:shovel_steel"] = 3, + ["default:shovel_diamond"] = 4, + ["default:shovel_mese"] = 5, + }, + axe = { + ["default:axe_wood"] = 0, + ["default:axe_stone"] = 1, + ["default:axe_bronze"] = 2, + ["default:axe_steel"] = 3, + ["default:axe_diamond"] = 4, + ["default:axe_mese"] = 5, + } +} @@ -91,7 +130,7 @@ skywars_settings.remove_armors_on_join = true -- The armors importances that are used by the auto equip system: -- when a player takes an armor from a chest, if it has a greater --- importance that the already equipped one the latter gets replaced. +-- importance that the already equipped one, the latter gets replaced. -- If the armor name contains one of this materials then the -- corresponding importance will be associated with it. skywars_settings.armors_importances = { diff --git a/_compatible_mods/3d_armor/auto_equip_armors.lua b/_compatible_mods/3d_armor/auto_equip_armors.lua new file mode 100644 index 0000000..2cb7caa --- /dev/null +++ b/_compatible_mods/3d_armor/auto_equip_armors.lua @@ -0,0 +1,79 @@ +local function get_armor_importance() end +local on_punch = minetest.registered_entities["__builtin:item"].on_punch + + +function skywars.auto_equip_armor(player, armor_itemstack) + local armor_name = armor_itemstack:get_name() + local armor_element = armor:get_element(armor_name) + -- Returning if it isn't an armor. + if not armor_element then return end + -- A table containing pairs of [armor_element : string] = armor_name : string. + local player_armor_elements = armor:get_weared_armor_elements(player) + local equipped_armor = player_armor_elements[armor_element] + local inventory = player:get_inventory() + + if equipped_armor then + local armor_importance = get_armor_importance(armor_name) + local weared_armor_importance = get_armor_importance(equipped_armor) + + if not armor_importance or not weared_armor_importance then return false end + + -- Returning if the just taken armor is worse or as good as the equipped one. + if armor_importance <= weared_armor_importance then return end + end + + armor:equip(player, armor_itemstack) + + return true +end + + + +-- Applying the auto equip system when the player takes an armor from an inventory. +minetest.register_on_player_inventory_action(function(player, action, inventory, inventory_info) + local pl_name = player:get_player_name() + + if minetest.get_modpath("3d_armor") and arena_lib.is_player_in_arena(pl_name, "skywars") then + if action == "put" then + local armor_itemstack = inventory_info.stack + local armor_name = armor_itemstack:get_name() + if not armor_itemstack then return end + + if skywars.auto_equip_armor(player, armor_itemstack) then + minetest.after(0, function() + inventory:remove_item("main", ItemStack(armor_name)) + end) + end + end + end +end) + + + +-- Applying the auto equip system when somenone punches on a drop. +minetest.registered_entities["__builtin:item"].on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, dir) + local pos = self.object:get_pos() + local pl_name = puncher:get_player_name() + local arena = skywars.get_arena_by_pos(pos) + + if minetest.get_modpath("3d_armor") and arena_lib.is_player_in_arena(pl_name, "skywars") then + local item = ItemStack(self.itemstring) + + if skywars.auto_equip_armor(puncher, item) then + self.object:remove() + return + end + end + + on_punch(self, puncher, time_from_last_punch, tool_capabilities, dir) +end + + + +function get_armor_importance(armor_name) + for material, importance in pairs(skywars_settings.armors_importances) do + if armor_name:match(material) then + return importance + end + end +end \ No newline at end of file diff --git a/_compatible_mods/3d_armor/init_3d_armor.lua b/_compatible_mods/3d_armor/init_3d_armor.lua index 56a80da..0ef83ef 100644 --- a/_compatible_mods/3d_armor/init_3d_armor.lua +++ b/_compatible_mods/3d_armor/init_3d_armor.lua @@ -1,7 +1,3 @@ -local function get_armor_importance() end -local on_punch = minetest.registered_entities["__builtin:item"].on_punch - - minetest.register_on_joinplayer(function(player) if skywars_settings.remove_armors_on_join and minetest.get_modpath("3d_armor") then minetest.after(5, function() armor:remove_all(player) end) @@ -18,81 +14,4 @@ end -function skywars.auto_equip(player, armor_itemstack) - local armor_name = armor_itemstack:get_name() - local armor_element = armor:get_element(armor_name) - -- A table containing pairs of [armor_element : string] = armor_name : string. - local player_armor_elements = armor:get_weared_armor_elements(player) - local equipped_armor = player_armor_elements[armor_element] - local inventory = player:get_inventory() - - if equipped_armor then - local armor_importance = get_armor_importance(armor_name) - local weared_armor_importance = get_armor_importance(equipped_armor) - - if not armor_importance or not weared_armor_importance then return false end - - -- Returning if the just taken armor is worse or as good as the equipped one. - if armor_importance <= weared_armor_importance then return end - end - - armor:equip(player, armor_itemstack) - - return true -end - - - -minetest.register_on_player_inventory_action(function(player, action, inventory, inventory_info) - local pl_name = player:get_player_name() - - if minetest.get_modpath("3d_armor") and arena_lib.is_player_in_arena(pl_name, "skywars") then - -- The armor that the player's taking. - local armor_itemstack = inventory_info.stack - if not armor_itemstack then return end - local armor_name = armor_itemstack:get_name() - -- The body part that the armor's assigned to, returns nil if it's not an armor. - local is_an_armor = armor:get_element(armor_name) - - if action == "put" and is_an_armor then - if skywars.auto_equip(player, armor_itemstack) then - minetest.after(0, function() - inventory:remove_item("main", ItemStack(armor_name)) - end) - end - end - end -end) - - - --- Applying the auto equip system when somenone punches on a drop. -minetest.registered_entities["__builtin:item"].on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, dir) - local pos = self.object:get_pos() - local pl_name = puncher:get_player_name() - local arena = skywars.get_arena_by_pos(pos) - - if minetest.get_modpath("3d_armor") and arena_lib.is_player_in_arena(pl_name, "skywars") then - local item = ItemStack(self.itemstring) - local is_an_armor = armor:get_element(self.itemstring) - - if is_an_armor then - if skywars.auto_equip(puncher, item) then - self.object:remove() - return - end - end - end - - on_punch(self, puncher, time_from_last_punch, tool_capabilities, dir) -end - - - -function get_armor_importance(armor_name) - for material, importance in pairs(skywars_settings.armors_importances) do - if armor_name:match(material) then - return importance - end - end -end \ No newline at end of file +dofile(minetest.get_modpath("skywars") .. "/_compatible_mods/3d_armor/auto_equip_armors.lua") \ No newline at end of file diff --git a/_player/auto_equip_items.lua b/_player/auto_equip_items.lua new file mode 100644 index 0000000..b27646d --- /dev/null +++ b/_player/auto_equip_items.lua @@ -0,0 +1,97 @@ +local function compare_items() end +local function get_item_importance() end +local function get_first_empty_slot() end +local on_punch = minetest.registered_entities["__builtin:item"].on_punch + + +function skywars.auto_equip_item(player, picked_itemstack, picked_itemstack_slot) + local inventory = player:get_inventory() + local hotbar = inventory:get_list("main") + + for hotbar_slot, hotbar_itemstack in ipairs(hotbar) do + if hotbar_slot > player:hud_get_hotbar_itemcount() or hotbar_itemstack:get_name() == "" then + break + end + + local picked_item_name = picked_itemstack:get_name() + local hotbar_item_name = hotbar_itemstack:get_name() + local best_item_name = compare_items(hotbar_item_name, picked_item_name) + -- Returning if the picked item is in the hotbar already. + if not picked_item_name == hotbar_item_name then return end + + if best_item_name == picked_item_name then + local first_empty_slot = picked_itemstack_slot or get_first_empty_slot(hotbar) + if not first_empty_slot then return end -- Returning if the inventory is full. + + hotbar[hotbar_slot] = picked_itemstack + hotbar[first_empty_slot] = hotbar_itemstack + inventory:set_list("main", hotbar) + + return true + end + end +end + + + +-- Applying the auto equip system when the player takes an item from an inventory. +minetest.register_on_player_inventory_action(function(player, action, inventory, inventory_info) + local pl_name = player:get_player_name() + + if arena_lib.is_player_in_arena(pl_name, "skywars") then + if action == "put" then + local picked_itemstack = inventory_info.stack + skywars.auto_equip_item(player, picked_itemstack, inventory_info.index) + end + end +end) + + + +-- Applying the auto equip system when somenone punches on a drop. +minetest.registered_entities["__builtin:item"].on_punch = function(self, puncher, time_from_last_punch, tool_capabilities, dir) + local pos = self.object:get_pos() + local pl_name = puncher:get_player_name() + + if arena_lib.is_player_in_arena(pl_name, "skywars") then + local itemstack = ItemStack(self.itemstring) + + if skywars.auto_equip_item(puncher, itemstack) then + self.object:remove() + return + end + end + + on_punch(self, puncher, time_from_last_punch, tool_capabilities, dir) +end + + + +function compare_items(item1, item2) + local item1_category, item1_importance = get_item_importance(item1) + local item2_category, item2_importance = get_item_importance(item2) + + if item1_category and item2_category then + if item1_category == item2_category then + if item1_importance > item2_importance then return item1 + elseif item1_importance < item2_importance then return item2 end + end + end +end + + + +function get_item_importance(item_name) + for category, importances in pairs(skywars_settings.items_importances) do + local importance = importances[item_name] + if importance then return category, importance end + end +end + + + +function get_first_empty_slot(list) + for i, itemstack in ipairs(list) do + if itemstack:get_name() == "" then return i end + end +end \ No newline at end of file diff --git a/init.lua b/init.lua index 5fb6008..9de3fb7 100644 --- a/init.lua +++ b/init.lua @@ -47,3 +47,4 @@ dofile(minetest.get_modpath("skywars") .. "/_chest_handler/treasures.lua") dofile(minetest.get_modpath("skywars") .. "/_arena_lib/arena_callbacks.lua") dofile(minetest.get_modpath("skywars") .. "/_kits/formspec.lua") dofile(minetest.get_modpath("skywars") .. "/_kits/kit_items.lua") +dofile(minetest.get_modpath("skywars") .. "/_player/auto_equip_items.lua") \ No newline at end of file