From 6a6f033197abe1d09ed54124526089e50a021c73 Mon Sep 17 00:00:00 2001 From: the-real-herowl Date: Sun, 29 Dec 2024 07:42:00 +0100 Subject: [PATCH] Spear throw charging - spear throw has to be charged for full power - bow charging is improved and compatible with spears - fixed a crash --- mods/HUD/mcl_inventory/creative.lua | 2 +- mods/ITEMS/mcl_bows/bow.lua | 25 +-- mods/ITEMS/vl_weaponry/init.lua | 248 +++++++++++++++++++--------- mods/ITEMS/vl_weaponry/mod.conf | 2 +- 4 files changed, 181 insertions(+), 96 deletions(-) diff --git a/mods/HUD/mcl_inventory/creative.lua b/mods/HUD/mcl_inventory/creative.lua index 5a2a79ce3..3deade807 100644 --- a/mods/HUD/mcl_inventory/creative.lua +++ b/mods/HUD/mcl_inventory/creative.lua @@ -875,7 +875,7 @@ minetest.register_globalstep(function(dtime) if minetest.is_creative_enabled(name) then local touch_enabled = is_touch_enabled(name) - if touch_enabled ~= players[name].last_touch_enabled then + if not players[name] or touch_enabled ~= players[name].last_touch_enabled then mcl_inventory.set_creative_formspec(player) end end diff --git a/mods/ITEMS/mcl_bows/bow.lua b/mods/ITEMS/mcl_bows/bow.lua index 254a340dc..989f17337 100644 --- a/mods/ITEMS/mcl_bows/bow.lua +++ b/mods/ITEMS/mcl_bows/bow.lua @@ -180,6 +180,7 @@ local function reset_bows(player) for place, stack in pairs(list) do if stack:get_name() == "mcl_bows:bow" or stack:get_name() == "mcl_bows:bow_enchanted" then stack:get_meta():set_string("active", "") + stack:get_meta():set_string("inventory_image", "") elseif stack:get_name()=="mcl_bows:bow_0" or stack:get_name()=="mcl_bows:bow_1" or stack:get_name()=="mcl_bows:bow_2" then stack:set_name("mcl_bows:bow") stack:get_meta():set_string("active", "") @@ -290,12 +291,6 @@ controls.register_on_release(function(player, key, time) local has_shot = player_shoot_arrow(wielditem, player, speed, damage, is_critical) - if enchanted then - meta:set_string("inventory_image", "mcl_bows_bow.png"..mcl_enchanting.overlay) - else - meta:set_string("inventory_image", "mcl_bows_bow.png") - end - if has_shot and not minetest.is_creative_enabled(player:get_player_name()) then local durability = BOW_DURABILITY local unbreaking = mcl_enchanting.get_enchantment(wielditem, "unbreaking") @@ -333,14 +328,13 @@ controls.register_on_hold(function(player, key, time) bow_load[name] = minetest.get_us_time() bow_load_level[name] = 0 bow_index[name] = player:get_wield_index() - core.chat_send_all("init") -- begin Bow Zoom. mcl_fovapi.apply_modifier(player, "bowcomplete") else if player:get_wield_index() == bow_index[name] then - local level = 0 if type(bow_load[name]) == "number" then + local level = 0 if minetest.get_us_time() - bow_load[name] >= BOW_CHARGE_TIME_FULL then if bow_load_level[name] == 2 then return end level = 2 @@ -350,18 +344,17 @@ controls.register_on_hold(function(player, key, time) level = 1 bow_load_level[name] = 1 else return end + local im_string = "mcl_bows_bow_"..level..".png" + if wielditem:get_name() == "mcl_bows:bow_enchanted" then + im_string = im_string .. mcl_enchanting.overlay + end + meta:set_string("inventory_image", im_string) else - level = -1 + meta:set_string("inventory_image", "") bow_load_level[name] = nil end - local im_string = level == -1 and "mcl_bows_bow.png" or "mcl_bows_bow_"..level..".png" - if wielditem:get_name() == "mcl_bows:bow_enchanted" then - im_string = im_string .. mcl_enchanting.overlay - end - meta:set_string("inventory_image", im_string) - core.chat_send_all(im_string) player:set_wielded_item(wielditem) - else + elseif bow_load[name] then reset_bow_state(player, true) end end diff --git a/mods/ITEMS/vl_weaponry/init.lua b/mods/ITEMS/vl_weaponry/init.lua index b533dbb87..ad52195e1 100644 --- a/mods/ITEMS/vl_weaponry/init.lua +++ b/mods/ITEMS/vl_weaponry/init.lua @@ -1,6 +1,6 @@ -local modname = minetest.get_current_modname() -local modpath = minetest.get_modpath(modname) -local S = minetest.get_translator(modname) +local modname = core.get_current_modname() +local modpath = core.get_modpath(modname) +local S = core.get_translator(modname) local hammer_tt = S("Can crush blocks") .. "\n" .. S("Increased knockback") local hammer_longdesc = S("Hammers are great in melee combat, as they deal high damage with increased knockback and can endure countless battles. Hammers can also be used to crush things.") @@ -12,6 +12,8 @@ local spear_use = S("To throw a spear, hold it in your hand, then hold use (righ local wield_scale = mcl_vars.tool_wield_scale + + local spear_entity = table.copy(mcl_bows.arrow_entity) table.update(spear_entity,{ visual = "item", @@ -59,60 +61,150 @@ table.update(spear_entity._vl_projectile,{ vl_projectile.register("vl_weaponry:spear_entity", spear_entity) -local spear_throw_power = 25 +local SPEAR_THROW_POWER = 30 -local spear_on_place = function(wear_divisor) - return function(itemstack, user, pointed_thing) - if pointed_thing.type == "node" then - -- Call on_rightclick if the pointed node defines it - local node = minetest.get_node(pointed_thing.under) - if user and not user:get_player_control().sneak then - if minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].on_rightclick then - return minetest.registered_nodes[node.name].on_rightclick(pointed_thing.under, node, user, itemstack) or itemstack - end +local function spear_on_place(itemstack, user, pointed_thing) + if pointed_thing.type == "node" then + -- Call on_rightclick if the pointed node defines it + local node = core.get_node(pointed_thing.under) + if user and not user:get_player_control().sneak then + if core.registered_nodes[node.name] and core.registered_nodes[node.name].on_rightclick then + return core.registered_nodes[node.name].on_rightclick(pointed_thing.under, node, user, itemstack) or itemstack end end - - if minetest.is_protected(pointed_thing.under, user:get_player_name()) then - minetest.record_protection_violation(pointed_thing.under, user:get_player_name()) - return itemstack - end - - if not minetest.is_creative_enabled(user:get_player_name()) then - mcl_util.use_item_durability(itemstack, 1) - end - - local pos = user:get_pos() - pos.y = pos.y + 1.5 - local dir = user:get_look_dir() - local yaw = user:get_look_horizontal() - local obj = vl_projectile.create("vl_weaponry:spear_entity",{ - pos = pos, - dir = dir, - owner = user, - velocity = spear_throw_power, - }) - obj:set_properties({textures = {itemstack:get_name()}}) - local le = obj:get_luaentity() - le._shooter = user - le._source_object = user - le._damage = itemstack:get_definition()._mcl_spear_thrown_damage - le._is_critical = false - le._startpos = pos - le._collectable = true - le._arrow_item = itemstack:to_string() - minetest.sound_play("mcl_bows_bow_shoot", {pos=pos, max_hear_distance=16}, true) - if user and user:is_player() then - if obj:get_luaentity().player == "" then - obj:get_luaentity().player = user - end --- obj:get_luaentity().node = shooter:get_inventory():get_stack("main", 1):get_name() - end - - return ItemStack() end + + itemstack:get_meta():set_int("active", 1) + return itemstack end +local function throw_spear(itemstack, user, power_factor) + if not core.is_creative_enabled(user:get_player_name()) then + mcl_util.use_item_durability(itemstack, 1) + end + local meta = itemstack:get_meta() + meta:set_string("inventory_image", "") + meta:set_int("active", 0) + + local pos = user:get_pos() + pos.y = pos.y + 1.5 + local dir = user:get_look_dir() + local yaw = user:get_look_horizontal() + local obj = vl_projectile.create("vl_weaponry:spear_entity",{ + pos = pos, + dir = dir, + owner = user, + velocity = SPEAR_THROW_POWER * power_factor, + }) + obj:set_properties({textures = {itemstack:get_name()}}) + local le = obj:get_luaentity() + le._shooter = user + le._source_object = user + le._damage = itemstack:get_definition()._mcl_spear_thrown_damage * power_factor + le._is_critical = false -- TODO get from luck? + le._startpos = pos + le._collectable = true + le._arrow_item = itemstack:to_string() + core.sound_play("mcl_bows_bow_shoot", {pos=pos, max_hear_distance=16}, true) + if user and user:is_player() then + if obj:get_luaentity().player == "" then + obj:get_luaentity().player = user + end + end + + user:set_wielded_item(ItemStack()) +end + + + +-- Factor to multiply with player speed while player uses bow +-- This emulates the sneak speed. +local AIMING_MOVEMENT_SPEED = + tonumber(core.settings:get("movement_speed_crouch")) + / tonumber(core.settings:get("movement_speed_walk")) + +local SPEAR_FULL_CHARGE_TIME = 1000000 -- time until full charge in microseconds + +local spear_raise_time = {} +local spear_index = {} + +local function reset_spear_state(player, skip_inv_cleanup) + -- clear the FOV change from the player. + mcl_fovapi.remove_modifier(player, "bowcomplete") + + spear_raise_time[player:get_player_name()] = nil + spear_index[player:get_player_name()] = nil + if core.get_modpath("playerphysics") then + playerphysics.remove_physics_factor(player, "speed", "mcl_bows:use_bow") + end + if skip_inv_cleanup then return end + local inv = player:get_inventory() + local list = inv:get_list("main") + for place, stack in pairs(list) do + if core.get_item_group(stack:get_name(), "spear") > 0 then + local meta = stack:get_meta() + meta:set_int("active", 0) + meta:set_string("inventory_image", "") + end + end + inv:set_list("main", list) +end + +controls.register_on_release(function(player, key, time) + if key~="RMB" and key~="zoom" then return end + local wielditem = player:get_wielded_item() + if core.get_item_group(wielditem:get_name(), "spear") < 1 then return end + local pname = player:get_player_name() + local raise_moment = spear_raise_time[pname] or 0 + local power = math.max(math.min((core.get_us_time() - raise_moment) + / SPEAR_FULL_CHARGE_TIME, 1), 0) + throw_spear(wielditem, player, power) + reset_spear_state(player, true) +end) + +controls.register_on_hold(function(player, key, time) + local name = player:get_player_name() + local creative = core.is_creative_enabled(name) + local wielditem = player:get_wielded_item() + if (key ~= "RMB" and key ~= "zoom") + or core.get_item_group(wielditem:get_name(), "spear") < 1 then + return + end + local meta = wielditem:get_meta() + if spear_raise_time[name] == nil and (meta:get("active") or key == "zoom") then + meta:set_string("inventory_image", wielditem:get_definition().inventory_image .. "^[transformR90") + player:set_wielded_item(wielditem) + if core.get_modpath("playerphysics") then + -- Slow player down when using bow + playerphysics.add_physics_factor(player, "speed", "mcl_bows:use_bow", AIMING_MOVEMENT_SPEED) + end + spear_raise_time[name] = core.get_us_time() + spear_index[name] = player:get_wield_index() + + -- begin aiming Zoom. + mcl_fovapi.apply_modifier(player, "bowcomplete") + else + if player:get_wield_index() ~= spear_index[name] then + reset_spear_state(player) + end + end +end) + +minetest.register_globalstep(function(dtime) + for _, player in pairs(minetest.get_connected_players()) do + local name = player:get_player_name() + local wielditem = player:get_wielded_item() + local wieldindex = player:get_wield_index() + if type(spear_raise_time[name]) == "number" + and (core.get_item_group(wielditem:get_name(), "spear") < 1 + or wieldindex ~= spear_index[name]) then + reset_spear_state(player) + end + end +end) + + + local uses = { wood = 60, stone = 132, @@ -132,7 +224,7 @@ local materials = { local SPEAR_RANGE = 4.5 --Hammers -minetest.register_tool("vl_weaponry:hammer_wood", { +core.register_tool("vl_weaponry:hammer_wood", { description = S("Wooden Hammer"), _tt_help = hammer_tt, _doc_items_longdesc = hammer_longdesc, @@ -155,7 +247,7 @@ minetest.register_tool("vl_weaponry:hammer_wood", { shovely = { speed = 1, level = 2, uses = uses.wood } }, }) -minetest.register_tool("vl_weaponry:hammer_stone", { +core.register_tool("vl_weaponry:hammer_stone", { description = S("Stone Hammer"), _tt_help = hammer_tt, _doc_items_longdesc = hammer_longdesc, @@ -177,7 +269,7 @@ minetest.register_tool("vl_weaponry:hammer_stone", { shovely = { speed = 2, level = 3, uses = uses.stone } }, }) -minetest.register_tool("vl_weaponry:hammer_iron", { +core.register_tool("vl_weaponry:hammer_iron", { description = S("Iron Hammer"), _tt_help = hammer_tt, _doc_items_longdesc = hammer_longdesc, @@ -199,7 +291,7 @@ minetest.register_tool("vl_weaponry:hammer_iron", { shovely = { speed = 3, level = 4, uses = uses.iron } }, }) -minetest.register_tool("vl_weaponry:hammer_gold", { +core.register_tool("vl_weaponry:hammer_gold", { description = S("Golden Hammer"), _tt_help = hammer_tt, _doc_items_longdesc = hammer_longdesc, @@ -221,7 +313,7 @@ minetest.register_tool("vl_weaponry:hammer_gold", { shovely = { speed = 8, level = 4, uses = uses.gold } }, }) -minetest.register_tool("vl_weaponry:hammer_diamond", { +core.register_tool("vl_weaponry:hammer_diamond", { description = S("Diamond Hammer"), _tt_help = hammer_tt, _doc_items_longdesc = hammer_longdesc, @@ -245,7 +337,7 @@ minetest.register_tool("vl_weaponry:hammer_diamond", { _mcl_upgradable = true, _mcl_upgrade_item = "vl_weaponry:hammer_netherite" }) -minetest.register_tool("vl_weaponry:hammer_netherite", { +core.register_tool("vl_weaponry:hammer_netherite", { description = S("Netherite Hammer"), _tt_help = hammer_tt, _doc_items_longdesc = hammer_longdesc, @@ -269,7 +361,7 @@ minetest.register_tool("vl_weaponry:hammer_netherite", { }) --Spears -minetest.register_tool("vl_weaponry:spear_wood", { +core.register_tool("vl_weaponry:spear_wood", { description = S("Wooden Spear"), _tt_help = spear_tt, _doc_items_longdesc = spear_longdesc, @@ -277,8 +369,8 @@ minetest.register_tool("vl_weaponry:spear_wood", { _doc_items_hidden = false, inventory_image = "vl_tool_woodspear.png", wield_scale = wield_scale, - on_place = spear_on_place(uses.wood), - on_secondary_use = spear_on_place(uses.wood), + on_place = spear_on_place, + on_secondary_use = spear_on_place, groups = { weapon=1, spear=1, dig_speed_class=2, enchantability=15 }, range = SPEAR_RANGE, tool_capabilities = { @@ -296,15 +388,15 @@ minetest.register_tool("vl_weaponry:spear_wood", { }, _mcl_spear_thrown_damage = 5, }) -minetest.register_tool("vl_weaponry:spear_stone", { +core.register_tool("vl_weaponry:spear_stone", { description = S("Stone Spear"), _tt_help = spear_tt, _doc_items_longdesc = spear_longdesc, _doc_items_usagehelp = spear_use, inventory_image = "vl_tool_stonespear.png", wield_scale = wield_scale, - on_place = spear_on_place(uses.stone), - on_secondary_use = spear_on_place(uses.stone), + on_place = spear_on_place, + on_secondary_use = spear_on_place, groups = { weapon=1, spear=1, dig_speed_class=2, enchantability=5 }, range = SPEAR_RANGE, tool_capabilities = { @@ -322,15 +414,15 @@ minetest.register_tool("vl_weaponry:spear_stone", { }, _mcl_spear_thrown_damage = 6, }) -minetest.register_tool("vl_weaponry:spear_iron", { +core.register_tool("vl_weaponry:spear_iron", { description = S("Iron Spear"), _tt_help = spear_tt, _doc_items_longdesc = spear_longdesc, _doc_items_usagehelp = spear_use, inventory_image = "vl_tool_steelspear.png", wield_scale = wield_scale, - on_place = spear_on_place(uses.iron), - on_secondary_use = spear_on_place(uses.iron), + on_place = spear_on_place, + on_secondary_use = spear_on_place, groups = { weapon=1, spear=1, dig_speed_class=2, enchantability=14 }, range = SPEAR_RANGE, tool_capabilities = { @@ -348,15 +440,15 @@ minetest.register_tool("vl_weaponry:spear_iron", { }, _mcl_spear_thrown_damage = 7, }) -minetest.register_tool("vl_weaponry:spear_gold", { +core.register_tool("vl_weaponry:spear_gold", { description = S("Golden Spear"), _tt_help = spear_tt, _doc_items_longdesc = spear_longdesc, _doc_items_usagehelp = spear_use, inventory_image = "vl_tool_goldspear.png", wield_scale = wield_scale, - on_place = spear_on_place(uses.gold), - on_secondary_use = spear_on_place(uses.gold), + on_place = spear_on_place, + on_secondary_use = spear_on_place, groups = { weapon=1, spear=1, dig_speed_class=2, enchantability=22 }, range = SPEAR_RANGE, tool_capabilities = { @@ -374,15 +466,15 @@ minetest.register_tool("vl_weaponry:spear_gold", { }, _mcl_spear_thrown_damage = 5, }) -minetest.register_tool("vl_weaponry:spear_diamond", { +core.register_tool("vl_weaponry:spear_diamond", { description = S("Diamond Spear"), _tt_help = spear_tt, _doc_items_longdesc = spear_longdesc, _doc_items_usagehelp = spear_use, inventory_image = "vl_tool_diamondspear.png", wield_scale = wield_scale, - on_place = spear_on_place(uses.diamond), - on_secondary_use = spear_on_place(uses.diamond), + on_place = spear_on_place, + on_secondary_use = spear_on_place, groups = { weapon=1, spear=1, dig_speed_class=2, enchantability=10 }, range = SPEAR_RANGE, tool_capabilities = { @@ -402,15 +494,15 @@ minetest.register_tool("vl_weaponry:spear_diamond", { _mcl_upgradable = true, _mcl_upgrade_item = "vl_weaponry:spear_netherite" }) -minetest.register_tool("vl_weaponry:spear_netherite", { +core.register_tool("vl_weaponry:spear_netherite", { description = S("Netherite Spear"), _tt_help = spear_tt, _doc_items_longdesc = spear_longdesc, _doc_items_usagehelp = spear_use, inventory_image = "vl_tool_netheritespear.png", wield_scale = wield_scale, - on_place = spear_on_place(uses.netherite), - on_secondary_use = spear_on_place(uses.netherite), + on_place = spear_on_place, + on_secondary_use = spear_on_place, groups = { weapon=1, spear=1, dig_speed_class=2, enchantability=10, fire_immune=1 }, range = SPEAR_RANGE, tool_capabilities = { @@ -433,7 +525,7 @@ minetest.register_tool("vl_weaponry:spear_netherite", { local s = "mcl_core:stick" local b = "" for t,m in pairs(materials) do - minetest.register_craft({ + core.register_craft({ output = "vl_weaponry:hammer_"..t, recipe = { { m, b, m }, @@ -441,7 +533,7 @@ for t,m in pairs(materials) do { b, s, b }, } }) - minetest.register_craft({ + core.register_craft({ output = "vl_weaponry:spear_"..t, recipe = { { m, b, b }, @@ -449,7 +541,7 @@ for t,m in pairs(materials) do { b, b, s }, } }) - minetest.register_craft({ + core.register_craft({ output = "vl_weaponry:spear_"..t, recipe = { { b, b, m }, diff --git a/mods/ITEMS/vl_weaponry/mod.conf b/mods/ITEMS/vl_weaponry/mod.conf index 1d49767b1..bdc4f326d 100644 --- a/mods/ITEMS/vl_weaponry/mod.conf +++ b/mods/ITEMS/vl_weaponry/mod.conf @@ -1,3 +1,3 @@ name = vl_weaponry author = Herowl -depends = mcl_sounds, mcl_init, mcl_bows, vl_projectile +depends = mcl_sounds, mcl_init, mcl_bows, vl_projectile, controls