Compare commits

...

18 Commits

Author SHA1 Message Date
teknomunk f2f0e8484b Wear spears when thrown, add spear recipe 2024-11-16 21:43:55 -06:00
teknomunk e26464b704 Add initial craft recipe for hammers 2024-11-16 21:43:55 -06:00
teknomunk 2eb4ca54b0 Fix item duplication bug, drop spears that start sliding 2024-11-16 21:43:55 -06:00
teknomunk 9c68a70bd2 Remove debug print, remove dead code, replace magic numbers in tool uses with uses.* 2024-11-16 21:43:55 -06:00
teknomunk 34f1ec68e4 Remove old spear implementation, make spears drop as an item when removed 2024-11-16 21:43:55 -06:00
teknomunk aa2fac6ef8 Start rewriting spears using vl_projectile API 2024-11-16 21:43:55 -06:00
the-real-herowl d5799c6b21 Reworked hammer crushing
- crushing is now done by digging with a hammer
- cobble is now crushable
2024-11-16 21:43:55 -06:00
the-real-herowl 78e6ab1868 Added spears 2024-11-16 21:43:55 -06:00
teknomunk 8f75d34061 Resolve merge conflict 2024-11-16 21:43:55 -06:00
the-real-herowl 155a971dc2 Added hammers 2024-11-16 21:43:55 -06:00
teknomunk 0f2007c736 Implement mcl_util.remove_entity() and convert projectile code to use it 2024-11-16 21:43:55 -06:00
teknomunk 1c7d727286 Fix tipped arrow behavior, remove debug code 2024-11-16 19:46:39 -06:00
teknomunk 9061df8adf Rework projectile pickup code (to prevent item duplication bugs), always update _last_pos, short circuit processing behaviors if the entity was removed by a behavior but didn't report it 2024-11-16 19:46:39 -06:00
teknomunk a03aa6065b Fix crash when respawning 2024-11-16 19:46:39 -06:00
teknomunk 6a1b8d0f09 Let arrows stick in players 2024-11-16 19:46:39 -06:00
teknomunk 2fec9696b6 Implement mcl_util.remove_entity() and convert projectile code to use it 2024-11-16 19:46:37 -06:00
teknomunk 27f0f8b52b Add pitch and yaw offset support to vl_projectile 2024-11-16 19:44:18 -06:00
teknomunk 74ce69e3f0 Correct self-collision for lingering/splash potions 2024-11-16 19:44:18 -06:00
31 changed files with 566 additions and 83 deletions

View File

@ -731,3 +731,21 @@ function mcl_util.get_entity_id(entity)
return id
end
end
function mcl_util.remove_entity(luaentity)
if luaentity._removed then return end
luaentity._removed = true
local hook = luaentity._on_remove
if hook then hook(luaentity) end
luaentity.object:remove()
end
function mcl_util.remove_entity(luaentity)
if luaentity._removed then return end
luaentity._removed = true
local hook = luaentity._on_remove
if hook then hook(luaentity) end
luaentity.object:remove()
end

View File

@ -318,6 +318,12 @@ function minetest.handle_node_drops(pos, drops, digger)
end
end
-- Special node drops (crushing) when digging with a hammer
local hammer = tooldef.groups.hammer
if hammer and hammer > 0 and nodedef._vl_crushing_drop then
drops = nodedef._vl_crushing_drop
end
if tool and nodedef._mcl_fortune_drop and enchantments.fortune then
local fortune_level = enchantments.fortune
local fortune_drop = nodedef._mcl_fortune_drop

View File

@ -522,10 +522,11 @@ function mob_class:on_punch(hitter, tflp, tool_capabilities, dir)
local is_player = hitter:is_player()
local mob_pos = self.object:get_pos()
local player_pos = hitter:get_pos()
local weapon = hitter:get_wielded_item()
if is_player then
-- is mob out of reach?
if vector.distance(mob_pos, player_pos) > 3 then
if vector.distance(mob_pos, player_pos) > (weapon:get_definition().range or 3) then
return
end
-- is mob protected?
@ -572,7 +573,6 @@ function mob_class:on_punch(hitter, tflp, tool_capabilities, dir)
-- punch interval
local weapon = hitter:get_wielded_item()
local punch_interval = 1.4
-- exhaust attacker
@ -733,6 +733,7 @@ function mob_class:on_punch(hitter, tflp, tool_capabilities, dir)
if hitter and is_player then
local wielditem = hitter:get_wielded_item()
kb = kb + 9 * mcl_enchanting.get_enchantment(wielditem, "knockback")
kb = kb + 9 * minetest.get_item_group(wielditem:get_name(), "hammer")
-- add player velocity to mob knockback
local hv = hitter:get_velocity()
local dir_dot = (hv.x * dir.x) + (hv.z * dir.z)

