MineClone2/mods/ITEMS/vl_weaponry/init.lua
the-real-herowl 6a6f033197 Spear throw charging
- spear throw has to be charged for full power
- bow charging is improved and compatible with spears
- fixed a crash
2024-12-29 08:09:33 +01:00

553 lines
17 KiB
Lua

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.")
local hammer_use = S("To crush a block, dig the block with the hammer. This only works with some blocks.")
local spear_tt = S("Reaches farther") .. "\n" .. S("Can be thrown")
local spear_longdesc = S("Spears are great in melee combat, as they have an increased reach. They can also be thrown.")
local spear_use = S("To throw a spear, hold it in your hand, then hold use (rightclick) in the air.")
local wield_scale = mcl_vars.tool_wield_scale
local spear_entity = table.copy(mcl_bows.arrow_entity)
table.update(spear_entity,{
visual = "item",
visual_size = {x=-0.5, y=-0.5},
textures = {"vl_weaponry:spear_wood"},
_on_remove = function(self)
-- Prevent item duplication
if self._picked_up then return end
self._picked_up = true
vl_projectile.replace_with_item_drop(self, self.object:get_pos())
end,
})
table.update(spear_entity._vl_projectile,{
behaviors = {
vl_projectile.sticks,
vl_projectile.burns,
vl_projectile.has_tracer,
vl_projectile.has_owner_grace_distance,
vl_projectile.collides_with_solids,
vl_projectile.raycast_collides_with_entities,
-- Drop spears that are sliding
function(self, dtime)
if not self._last_pos then return end
local pos = self.object:get_pos()
local y_diff = math.abs(self._last_pos.y - pos.y)
if y_diff > 0.0001 then
self._flat_time = 0
return
end
local flat_time = (self._flat_time or 0) + dtime
self._flat_time = flat_time
if flat_time < 0.25 then return end
mcl_util.remove_entity(self)
return true
end,
},
pitch_offset = math.pi / 4,
})
vl_projectile.register("vl_weaponry:spear_entity", spear_entity)
local SPEAR_THROW_POWER = 30
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
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,
iron = 251,
gold = 33,
diamond = 1562,
netherite = 2031,
}
local materials = {
wood = "group:wood",
stone = "group:cobble",
iron = "mcl_core:iron_ingot",
gold = "mcl_core:gold_ingot",
diamond = "mcl_core:diamond",
}
local SPEAR_RANGE = 4.5
--Hammers
core.register_tool("vl_weaponry:hammer_wood", {
description = S("Wooden Hammer"),
_tt_help = hammer_tt,
_doc_items_longdesc = hammer_longdesc,
_doc_items_usagehelp = hammer_use,
_doc_items_hidden = false,
inventory_image = "vl_tool_woodhammer.png",
wield_scale = wield_scale,
groups = { weapon=1, hammer=1, dig_speed_class=2, enchantability=15 },
tool_capabilities = {
full_punch_interval = 1.2,
max_drop_level=1,
damage_groups = {fleshy=4},
punch_attack_uses = uses.wood,
},
sound = { breaks = "default_tool_breaks" },
_repair_material = "group:wood",
_mcl_toollike_wield = true,
_mcl_diggroups = {
pickaxey = { speed = 1, level = 1, uses = uses.wood },
shovely = { speed = 1, level = 2, uses = uses.wood }
},
})
core.register_tool("vl_weaponry:hammer_stone", {
description = S("Stone Hammer"),
_tt_help = hammer_tt,
_doc_items_longdesc = hammer_longdesc,
_doc_items_usagehelp = hammer_use,
inventory_image = "vl_tool_stonehammer.png",
wield_scale = wield_scale,
groups = { weapon=1, hammer=1, dig_speed_class=2, enchantability=5 },
tool_capabilities = {
full_punch_interval = 1.3,
max_drop_level=3,
damage_groups = {fleshy=5},
punch_attack_uses = uses.stone,
},
sound = { breaks = "default_tool_breaks" },
_repair_material = "group:cobble",
_mcl_toollike_wield = true,
_mcl_diggroups = {
pickaxey = { speed = 2, level = 3, uses = uses.stone },
shovely = { speed = 2, level = 3, uses = uses.stone }
},
})
core.register_tool("vl_weaponry:hammer_iron", {
description = S("Iron Hammer"),
_tt_help = hammer_tt,
_doc_items_longdesc = hammer_longdesc,
_doc_items_usagehelp = hammer_use,
inventory_image = "vl_tool_steelhammer.png",
wield_scale = wield_scale,
groups = { weapon=1, hammer=1, dig_speed_class=2, enchantability=14 },
tool_capabilities = {
full_punch_interval = 1.2,
max_drop_level=4,
damage_groups = {fleshy=6},
punch_attack_uses = uses.iron,
},
sound = { breaks = "default_tool_breaks" },
_repair_material = "mcl_core:iron_ingot",
_mcl_toollike_wield = true,
_mcl_diggroups = {
pickaxey = { speed = 3, level = 4, uses = uses.iron },
shovely = { speed = 3, level = 4, uses = uses.iron }
},
})
core.register_tool("vl_weaponry:hammer_gold", {
description = S("Golden Hammer"),
_tt_help = hammer_tt,
_doc_items_longdesc = hammer_longdesc,
_doc_items_usagehelp = hammer_use,
inventory_image = "vl_tool_goldhammer.png",
wield_scale = wield_scale,
groups = { weapon=1, hammer=1, dig_speed_class=2, enchantability=22 },
tool_capabilities = {
full_punch_interval = 1.0,
max_drop_level=2,
damage_groups = {fleshy=5},
punch_attack_uses = uses.gold,
},
sound = { breaks = "default_tool_breaks" },
_repair_material = "mcl_core:gold_ingot",
_mcl_toollike_wield = true,
_mcl_diggroups = {
pickaxey = { speed = 8, level = 4, uses = uses.gold },
shovely = { speed = 8, level = 4, uses = uses.gold }
},
})
core.register_tool("vl_weaponry:hammer_diamond", {
description = S("Diamond Hammer"),
_tt_help = hammer_tt,
_doc_items_longdesc = hammer_longdesc,
_doc_items_usagehelp = hammer_use,
inventory_image = "vl_tool_diamondhammer.png",
wield_scale = wield_scale,
groups = { weapon=1, hammer=1, dig_speed_class=2, enchantability=10 },
tool_capabilities = {
full_punch_interval = 1.0,
max_drop_level=5,
damage_groups = {fleshy=7},
punch_attack_uses = uses.diamond,
},
sound = { breaks = "default_tool_breaks" },
_repair_material = "mcl_core:diamond",
_mcl_toollike_wield = true,
_mcl_diggroups = {
pickaxey = { speed = 4, level = 5, uses = uses.diamond },
pickaxey = { speed = 4, level = 5, uses = uses.diamond }
},
_mcl_upgradable = true,
_mcl_upgrade_item = "vl_weaponry:hammer_netherite"
})
core.register_tool("vl_weaponry:hammer_netherite", {
description = S("Netherite Hammer"),
_tt_help = hammer_tt,
_doc_items_longdesc = hammer_longdesc,
_doc_items_usagehelp = hammer_use,
inventory_image = "vl_tool_netheritehammer.png",
wield_scale = wield_scale,
groups = { weapon=1, hammer=1, dig_speed_class=2, enchantability=10, fire_immune=1 },
tool_capabilities = {
full_punch_interval = 1.0,
max_drop_level=5,
damage_groups = {fleshy=9},
punch_attack_uses = uses.netherite,
},
sound = { breaks = "default_tool_breaks" },
_repair_material = "mcl_nether:netherite_ingot",
_mcl_toollike_wield = true,
_mcl_diggroups = {
pickaxey = { speed = 6, level = 6, uses = uses.netherite },
shovely = { speed = 6, level = 6, uses = uses.netherite }
},
})
--Spears
core.register_tool("vl_weaponry:spear_wood", {
description = S("Wooden Spear"),
_tt_help = spear_tt,
_doc_items_longdesc = spear_longdesc,
_doc_items_usagehelp = spear_use,
_doc_items_hidden = false,
inventory_image = "vl_tool_woodspear.png",
wield_scale = wield_scale,
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 = {
full_punch_interval = 0.75,
max_drop_level=1,
damage_groups = {fleshy=3},
punch_attack_uses = uses.wood,
},
sound = { breaks = "default_tool_breaks" },
_repair_material = "group:wood",
_mcl_toollike_wield = true,
_mcl_diggroups = {
swordy = { speed = 2, level = 1, uses = uses.wood },
swordy_cobweb = { speed = 2, level = 1, uses = uses.wood }
},
_mcl_spear_thrown_damage = 5,
})
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,
on_secondary_use = spear_on_place,
groups = { weapon=1, spear=1, dig_speed_class=2, enchantability=5 },
range = SPEAR_RANGE,
tool_capabilities = {
full_punch_interval = 0.75,
max_drop_level=3,
damage_groups = {fleshy=4},
punch_attack_uses = uses.stone,
},
sound = { breaks = "default_tool_breaks" },
_repair_material = "group:cobble",
_mcl_toollike_wield = true,
_mcl_diggroups = {
swordy = { speed = 2, level = 1, uses = uses.stone },
swordy_cobweb = { speed = 2, level = 1, uses = uses.stone }
},
_mcl_spear_thrown_damage = 6,
})
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,
on_secondary_use = spear_on_place,
groups = { weapon=1, spear=1, dig_speed_class=2, enchantability=14 },
range = SPEAR_RANGE,
tool_capabilities = {
full_punch_interval = 0.75,
max_drop_level=4,
damage_groups = {fleshy=5},
punch_attack_uses = uses.iron,
},
sound = { breaks = "default_tool_breaks" },
_repair_material = "mcl_core:iron_ingot",
_mcl_toollike_wield = true,
_mcl_diggroups = {
swordy = { speed = 2, level = 1, uses = uses.iron },
swordy_cobweb = { speed = 2, level = 1, uses = uses.iron }
},
_mcl_spear_thrown_damage = 7,
})
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,
on_secondary_use = spear_on_place,
groups = { weapon=1, spear=1, dig_speed_class=2, enchantability=22 },
range = SPEAR_RANGE,
tool_capabilities = {
full_punch_interval = 0.75,
max_drop_level=2,
damage_groups = {fleshy=3},
punch_attack_uses = uses.gold,
},
sound = { breaks = "default_tool_breaks" },
_repair_material = "mcl_core:gold_ingot",
_mcl_toollike_wield = true,
_mcl_diggroups = {
swordy = { speed = 2, level = 1, uses = uses.gold },
swordy_cobweb = { speed = 2, level = 1, uses = uses.gold }
},
_mcl_spear_thrown_damage = 5,
})
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,
on_secondary_use = spear_on_place,
groups = { weapon=1, spear=1, dig_speed_class=2, enchantability=10 },
range = SPEAR_RANGE,
tool_capabilities = {
full_punch_interval = 0.75,
max_drop_level=5,
damage_groups = {fleshy=6},
punch_attack_uses = uses.diamond,
},
sound = { breaks = "default_tool_breaks" },
_repair_material = "mcl_core:diamond",
_mcl_toollike_wield = true,
_mcl_diggroups = {
swordy = { speed = 2, level = 1, uses = uses.diamond },
swordy_cobweb = { speed = 2, level = 1, uses = uses.diamond }
},
_mcl_spear_thrown_damage = 8,
_mcl_upgradable = true,
_mcl_upgrade_item = "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,
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 = {
full_punch_interval = 0.75,
max_drop_level=5,
damage_groups = {fleshy=8},
punch_attack_uses = uses.netherite,
},
sound = { breaks = "default_tool_breaks" },
_repair_material = "mcl_nether:netherite_ingot",
_mcl_toollike_wield = true,
_mcl_diggroups = {
swordy = { speed = 2, level = 1, uses = uses.netherite },
swordy_cobweb = { speed = 2, level = 1, uses = uses.netherite }
},
_mcl_spear_thrown_damage = 12,
})
-- Crafting recipes
local s = "mcl_core:stick"
local b = ""
for t,m in pairs(materials) do
core.register_craft({
output = "vl_weaponry:hammer_"..t,
recipe = {
{ m, b, m },
{ m, s, m },
{ b, s, b },
}
})
core.register_craft({
output = "vl_weaponry:spear_"..t,
recipe = {
{ m, b, b },
{ b, s, b },
{ b, b, s },
}
})
core.register_craft({
output = "vl_weaponry:spear_"..t,
recipe = {
{ b, b, m },
{ b, s, b },
{ s, b, b },
}
})
end