Offhand shield
|
@ -571,3 +571,16 @@ function mcl_util.replace_mob(obj, mob)
|
||||||
obj:set_yaw(rot)
|
obj:set_yaw(rot)
|
||||||
return obj
|
return obj
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function mcl_util.get_pointed_thing(player)
|
||||||
|
local pos = vector.offset(player:get_pos(), 0, player:get_properties().eye_height, 0)
|
||||||
|
local look_dir = vector.multiply(player:get_look_dir(), 5)
|
||||||
|
local pos2 = vector.add(pos, look_dir)
|
||||||
|
local ray = minetest.raycast(pos, pos2, false, true)
|
||||||
|
|
||||||
|
if ray then
|
||||||
|
for pointed_thing in ray do
|
||||||
|
return pointed_thing
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
|
@ -525,7 +525,7 @@ if c("totem") then
|
||||||
inventory_image = "mcl_totems_totem.png",
|
inventory_image = "mcl_totems_totem.png",
|
||||||
wield_image = "mcl_totems_totem.png",
|
wield_image = "mcl_totems_totem.png",
|
||||||
stack_max = 1,
|
stack_max = 1,
|
||||||
groups = {combat_item=1},
|
groups = {combat_item = 1, offhand_item = 1},
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,171 @@
|
||||||
|
local minetest, math = minetest, math
|
||||||
|
mcl_offhand = {}
|
||||||
|
|
||||||
|
local max_offhand_px = 128
|
||||||
|
-- only supports up to 128px textures
|
||||||
|
|
||||||
|
function mcl_offhand.get_offhand(player)
|
||||||
|
return player:get_inventory():get_stack("offhand", 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function offhand_get_wear(player)
|
||||||
|
return mcl_offhand.get_offhand(player):get_wear()
|
||||||
|
end
|
||||||
|
|
||||||
|
local function offhand_get_count(player)
|
||||||
|
return mcl_offhand.get_offhand(player):get_count()
|
||||||
|
end
|
||||||
|
|
||||||
|
minetest.register_on_joinplayer(function(player, last_login)
|
||||||
|
mcl_offhand[player] = {
|
||||||
|
hud = {},
|
||||||
|
last_wear = offhand_get_wear(player),
|
||||||
|
last_count = offhand_get_count(player),
|
||||||
|
}
|
||||||
|
end)
|
||||||
|
|
||||||
|
local function remove_hud(player, hud)
|
||||||
|
local offhand_hud = mcl_offhand[player].hud[hud]
|
||||||
|
if offhand_hud then
|
||||||
|
player:hud_remove(offhand_hud)
|
||||||
|
mcl_offhand[player].hud[hud] = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function rgb_to_hex(r, g, b)
|
||||||
|
return string.format("%02x%02x%02x", r, g, b)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function update_wear_bar(player, itemstack)
|
||||||
|
local wear_bar_percent = (65535 - offhand_get_wear(player)) / 65535
|
||||||
|
|
||||||
|
local color = {255, 255, 255}
|
||||||
|
local wear = itemstack:get_wear() / 65535;
|
||||||
|
local wear_i = math.min(math.floor(wear * 600), 511);
|
||||||
|
wear_i = math.min(wear_i + 10, 511);
|
||||||
|
if wear_i <= 255 then
|
||||||
|
color = {wear_i, 255, 0}
|
||||||
|
else
|
||||||
|
color = {255, 511 - wear_i, 0}
|
||||||
|
end
|
||||||
|
local wear_bar = mcl_offhand[player].hud.wear_bar
|
||||||
|
player:hud_change(wear_bar, "text", "mcl_wear_bar.png^[colorize:#" .. rgb_to_hex(color[1], color[2], color[3]))
|
||||||
|
player:hud_change(wear_bar, "scale", {x = 40 * wear_bar_percent, y = 3})
|
||||||
|
player:hud_change(wear_bar, "offset", {x = -320 - (20 - player:hud_get(wear_bar).scale.x / 2), y = -13})
|
||||||
|
end
|
||||||
|
|
||||||
|
minetest.register_globalstep(function(dtime)
|
||||||
|
for _, player in pairs(minetest.get_connected_players()) do
|
||||||
|
local itemstack = mcl_offhand.get_offhand(player)
|
||||||
|
local offhand_item = itemstack:get_name()
|
||||||
|
local offhand_hud = mcl_offhand[player].hud
|
||||||
|
if offhand_item ~= "" then
|
||||||
|
local item_texture = minetest.registered_items[offhand_item].inventory_image .. "^[resize:" .. max_offhand_px .. "x" .. max_offhand_px
|
||||||
|
local position = {x = 0.5, y = 1}
|
||||||
|
local offset = {x = -320, y = -32}
|
||||||
|
|
||||||
|
if not offhand_hud.slot then
|
||||||
|
offhand_hud.slot = player:hud_add({
|
||||||
|
hud_elem_type = "image",
|
||||||
|
position = position,
|
||||||
|
offset = offset,
|
||||||
|
scale = {x = 2.75, y = 2.75},
|
||||||
|
text = "mcl_offhand_slot.png",
|
||||||
|
z_index = 0,
|
||||||
|
})
|
||||||
|
end
|
||||||
|
if not offhand_hud.item then
|
||||||
|
offhand_hud.item = player:hud_add({
|
||||||
|
hud_elem_type = "image",
|
||||||
|
position = position,
|
||||||
|
offset = offset,
|
||||||
|
scale = {x = 0.4, y = 0.4},
|
||||||
|
text = item_texture,
|
||||||
|
z_index = 1,
|
||||||
|
})
|
||||||
|
else
|
||||||
|
player:hud_change(offhand_hud.item, "text", item_texture)
|
||||||
|
end
|
||||||
|
if not offhand_hud.wear_bar_bg and minetest.registered_tools[offhand_item] then
|
||||||
|
if offhand_get_wear(player) > 0 then
|
||||||
|
local texture = "mcl_wear_bar.png^[colorize:#000000"
|
||||||
|
offhand_hud.wear_bar_bg = player:hud_add({
|
||||||
|
hud_elem_type = "image",
|
||||||
|
position = {x = 0.5, y = 1},
|
||||||
|
offset = {x = -320, y = -13},
|
||||||
|
scale = {x = 40, y = 3},
|
||||||
|
text = texture,
|
||||||
|
z_index = 2,
|
||||||
|
})
|
||||||
|
offhand_hud.wear_bar = player:hud_add({
|
||||||
|
hud_elem_type = "image",
|
||||||
|
position = {x = 0.5, y = 1},
|
||||||
|
offset = {x = -320, y = -13},
|
||||||
|
scale = {x = 10, y = 3},
|
||||||
|
text = texture,
|
||||||
|
z_index = 3,
|
||||||
|
})
|
||||||
|
update_wear_bar(player, itemstack)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if not offhand_hud.item_count and offhand_get_count(player) > 1 then
|
||||||
|
offhand_hud.item_count = player:hud_add({
|
||||||
|
hud_elem_type = "text",
|
||||||
|
position = {x = 0.5, y = 1},
|
||||||
|
offset = {x = -298, y = -18},
|
||||||
|
scale = {x = 1, y = 1},
|
||||||
|
alignment = {x = -1, y = 0},
|
||||||
|
text = offhand_get_count(player),
|
||||||
|
z_index = 4,
|
||||||
|
number = 0xFFFFFF,
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
if offhand_hud.wear_bar then
|
||||||
|
if offhand_hud.last_wear ~= offhand_get_wear(player) then
|
||||||
|
update_wear_bar(player, itemstack)
|
||||||
|
offhand_hud.last_wear = offhand_get_wear(player)
|
||||||
|
end
|
||||||
|
if offhand_get_wear(player) <= 0 or not minetest.registered_tools[offhand_item] then
|
||||||
|
remove_hud(player, "wear_bar_bg")
|
||||||
|
remove_hud(player, "wear_bar")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if offhand_hud.item_count then
|
||||||
|
if offhand_hud.last_count ~= offhand_get_count(player) then
|
||||||
|
player:hud_change(offhand_hud.item_count, "text", offhand_get_count(player))
|
||||||
|
offhand_hud.last_count = offhand_get_count(player)
|
||||||
|
end
|
||||||
|
if offhand_get_count(player) <= 1 then
|
||||||
|
remove_hud(player, "item_count")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
elseif offhand_hud.slot then
|
||||||
|
for index, _ in pairs(mcl_offhand[player].hud) do
|
||||||
|
remove_hud(player, index)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
minetest.register_allow_player_inventory_action(function(player, action, inventory, inventory_info)
|
||||||
|
if action == "move" and inventory_info.to_list == "offhand" then
|
||||||
|
local itemstack = inventory:get_stack(inventory_info.from_list, inventory_info.from_index)
|
||||||
|
if not (minetest.get_item_group(itemstack:get_name(), "offhand_item") > 0) then
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
return itemstack:get_stack_max()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
minetest.register_on_player_inventory_action(function(player, action, inventory, inventory_info)
|
||||||
|
local from_offhand = inventory_info.from_list == "offhand"
|
||||||
|
local to_offhand = inventory_info.to_list == "offhand"
|
||||||
|
if action == "move" and from_offhand or to_offhand then
|
||||||
|
mcl_inventory.update_inventory_formspec(player)
|
||||||
|
end
|
||||||
|
end)
|
|
@ -0,0 +1,3 @@
|
||||||
|
name = mcl_offhand
|
||||||
|
author = NO11
|
||||||
|
depends = mcl_inventory
|
After Width: | Height: | Size: 8.6 KiB |
After Width: | Height: | Size: 168 B |
|
@ -12,7 +12,7 @@ mcl_shields = {
|
||||||
dragon_breath = true,
|
dragon_breath = true,
|
||||||
},
|
},
|
||||||
enchantments = {"mending", "unbreaking"},
|
enchantments = {"mending", "unbreaking"},
|
||||||
player_shields = {},
|
players = {},
|
||||||
}
|
}
|
||||||
|
|
||||||
local interact_priv = minetest.registered_privileges.interact
|
local interact_priv = minetest.registered_privileges.interact
|
||||||
|
@ -22,36 +22,37 @@ interact_priv.give_to_admin = false
|
||||||
local overlay = mcl_enchanting.overlay
|
local overlay = mcl_enchanting.overlay
|
||||||
local hud = "mcl_shield_hud.png"
|
local hud = "mcl_shield_hud.png"
|
||||||
|
|
||||||
local shield_groups = {
|
minetest.register_tool("mcl_shields:shield", {
|
||||||
shield = 1,
|
|
||||||
weapon = 1,
|
|
||||||
enchantability = 1,
|
|
||||||
no_wieldview = 1,
|
|
||||||
not_in_creative_inventory = 1,
|
|
||||||
offhand_item = 1,
|
|
||||||
}
|
|
||||||
|
|
||||||
minetest.register_tool("mcl_shields:shield",{
|
|
||||||
description = S("Shield"),
|
description = S("Shield"),
|
||||||
_doc_items_longdesc = S("A shield is a tool used for protecting the player against attacks."),
|
_doc_items_longdesc = S("A shield is a tool used for protecting the player against attacks."),
|
||||||
inventory_image = "mcl_shield.png",
|
inventory_image = "mcl_shield.png",
|
||||||
stack_max = 1,
|
stack_max = 1,
|
||||||
groups = shield_groups,
|
groups = {
|
||||||
|
shield = 1,
|
||||||
|
weapon = 1,
|
||||||
|
enchantability = 1,
|
||||||
|
no_wieldview = 1,
|
||||||
|
offhand_item = 1,
|
||||||
|
},
|
||||||
sound = {breaks = "default_tool_breaks"},
|
sound = {breaks = "default_tool_breaks"},
|
||||||
_repair_material = "group:wood",
|
_repair_material = "group:wood",
|
||||||
wield_scale = {x = 2, y = 2, z = 2},
|
wield_scale = vector.new(2, 2, 2),
|
||||||
})
|
})
|
||||||
|
|
||||||
local function wielded_item(obj)
|
local function wielded_item(obj, i)
|
||||||
return obj:get_wielded_item():get_name()
|
local itemstack = obj:get_wielded_item()
|
||||||
|
if i == 1 then
|
||||||
|
itemstack = obj:get_inventory():get_stack("offhand", 1)
|
||||||
|
end
|
||||||
|
return itemstack:get_name()
|
||||||
end
|
end
|
||||||
|
|
||||||
local function wielding_shield(obj)
|
function mcl_shields.wielding_shield(obj, i)
|
||||||
return wielded_item(obj):find("mcl_shields:shield")
|
return wielded_item(obj, i):find("mcl_shields:shield")
|
||||||
end
|
end
|
||||||
|
|
||||||
local function shield_is_enchanted(obj)
|
local function shield_is_enchanted(obj, i)
|
||||||
return mcl_enchanting.is_enchanted(wielded_item(obj))
|
return mcl_enchanting.is_enchanted(wielded_item(obj, i))
|
||||||
end
|
end
|
||||||
|
|
||||||
minetest.register_entity("mcl_shields:shield_entity", {
|
minetest.register_entity("mcl_shields:shield_entity", {
|
||||||
|
@ -65,17 +66,20 @@ minetest.register_entity("mcl_shields:shield_entity", {
|
||||||
visual_size = vector.new(1, 1, 1),
|
visual_size = vector.new(1, 1, 1),
|
||||||
},
|
},
|
||||||
_blocking = false,
|
_blocking = false,
|
||||||
|
_shield_number = 2,
|
||||||
on_step = function(self, dtime, moveresult)
|
on_step = function(self, dtime, moveresult)
|
||||||
local player = self.object:get_attach()
|
local player = self.object:get_attach()
|
||||||
if player then
|
if player then
|
||||||
local shield_texture = "mcl_shield_base_nopattern.png"
|
local shield_texture = "mcl_shield_base_nopattern.png"
|
||||||
|
local i = self._shield_number
|
||||||
|
local item = wielded_item(player, i)
|
||||||
|
|
||||||
if wielded_item(player) ~= "mcl_shields:shield" and wielded_item(player) ~= "mcl_shields:shield_enchanted" then
|
if item ~= "mcl_shields:shield" and item ~= "mcl_shields:shield_enchanted" then
|
||||||
local meta_texture = player:get_wielded_item():get_meta():get_string("mcl_shields:shield_custom_pattern_texture")
|
local meta_texture = player:get_wielded_item():get_meta():get_string("mcl_shields:shield_custom_pattern_texture")
|
||||||
if meta_texture ~= "" then
|
if meta_texture ~= "" then
|
||||||
shield_texture = meta_texture
|
shield_texture = meta_texture
|
||||||
else
|
else
|
||||||
local color = minetest.registered_items[wielded_item(player)]._shield_color
|
local color = minetest.registered_items[item]._shield_color
|
||||||
if color then
|
if color then
|
||||||
shield_texture = "mcl_shield_base_nopattern.png^(mcl_shield_pattern_base.png^[colorize:" .. color .. ")"
|
shield_texture = "mcl_shield_base_nopattern.png^(mcl_shield_pattern_base.png^[colorize:" .. color .. ")"
|
||||||
end
|
end
|
||||||
|
@ -83,7 +87,7 @@ minetest.register_entity("mcl_shields:shield_entity", {
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if shield_is_enchanted(player) then
|
if shield_is_enchanted(player, i) then
|
||||||
shield_texture = shield_texture .. overlay
|
shield_texture = shield_texture .. overlay
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -99,52 +103,76 @@ for _, e in pairs(mcl_shields.enchantments) do
|
||||||
end
|
end
|
||||||
|
|
||||||
function mcl_shields.is_blocking(obj)
|
function mcl_shields.is_blocking(obj)
|
||||||
if not obj then return end
|
local blocking = mcl_shields.players[obj].blocking
|
||||||
local shield = mcl_shields.player_shields[obj]
|
if blocking > 0 then
|
||||||
if shield then
|
local shieldstack = obj:get_wielded_item()
|
||||||
return shield:get_luaentity()._blocking
|
if blocking == 1 then
|
||||||
|
shieldstack = obj:get_inventory():get_stack("offhand", 1)
|
||||||
|
end
|
||||||
|
return blocking, shieldstack
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
mcl_damage.register_modifier(function(obj, damage, reason)
|
mcl_damage.register_modifier(function(obj, damage, reason)
|
||||||
local type = reason.type
|
local type = reason.type
|
||||||
local damager = reason.direct
|
local damager = reason.direct
|
||||||
if obj:is_player() and mcl_shields.is_blocking(obj) and mcl_shields.types[type] and damager then
|
local blocking, shieldstack = mcl_shields.is_blocking(obj)
|
||||||
|
if obj:is_player() and blocking and mcl_shields.types[type] and damager then
|
||||||
local entity = damager:get_luaentity()
|
local entity = damager:get_luaentity()
|
||||||
if entity and (type == "arrow" or type == "generic") then
|
if entity and (type == "arrow" or type == "generic") then
|
||||||
damager = entity._shooter
|
damager = entity._shooter
|
||||||
end
|
end
|
||||||
if vector.dot(obj:get_look_dir(), vector.subtract(damager:get_pos(), obj:get_pos())) >= 0 then
|
if vector.dot(obj:get_look_dir(), vector.subtract(damager:get_pos(), obj:get_pos())) >= 0 then
|
||||||
local item = obj:get_wielded_item()
|
|
||||||
local durability = 336
|
local durability = 336
|
||||||
local unbreaking = mcl_enchanting.get_enchantment(item, mcl_shields.enchantments[2])
|
local unbreaking = mcl_enchanting.get_enchantment(shieldstack, mcl_shields.enchantments[2])
|
||||||
if unbreaking > 0 then
|
if unbreaking > 0 then
|
||||||
durability = durability * (unbreaking + 1)
|
durability = durability * (unbreaking + 1)
|
||||||
end
|
end
|
||||||
if not minetest.is_creative_enabled(obj:get_player_name()) and damage >= 3 then
|
if not minetest.is_creative_enabled(obj:get_player_name()) and damage >= 3 then
|
||||||
item:add_wear(65535 / durability)
|
shieldstack:add_wear(65535 / durability)
|
||||||
|
if blocking == 2 then
|
||||||
|
obj:set_wielded_item(shieldstack)
|
||||||
|
else
|
||||||
|
obj:get_inventory():set_stack("offhand", 1, shieldstack)
|
||||||
|
mcl_inventory.update_inventory_formspec(obj)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
minetest.sound_play({name = "mcl_block"})
|
minetest.sound_play({name = "mcl_block"})
|
||||||
obj:set_wielded_item(item)
|
|
||||||
return 0
|
return 0
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
local function modify_shield(player, vpos, vrot)
|
local function modify_shield(player, vpos, vrot, i)
|
||||||
mcl_shields.player_shields[player]:set_attach(player, "Arm_Right", vpos, vrot, false)
|
local arm = "Right"
|
||||||
end
|
if i == 1 then
|
||||||
|
arm = "Left"
|
||||||
local function set_shield(player, block)
|
end
|
||||||
if block then
|
local shield = mcl_shields.players[player].shields[i]
|
||||||
modify_shield(player, vector.new(-8, 4, -2.5), vector.new(80, 80, 0))
|
if shield then
|
||||||
else
|
shield:set_attach(player, "Arm_" .. arm, vpos, vrot, false)
|
||||||
modify_shield(player, vector.new(3, -5, 0), vector.new(0, 0, 0))
|
|
||||||
end
|
end
|
||||||
mcl_shields.player_shields[player]:get_luaentity()._blocking = block
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local shield_hud = {}
|
local function set_shield(player, block, i)
|
||||||
|
if block then
|
||||||
|
if i == 1 then
|
||||||
|
modify_shield(player, vector.new(-9, 4, 0.5), vector.new(80, 100, 0), i) -- TODO
|
||||||
|
else
|
||||||
|
modify_shield(player, vector.new(-8, 4, -2.5), vector.new(80, 80, 0), i)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if i == 1 then
|
||||||
|
modify_shield(player, vector.new(-3, -5, 0), vector.new(0, 180, 0), i)
|
||||||
|
else
|
||||||
|
modify_shield(player, vector.new(3, -5, 0), vector.new(0, 0, 0), i)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local shield = mcl_shields.players[player].shields[i]
|
||||||
|
if shield then
|
||||||
|
shield:get_luaentity()._blocking = block
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local function set_interact(player, interact)
|
local function set_interact(player, interact)
|
||||||
local player_name = player:get_player_name()
|
local player_name = player:get_player_name()
|
||||||
|
@ -153,92 +181,184 @@ local function set_interact(player, interact)
|
||||||
minetest.set_player_privs(player_name, privs)
|
minetest.set_player_privs(player_name, privs)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local shield_hud = {}
|
||||||
|
|
||||||
local function remove_shield_hud(player)
|
local function remove_shield_hud(player)
|
||||||
if shield_hud[player] then
|
if shield_hud[player] then
|
||||||
player:hud_remove(shield_hud[player])
|
player:hud_remove(shield_hud[player])
|
||||||
shield_hud[player] = nil
|
shield_hud[player] = nil
|
||||||
player:hud_set_flags({wielditem = true})
|
set_shield(player, false, 1)
|
||||||
playerphysics.remove_physics_factor(player, "speed", "shield_speed")
|
set_shield(player, false, 2)
|
||||||
set_interact(player, true)
|
end
|
||||||
set_shield(player, false)
|
player:hud_set_flags({wielditem = true})
|
||||||
|
playerphysics.remove_physics_factor(player, "speed", "shield_speed")
|
||||||
|
set_interact(player, true)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function add_shield_entity(player, i)
|
||||||
|
local shield = minetest.add_entity(player:get_pos(), "mcl_shields:shield_entity")
|
||||||
|
shield:get_luaentity()._shield_number = i
|
||||||
|
mcl_shields.players[player].shields[i] = shield
|
||||||
|
set_shield(player, false, i)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function remove_shield_entity(player, i)
|
||||||
|
local shields = mcl_shields.players[player].shields
|
||||||
|
if shields[i] then
|
||||||
|
shields[i]:remove()
|
||||||
|
shields[i] = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function add_shield(player)
|
local function handle_blocking(player)
|
||||||
local shield = minetest.add_entity(player:get_pos(), "mcl_shields:shield_entity")
|
local player_shield = mcl_shields.players[player]
|
||||||
mcl_shields.player_shields[player] = shield
|
local rmb = player:get_player_control().RMB
|
||||||
set_shield(player, false)
|
if rmb then
|
||||||
end
|
local shield_in_offhand = mcl_shields.wielding_shield(player, 1)
|
||||||
|
local shield_in_hand = mcl_shields.wielding_shield(player)
|
||||||
|
local not_blocking = player_shield.blocking == 0
|
||||||
|
|
||||||
local function update_shield(player)
|
local pos = player:get_pos()
|
||||||
if wielding_shield(player) and player:get_player_control().RMB then
|
if shield_in_hand then
|
||||||
if shield_hud[player] then
|
if not_blocking then
|
||||||
local image = player:hud_get(shield_hud[player]).text
|
minetest.after(0.25, function()
|
||||||
if shield_is_enchanted(player) and image == hud then
|
if (not_blocking or not shield_in_offhand) and shield_in_hand and rmb then
|
||||||
player:hud_change(shield_hud[player], "text", hud .. overlay)
|
player_shield.blocking = 2
|
||||||
elseif not shield_is_enchanted(player) and image == hud .. overlay then
|
set_shield(player, true, 2)
|
||||||
player:hud_change(shield_hud[player], "text", hud)
|
end
|
||||||
|
end)
|
||||||
|
elseif not shield_in_offhand then
|
||||||
|
player_shield.blocking = 2
|
||||||
|
end
|
||||||
|
elseif shield_in_offhand then
|
||||||
|
local offhand_can_block = (wielded_item(player) == "" or not mcl_util.get_pointed_thing(player))
|
||||||
|
if offhand_can_block then
|
||||||
|
if not_blocking then
|
||||||
|
minetest.after(0.25, function()
|
||||||
|
if (not_blocking or not shield_in_hand) and shield_in_offhand and rmb and offhand_can_block then
|
||||||
|
player_shield.blocking = 1
|
||||||
|
set_shield(player, true, 1)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
elseif not shield_in_hand then
|
||||||
|
player_shield.blocking = 1
|
||||||
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
minetest.after(0.25, function()
|
player_shield.blocking = 0
|
||||||
if player and not shield_hud[player] and wielding_shield(player) and
|
|
||||||
player:get_player_control().RMB and mcl_shields.player_shields[player] then
|
|
||||||
local texture = hud
|
|
||||||
if shield_is_enchanted(player) then
|
|
||||||
texture = texture .. overlay
|
|
||||||
end
|
|
||||||
shield_hud[player] = player:hud_add({
|
|
||||||
hud_elem_type = "image",
|
|
||||||
position = {x = 0.5, y = 0.5},
|
|
||||||
scale = {x = -101, y = -101},
|
|
||||||
text = texture,
|
|
||||||
})
|
|
||||||
player:hud_set_flags({wielditem = false})
|
|
||||||
playerphysics.add_physics_factor(player, "speed", "shield_speed", 0.5)
|
|
||||||
set_shield(player, true)
|
|
||||||
set_interact(player, nil)
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
remove_shield_hud(player)
|
player_shield.blocking = 0
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function remove_shield(player)
|
local function update_shield_entity(player, blocking, i)
|
||||||
local shield = mcl_shields.player_shields[player]
|
local shield = mcl_shields.players[player].shields[i]
|
||||||
if shield then
|
if mcl_shields.wielding_shield(player, i) then
|
||||||
shield:remove()
|
if not shield then
|
||||||
mcl_shields.player_shields[player] = nil
|
add_shield_entity(player, i)
|
||||||
|
else
|
||||||
|
if blocking == i then
|
||||||
|
if shield:get_luaentity() and not shield:get_luaentity()._blocking then
|
||||||
|
set_shield(player, true, i)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
set_shield(player, false, i)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elseif shield then
|
||||||
|
remove_shield_entity(player, i)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
minetest.register_globalstep(function(dtime)
|
minetest.register_globalstep(function(dtime)
|
||||||
for _, player in pairs(minetest.get_connected_players()) do
|
for _, player in pairs(minetest.get_connected_players()) do
|
||||||
local player_shield = mcl_shields.player_shields[player]
|
|
||||||
if wielding_shield(player) then
|
handle_blocking(player)
|
||||||
if not player_shield then
|
|
||||||
add_shield(player)
|
local blocking, shieldstack = mcl_shields.is_blocking(player)
|
||||||
|
|
||||||
|
if blocking then
|
||||||
|
local shieldhud = shield_hud[player]
|
||||||
|
if not shieldhud then
|
||||||
|
local texture = hud
|
||||||
|
if mcl_enchanting.is_enchanted(shieldstack:get_name()) then
|
||||||
|
texture = texture .. overlay
|
||||||
|
end
|
||||||
|
local offset = 100
|
||||||
|
if blocking == 1 then
|
||||||
|
texture = texture .. "^[transform4"
|
||||||
|
offset = -100
|
||||||
|
else
|
||||||
|
player:hud_set_flags({wielditem = false})
|
||||||
|
end
|
||||||
|
shield_hud[player] = player:hud_add({
|
||||||
|
hud_elem_type = "image",
|
||||||
|
position = {x = 0.5, y = 0.5},
|
||||||
|
scale = {x = -101, y = -101},
|
||||||
|
offset = {x = offset, y = 0},
|
||||||
|
text = texture,
|
||||||
|
z_index = -200,
|
||||||
|
})
|
||||||
|
playerphysics.add_physics_factor(player, "speed", "shield_speed", 0.5)
|
||||||
|
set_interact(player, nil)
|
||||||
else
|
else
|
||||||
update_shield(player)
|
local wielditem = player:hud_get_flags().wielditem
|
||||||
|
if blocking == 1 then
|
||||||
|
if not wielditem then
|
||||||
|
player:hud_change(shieldhud, "text", hud .. "^[transform4")
|
||||||
|
player:hud_change(shieldhud, "offset", {x = -100, y = 0})
|
||||||
|
player:hud_set_flags({wielditem = true})
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if wielditem then
|
||||||
|
player:hud_change(shieldhud, "text", hud)
|
||||||
|
player:hud_change(shieldhud, "offset", {x = 100, y = 0})
|
||||||
|
player:hud_set_flags({wielditem = false})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local image = player:hud_get(shieldhud).text
|
||||||
|
local enchanted = hud .. overlay
|
||||||
|
local enchanted1 = image == enchanted
|
||||||
|
local enchanted2 = image == enchanted .. "^[transform4"
|
||||||
|
if mcl_enchanting.is_enchanted(shieldstack:get_name()) then
|
||||||
|
if not enchanted1 and not enchanted2 then
|
||||||
|
if blocking == 1 then
|
||||||
|
player:hud_change(shieldhud, "text", hud .. overlay .. "^[transform4")
|
||||||
|
else
|
||||||
|
player:hud_change(shieldhud, "text", hud .. overlay)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elseif enchanted1 or enchanted2 then
|
||||||
|
if blocking == 1 then
|
||||||
|
player:hud_change(shieldhud, "text", hud .. "^[transform4")
|
||||||
|
else
|
||||||
|
player:hud_change(shieldhud, "text", hud)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
elseif not wielding_shield(player) and player_shield then
|
else
|
||||||
remove_shield_hud(player)
|
remove_shield_hud(player)
|
||||||
remove_shield(player)
|
end
|
||||||
|
|
||||||
|
for i = 1, 2 do
|
||||||
|
update_shield_entity(player, blocking, i)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
minetest.register_on_dieplayer(function(player)
|
minetest.register_on_dieplayer(function(player)
|
||||||
|
remove_shield_hud(player)
|
||||||
if not minetest.settings:get_bool("mcl_keepInventory") then
|
if not minetest.settings:get_bool("mcl_keepInventory") then
|
||||||
remove_shield_hud(player)
|
remove_shield_entity(player, 1)
|
||||||
remove_shield(player)
|
remove_shield_entity(player, 2)
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
minetest.register_on_leaveplayer(function(player)
|
minetest.register_on_leaveplayer(function(player)
|
||||||
shield_hud[player] = nil
|
shield_hud[player] = nil
|
||||||
mcl_shields.player_shields[player] = nil
|
mcl_shields.players[player] = nil
|
||||||
end)
|
end)
|
||||||
|
|
||||||
minetest.register_craft({
|
minetest.register_craft({
|
||||||
|
@ -251,15 +371,22 @@ minetest.register_craft({
|
||||||
})
|
})
|
||||||
|
|
||||||
for _, colortab in pairs(mcl_banners.colors) do
|
for _, colortab in pairs(mcl_banners.colors) do
|
||||||
minetest.register_tool("mcl_shields:shield_" .. colortab[1],{
|
minetest.register_tool("mcl_shields:shield_" .. colortab[1], {
|
||||||
description = S(colortab[6] .. " Shield"),
|
description = S(colortab[6] .. " Shield"),
|
||||||
_doc_items_longdesc = S("A shield is a tool used for protecting the player against attacks."),
|
_doc_items_longdesc = S("A shield is a tool used for protecting the player against attacks."),
|
||||||
inventory_image = "mcl_shield.png^(mcl_shield_item_overlay.png^[colorize:" .. colortab[4] ..")",
|
inventory_image = "mcl_shield.png^(mcl_shield_item_overlay.png^[colorize:" .. colortab[4] ..")",
|
||||||
stack_max = 1,
|
stack_max = 1,
|
||||||
groups = shield_groups,
|
groups = {
|
||||||
|
shield = 1,
|
||||||
|
weapon = 1,
|
||||||
|
enchantability = 1,
|
||||||
|
no_wieldview = 1,
|
||||||
|
not_in_creative_inventory = 1,
|
||||||
|
offhand_item = 1,
|
||||||
|
},
|
||||||
sound = {breaks = "default_tool_breaks"},
|
sound = {breaks = "default_tool_breaks"},
|
||||||
_repair_material = "group:wood",
|
_repair_material = "group:wood",
|
||||||
wield_scale = {x = 2, y = 2, z = 2},
|
wield_scale = vector.new(2, 2, 2),
|
||||||
_shield_color = colortab[4],
|
_shield_color = colortab[4],
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -320,22 +447,11 @@ minetest.register_on_craft(function(itemstack, player, old_craft_grid, craft_inv
|
||||||
return craft_banner_on_shield(itemstack, player, old_craft_grid, craft_inv)
|
return craft_banner_on_shield(itemstack, player, old_craft_grid, craft_inv)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
minetest.register_allow_player_inventory_action(function(player, action, inventory, inventory_info)
|
minetest.register_on_joinplayer(function(player)
|
||||||
if action == "move" and inventory_info.to_list == "offhand" then
|
mcl_shields.players[player] = {
|
||||||
if minetest.get_item_group(inventory:get_stack(inventory_info.from_list, inventory_info.from_index):get_name(), "offhand_item") > 0 then
|
shields = {},
|
||||||
return
|
blocking = 0,
|
||||||
else
|
}
|
||||||
return 0
|
mcl_shields.players[player].blocking = 0
|
||||||
end
|
remove_shield_hud(player)
|
||||||
else
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
minetest.register_on_player_inventory_action(function(player, action, inventory, inventory_info)
|
|
||||||
local from_offhand = inventory_info.from_list == "offhand"
|
|
||||||
local to_offhand = inventory_info.to_list == "offhand"
|
|
||||||
if action == "move" and from_offhand or to_offhand then
|
|
||||||
mcl_inventory.update_inventory_formspec(player)
|
|
||||||
end
|
|
||||||
end)
|
end)
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
name = mcl_shields
|
name = mcl_shields
|
||||||
author = NO11
|
author = NO11
|
||||||
depends = mcl_damage, mcl_enchanting, mcl_banners, playerphysics
|
depends = mcl_damage, mcl_enchanting, mcl_banners, mcl_util, playerphysics
|
||||||
|
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 5.5 KiB |
Before Width: | Height: | Size: 141 KiB After Width: | Height: | Size: 639 KiB |
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 3.4 KiB |
|
@ -12,6 +12,14 @@ mcl_damage.register_modifier(function(obj, damage, reason)
|
||||||
local hp = obj:get_hp()
|
local hp = obj:get_hp()
|
||||||
if hp - damage <= 0 then
|
if hp - damage <= 0 then
|
||||||
local wield = obj:get_wielded_item()
|
local wield = obj:get_wielded_item()
|
||||||
|
local in_offhand = false
|
||||||
|
if not (wield:get_name() == "mobs_mc:totem") then
|
||||||
|
local inv = obj:get_inventory()
|
||||||
|
if inv then
|
||||||
|
wield = obj:get_inventory():get_stack("offhand", 1)
|
||||||
|
in_offhand = true
|
||||||
|
end
|
||||||
|
end
|
||||||
if wield:get_name() == "mobs_mc:totem" then
|
if wield:get_name() == "mobs_mc:totem" then
|
||||||
local ppos = obj:get_pos()
|
local ppos = obj:get_pos()
|
||||||
local pnname = minetest.get_node(ppos).name
|
local pnname = minetest.get_node(ppos).name
|
||||||
|
@ -28,7 +36,12 @@ mcl_damage.register_modifier(function(obj, damage, reason)
|
||||||
|
|
||||||
if not minetest.is_creative_enabled(obj:get_player_name()) then
|
if not minetest.is_creative_enabled(obj:get_player_name()) then
|
||||||
wield:take_item()
|
wield:take_item()
|
||||||
obj:set_wielded_item(wield)
|
if in_offhand then
|
||||||
|
obj:get_inventory():set_stack("offhand", 1, wield)
|
||||||
|
mcl_inventory.update_inventory_formspec(obj)
|
||||||
|
else
|
||||||
|
obj:set_wielded_item(wield)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Effects
|
-- Effects
|
||||||
|
|
|
@ -9,7 +9,8 @@ local animation_blend = 0
|
||||||
local function get_mouse_button(player)
|
local function get_mouse_button(player)
|
||||||
local controls = player:get_player_control()
|
local controls = player:get_player_control()
|
||||||
local get_wielded_item_name = player:get_wielded_item():get_name()
|
local get_wielded_item_name = player:get_wielded_item():get_name()
|
||||||
if controls.RMB and not string.find(get_wielded_item_name, "mcl_bows:bow") and not string.find(get_wielded_item_name, "mcl_bows:crossbow") and not string.find(get_wielded_item_name, "mcl_shields:shield") or controls.LMB then
|
if controls.RMB and not string.find(get_wielded_item_name, "mcl_bows:bow") and not string.find(get_wielded_item_name, "mcl_bows:crossbow") and
|
||||||
|
not mcl_shields.wielding_shield(player, 1) and not mcl_shields.wielding_shield(player, 2) or controls.LMB then
|
||||||
return true
|
return true
|
||||||
else
|
else
|
||||||
return false
|
return false
|
||||||
|
@ -208,7 +209,7 @@ minetest.register_globalstep(function(dtime)
|
||||||
or walking and velocity.z > 0.35
|
or walking and velocity.z > 0.35
|
||||||
or walking and velocity.z < -0.35 then
|
or walking and velocity.z < -0.35 then
|
||||||
local wielded_itemname = player:get_wielded_item():get_name()
|
local wielded_itemname = player:get_wielded_item():get_name()
|
||||||
local no_arm_moving = (string.find(wielded_itemname, "mcl_bows:bow") or string.find(wielded_itemname, "mcl_shields:shield"))
|
local no_arm_moving = string.find(wielded_itemname, "mcl_bows:bow") or mcl_shields.wielding_shield(player, 1) or mcl_shields.wielding_shield(player, 2)
|
||||||
|
|
||||||
if player_sneak[name] ~= controls.sneak then
|
if player_sneak[name] ~= controls.sneak then
|
||||||
player_anim[name] = nil
|
player_anim[name] = nil
|
||||||
|
|
|
@ -226,9 +226,11 @@ minetest.register_globalstep(function(dtime)
|
||||||
player_velocity_old = player:get_velocity() or player:get_player_velocity()
|
player_velocity_old = player:get_velocity() or player:get_player_velocity()
|
||||||
|
|
||||||
|
|
||||||
-- controls right and left arms pitch when shooting a bow
|
-- controls right and left arms pitch when shooting a bow or blocking
|
||||||
if mcl_shields.is_blocking(player) then
|
if mcl_shields.is_blocking(player) == 2 then
|
||||||
player:set_bone_position("Arm_Right_Pitch_Control", vector.new(-3, 5.785, 0), vector.new(20, -20, 0))
|
player:set_bone_position("Arm_Right_Pitch_Control", vector.new(-3, 5.785, 0), vector.new(20, -20, 0))
|
||||||
|
elseif mcl_shields.is_blocking(player) == 1 then
|
||||||
|
player:set_bone_position("Arm_Left_Pitch_Control", vector.new(3, 5.785, 0), vector.new(20, 20, 0))
|
||||||
elseif string.find(wielded:get_name(), "mcl_bows:bow") and control.RMB then
|
elseif string.find(wielded:get_name(), "mcl_bows:bow") and control.RMB then
|
||||||
player:set_bone_position("Arm_Right_Pitch_Control", vector.new(-3,5.785,0), vector.new(pitch+90,-30,pitch * -1 * .35))
|
player:set_bone_position("Arm_Right_Pitch_Control", vector.new(-3,5.785,0), vector.new(pitch+90,-30,pitch * -1 * .35))
|
||||||
player:set_bone_position("Arm_Left_Pitch_Control", vector.new(3.5,5.785,0), vector.new(pitch+90,43,pitch * .35))
|
player:set_bone_position("Arm_Left_Pitch_Control", vector.new(3.5,5.785,0), vector.new(pitch+90,43,pitch * .35))
|
||||||
|
|