View File

@ -434,14 +434,12 @@ function mcl_mobs.register_arrow(name, def)
minetest.add_item(self.lastpos, self.object:get_luaentity().name)
end
self._removed = true
self.object:remove();
mcl_util.remove_entity(self)
end,
on_collide_with_entity = function(self, pos, object)
if self.hit_player and object:is_player() then
self.hit_player(self, object)
self._removed = true
self.object:remove()
mcl_util.remove_entity(self)
return
end
@ -451,13 +449,11 @@ function mcl_mobs.register_arrow(name, def)
if self.hit_mob and entity.is_mob == true then
self.hit_mob(self, object)
self._removed = true
self.object:remove()
mcl_util.remove_entity(self)
return
elseif self.hit_object then
self.hit_object(self, object)
self._removed = true
self.object:remove()
mcl_util.remove_entity(self)
return
end
end
@ -481,8 +477,7 @@ function mcl_mobs.register_arrow(name, def)
if self.switch == 0 or self.timer > self._lifetime or not within_limits(pos, 0) then
mcl_burning.extinguish(self.object)
self._removed = true
self.object:remove();
mcl_util.remove_entity(self)
return
end

View File

@ -201,8 +201,7 @@ mcl_mobs.register_mob("mobs_mc:wither", {
self._death_timer = self._death_timer + self.health - self._health_old
if self.health == self._health_old then self._death_timer = self._death_timer + dtime end
if self._death_timer > 100 then
self._removed = true
self.object:remove()
mcl_util.remove_entity(self)
return false
end
self._health_old = self.health

View File

@ -138,8 +138,9 @@ local arrow_entity = {
-- Because arrows are flagged to survive collisions to allow sticking into blocks, manually remove it now that it
-- has collided with an entity
self._removed = true
self.object:remove()
if not is_player then
mcl_util.remove_entity(self)
end
end
},
@ -186,8 +187,7 @@ local arrow_entity = {
end
if data.stuckin_player then
self._removed = true
self.object:remove()
mcl_util.remove_entity(self)
end
end,
}
@ -201,7 +201,7 @@ minetest.register_on_respawnplayer(function(player)
for _, obj in pairs(player:get_children()) do
local ent = obj:get_luaentity()
if ent and ent.name and string.find(ent.name, "mcl_bows:arrow_entity") then
obj:remove()
mcl_util.remove_entity(ent)
end
end
end)

View File

@ -241,7 +241,7 @@ minetest.register_craftitem("mcl_bows:rocket", {
local eploded_particle = particle_explosion(pos)
damage_explosion(self, eploded_particle * 17, pos)
mcl_burning.extinguish(self.object)
self.object:remove()
mcl_util.remove_entity(self)
end
end,
})
@ -268,7 +268,7 @@ rocket_entity.on_step = function(self, dtime)
local eploded_particle = particle_explosion(self)
damage_explosion(self, eploded_particle * 17)
mcl_burning.extinguish(self.object)
self.object:remove()
mcl_util.remove_entity(self)
return
end

View File

@ -772,6 +772,7 @@ minetest.register_node("mcl_core:cobble", {
sounds = mcl_sounds.node_sound_stone_defaults(),
_mcl_blast_resistance = 6,
_mcl_hardness = 2,
_vl_crushing_drop = { "mcl_core:gravel" }
})
minetest.register_node("mcl_core:mossycobble", {

View File

@ -285,7 +285,8 @@ function minetest.calculate_knockback(player, hitter, time_from_last_punch, tool
local wielditem = hitter:get_wielded_item()
--knockback = knockback + 3 * mcl_enchanting.get_enchantment(wielditem, "knockback")
local enchant = mcl_enchanting.get_enchantment(wielditem, "knockback")
knockback = knockback + 3.22 * enchant
local hammer = minetest.get_item_group(wielditem:get_name(), "hammer")
knockback = knockback + 3.22 * enchant + 3.22 * hammer
-- add vertical lift to knockback
local v = player:get_velocity()
local added_v = 0

View File

@ -65,7 +65,7 @@ local hoe_usagehelp = S("Use the hoe on a cultivatable block (by rightclicking i
minetest.register_tool("mcl_farming:hoe_wood", {
description = S("Wood Hoe"),
_tt_help = hoe_tt.."\n"..S("Uses: @1", uses.wood),
_tt_help = hoe_tt,
_doc_items_longdesc = hoe_longdesc,
_doc_items_usagehelp = hoe_usagehelp,
_doc_items_hidden = false,
@ -109,7 +109,7 @@ minetest.register_craft({
minetest.register_tool("mcl_farming:hoe_stone", {
description = S("Stone Hoe"),
_tt_help = hoe_tt.."\n"..S("Uses: @1", uses.stone),
_tt_help = hoe_tt,
_doc_items_longdesc = hoe_longdesc,
_doc_items_usagehelp = hoe_usagehelp,
inventory_image = "farming_tool_stonehoe.png",
@ -147,7 +147,7 @@ minetest.register_craft({
minetest.register_tool("mcl_farming:hoe_iron", {
description = S("Iron Hoe"),
_tt_help = hoe_tt.."\n"..S("Uses: @1", uses.iron),
_tt_help = hoe_tt,
_doc_items_longdesc = hoe_longdesc,
_doc_items_usagehelp = hoe_usagehelp,
inventory_image = "farming_tool_steelhoe.png",
@ -193,7 +193,7 @@ minetest.register_craft({
minetest.register_tool("mcl_farming:hoe_gold", {
description = S("Golden Hoe"),
_tt_help = hoe_tt.."\n"..S("Uses: @1", uses.gold),
_tt_help = hoe_tt,
_doc_items_longdesc = hoe_longdesc,
_doc_items_usagehelp = hoe_usagehelp,
inventory_image = "farming_tool_goldhoe.png",
@ -240,7 +240,7 @@ minetest.register_craft({
minetest.register_tool("mcl_farming:hoe_diamond", {
description = S("Diamond Hoe"),
_tt_help = hoe_tt.."\n"..S("Uses: @1", uses.diamond),
_tt_help = hoe_tt,
_doc_items_longdesc = hoe_longdesc,
_doc_items_usagehelp = hoe_usagehelp,
inventory_image = "farming_tool_diamondhoe.png",
@ -280,7 +280,7 @@ minetest.register_craft({
minetest.register_tool("mcl_farming:hoe_netherite", {
description = S("Netherite Hoe"),
_tt_help = hoe_tt.."\n"..S("Uses: @1", uses.netherite),
_tt_help = hoe_tt,
_doc_items_longdesc = hoe_longdesc,
_doc_items_usagehelp = hoe_usagehelp,
inventory_image = "farming_tool_netheritehoe.png",

View File

@ -331,8 +331,7 @@ vl_projectile.register("mcl_fishing:flying_bobber_entity", {
on_collide_with_solid = function(self, pos, node)
local player = self._owner
self._remove = true
self.object:remove()
mcl_util.remove_entity(self)
-- Make sure the player field is valid for when we create the floating bobber
if not player then return end

View File

@ -151,9 +151,12 @@ function mcl_potions.register_lingering(name, descr, color, def)
local dir = placer:get_look_dir();
local pos = placer:getpos();
minetest.sound_play("mcl_throwing_throw", {pos = pos, gain = 0.4, max_hear_distance = 16}, true)
local obj = minetest.add_entity({x=pos.x+dir.x,y=pos.y+2+dir.y,z=pos.z+dir.z}, id.."_flying")
obj:set_velocity({x=dir.x*velocity,y=dir.y*velocity,z=dir.z*velocity})
obj:set_acceleration({x=dir.x*-3, y=-9.8, z=dir.z*-3})
local obj = vl_projectile.create(id.."_flying",{
pos = vector.offset(pos, dir.x, dir.y + 1.64, dir.z),
owner = placer,
dir = dir,
velocity = velocity,
})
local ent = obj:get_luaentity()
ent._thrower = placer:get_player_name()
ent._potency = item:get_meta():get_int("mcl_potions:potion_potent")
@ -212,6 +215,7 @@ function mcl_potions.register_lingering(name, descr, color, def)
vl_projectile.collides_with_entities,
vl_projectile.collides_with_solids,
},
grace_distance = 3.34, -- 1.5 active region + 1.64 height offset + 0.1 safety
on_collide_with_entity = on_collide,
on_collide_with_solid = function(self, pos, node)
if mod_target and node.name == "mcl_target:target_off" then

View File

@ -46,9 +46,12 @@ function mcl_potions.register_splash(name, descr, color, def)
local dir = placer:get_look_dir();
local pos = placer:get_pos();
minetest.sound_play("mcl_throwing_throw", {pos = pos, gain = 0.4, max_hear_distance = 16}, true)
local obj = minetest.add_entity({x=pos.x+dir.x,y=pos.y+2+dir.y,z=pos.z+dir.z}, id.."_flying")
obj:set_velocity({x=dir.x*velocity,y=dir.y*velocity,z=dir.z*velocity})
obj:set_acceleration({x=dir.x*-3, y=-9.8, z=dir.z*-3})
local obj = vl_projectile.create(id.."_flying",{
pos = vector.offset(pos, dir.x, dir.y + 1.64, dir.z),
owner = placer,
dir = dir,
velocity = velocity,
})
local ent = obj:get_luaentity()
ent._thrower = placer:get_player_name()
ent._potency = item:get_meta():get_int("mcl_potions:potion_potent")
@ -180,6 +183,7 @@ function mcl_potions.register_splash(name, descr, color, def)
vl_projectile.collides_with_entities,
vl_projectile.collides_with_solids,
},
grace_distance = 3.34, -- 1.5 active region + 1.64 height offset + 0.1 safety
on_collide_with_solid = function(self, pos, node)
splash_effects(self, pos, def, 4)

View File

@ -81,7 +81,7 @@ function mcl_potions.register_arrow(name, desc, color, def)
mcl_bows.arrow_entity.on_activate(self, staticdata, dtime_s)
self._arrow_item = arrow_item
end
minetest.register_entity("mcl_potions:"..name.."_arrow_entity", arrow_entity)
vl_projectile.register("mcl_potions:"..name.."_arrow_entity", arrow_entity)
if minetest.get_modpath("mcl_bows") then
minetest.register_craft({

View File

@ -22,9 +22,13 @@ dig_speed_class group:
-- Help texts
local pickaxe_longdesc = S("Pickaxes are mining tools to mine hard blocks, such as stone. A pickaxe can also be used as weapon, but it is rather inefficient.")
local axe_longdesc = S("An axe is your tool of choice to cut down trees, wood-based blocks and other blocks. Axes deal a lot of damage as well, but they are rather slow.")
local sword_longdesc = S("Swords are great in melee combat, as they are fast, deal high damage and can endure countless battles. Swords can also be used to cut down a few particular blocks, such as cobwebs.")
local sword_use = S("To slash multiple enemies, hold the sword in your hand, then use (rightclick) an enemy.")
local shovel_longdesc = S("Shovels are tools for digging coarse blocks, such as dirt, sand and gravel. They can also be used to turn grass blocks to grass paths. Shovels can be used as weapons, but they are very weak.")
local shovel_use = S("To turn a grass block into a grass path, hold the shovel in your hand, then use (rightclick) the top or side of a grass block. This only works when there's air above the grass block.")
local shears_longdesc = S("Shears are tools to shear sheep and to mine a few block types. Shears are a special mining tool and can be used to obtain the original item from grass, leaves and similar blocks that require cutting.")
local shears_use = S("To shear sheep or carve faceless pumpkins, use the “place” key on them. Faces can only be carved at the side of faceless pumpkins. Mining works as usual, but the drops are different for a few blocks.")

View File

@ -53,14 +53,16 @@ function mod.projectile_physics(obj, entity_def, v, a)
-- Update projectile yaw to match velocity direction
if v and le and not le._stuck then
local yaw = minetest.dir_to_yaw(v) + YAW_OFFSET
local pitch = math.asin(vector.normalize(v).y)
local yaw = minetest.dir_to_yaw(v) + YAW_OFFSET + (entity_def._vl_projectile.yaw_offset or 0)
local pitch = math.asin(vector.normalize(v).y) + (entity_def._vl_projectile.pitch_offset or 0)
obj:set_rotation(vector.new(0,yaw,pitch))
end
end
function mod.update_projectile(self, dtime)
if self._removed then return end
local pos = self.object:get_pos()
if not pos then return end
-- Workaround for randomly occurring velocity change between projectile creation
-- and the first time step
@ -82,15 +84,14 @@ function mod.update_projectile(self, dtime)
self.timer = (self.timer or 0) + dtime
local maximum_flight_time = entity_vl_projectile.maximum_time or 300
if (self.timer or 0) > maximum_flight_time then
self.removed = true
self.object:remove()
mcl_util.remove_entity(self)
return
end
-- Run behaviors
local behaviors = entity_vl_projectile.behaviors or {}
for i=1,#behaviors do
if behaviors[i](self, dtime, entity_def, entity_vl_projectile) then
if behaviors[i](self, dtime, entity_def, entity_vl_projectile) or self._removed then
return
end
end
@ -98,6 +99,9 @@ function mod.update_projectile(self, dtime)
if not self._stuck then
mod.projectile_physics(self.object, entity_def)
end
-- Update last position
self._last_pos = pos
end
local function damage_particles(pos, is_critical)
@ -155,10 +159,7 @@ local function handle_player_sticking(self, entity_def, projectile_def, entity)
if self._in_player or self._blocked then return end
if not projectile_def.sticks_in_players then return end
minetest.after(150, function()
self._removed = true
self.object:remove()
end)
minetest.after(150, function() mcl_util.remove_entity(self) end)
-- Handle blocking projectiles
if mcl_shields.is_blocking(entity) then
@ -256,15 +257,14 @@ function mod.replace_with_item_drop(self, pos, projectile_def)
item = projectile_def.item
end
if self._collectable and not minetest.is_creative_enabled("") then
if item and self._collectable and not minetest.is_creative_enabled("") then
local item = minetest.add_item(pos, item)
item:set_velocity(vector.zero())
item:set_yaw(self.object:get_yaw())
end
mcl_burning.extinguish(self.object)
self._removed = true
self.object:remove()
mcl_util.remove_entity(self)
end
local function stuck_on_step(self, dtime, entity_def, projectile_def)
@ -275,8 +275,7 @@ local function stuck_on_step(self, dtime, entity_def, projectile_def)
self._stucktimer = (self._stucktimer or 0) + dtime
if self._stucktimer > STUCK_TIMEOUT then
mcl_burning.extinguish(self.object)
self._removed = true
self.object:remove()
mcl_util.remove_entity(self)
return true
end
@ -295,15 +294,22 @@ local function stuck_on_step(self, dtime, entity_def, projectile_def)
end
end
-- Don't allow players to pick up arrows stuck in them or other players
if self._in_player then return true end
-- Pickup arrow if player is nearby (not in Creative Mode)
if not self._collectable or self._removed then return end
local objects = minetest.get_objects_inside_radius(pos, 1)
for i = 1,#objects do
obj = objects[i]
local obj = objects[i]
if obj:is_player() then
if self._collectable and not minetest.is_creative_enabled(obj:get_player_name()) then
local arrow_item = self._arrow_item
local player_name = obj:get_player_name()
if not minetest.is_creative_enabled(player_name) then
local arrow_item = self._itemstring or self._arrow_item
if arrow_item and minetest.registered_items[arrow_item] and obj:get_inventory():room_for_item("main", arrow_item) then
obj:get_inventory():add_item("main", arrow_item)
self._picked_up = true
minetest.sound_play("item_drop_pickup", {
pos = pos,
@ -311,13 +317,12 @@ local function stuck_on_step(self, dtime, entity_def, projectile_def)
gain = 1.0,
}, true)
end
end
mcl_burning.extinguish(self.object)
self.object:remove()
mcl_util.remove_entity(self)
return
end
return true
end
end
end
@ -334,13 +339,9 @@ end
function mod.collides_with_solids(self, dtime, entity_def, projectile_def)
local pos = self.object:get_pos()
if not pos then return end
-- Don't try to do anything on first update
if not self._last_pos then
self._last_pos = pos
return
end
if not self._last_pos then return end
-- Check if the object can collide with this node
local node = minetest.get_node(pos)
@ -440,8 +441,7 @@ function mod.collides_with_solids(self, dtime, entity_def, projectile_def)
survive_collision = survive_collision(self, entity_def, projectile_def, "node", node, node_def)
end
if not survive_collision then
self._removed = true
self.object:remove()
mcl_util.remove_entity(self)
end
-- Done with behaviors
@ -458,21 +458,13 @@ local function handle_entity_collision(self, entity_def, projectile_def, object)
allow_punching = allow_punching(self, entity_def, projectile_def, object)
end
if DEBUG then
minetest.log("handle_entity_collision("..dump({
self = self,
allow_punching = allow_punching,
entity_def = entity_def,
object = object,
object_id = mcl_util.get_entity_id(object),
luaentity = object:get_luaentity(),
})..")")
end
if not allow_punching then return end
local object_lua = object:get_luaentity()
-- Normally objects should be removed on collision with entities
local survive_collision = projectile_def.survive_collision
-- Apply damage
-- Note: Damage blocking for shields is handled in mcl_shields with an mcl_damage modifier
local do_damage = false
@ -480,6 +472,7 @@ local function handle_entity_collision(self, entity_def, projectile_def, object)
do_damage = true
handle_player_sticking(self, entity_def, projectile_def, object)
survive_collision = true
elseif object_lua and (object_lua.is_mob or object_lua._hittable_by_projectile) then
do_damage = true
end
@ -525,14 +518,12 @@ local function handle_entity_collision(self, entity_def, projectile_def, object)
minetest.sound_play(sound[1], arg2, sound[3])
end
-- Normally objects should be removed on collision with entities
local survive_collision = projectile_def.survive_collision
-- Remove the projectile if it didn't survive
if type(survive_collision) == "function" then
survive_collision = survive_collision(self, entity_def, projectile_def, "entity", object)
end
if not survive_collision then
self._removed = true
self.object:remove()
mcl_util.remove_entity(self)
end
return true

View File

@ -0,0 +1,456 @@
local modname = minetest.get_current_modname()
local modpath = minetest.get_modpath(modname)
local S = minetest.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)
minetest.log(dump({
y_diff = y_diff,
flat_time = self._flat_time,
}))
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 = 25
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
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
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
minetest.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 }
},
})
minetest.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 }
},
})
minetest.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 }
},
})
minetest.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 }
},
})
minetest.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"
})
minetest.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
minetest.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(uses.wood),
on_secondary_use = spear_on_place(uses.wood),
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,
})
minetest.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),
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,
})
minetest.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),
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,
})
minetest.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),
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,
})
minetest.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),
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"
})
minetest.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),
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
minetest.register_craft({
output = "vl_weaponry:hammer_"..t,
recipe = {
{ m, b, m },
{ m, s, m },
{ b, s, b },
}
})
minetest.register_craft({
output = "vl_weaponry:spear_"..t,
recipe = {
{ m, b, b },
{ b, s, b },
{ b, b, s },
}
})
end

View File

@ -0,0 +1,3 @@
name = vl_weaponry
author = Herowl
depends = mcl_sounds, mcl_init, mcl_bows

View File

@ -752,9 +752,10 @@ end, -200)
minetest.register_on_punchplayer(function(player, hitter, time_from_last_punch, tool_capabilities, dir, damage)
-- attack reach limit
if hitter and hitter:is_player() then
local weapon = hitter:get_wielded_item()
local player_pos = player:get_pos()
local hitter_pos = hitter:get_pos()
if vector.distance(player_pos, hitter_pos) > 3 then
if vector.distance(player_pos, hitter_pos) > (weapon:get_definition().range or 3) then
damage = 0
return damage
end

Binary file not shown.

After

Width:  |  Height:  |  Size: 189 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 183 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 213 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 157 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 255 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 201 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 210 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 171 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 228 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 215 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 B