added mod files
|
@ -0,0 +1,37 @@
|
|||
# [Mod] Obsidian-Mese [obsidianmese]
|
||||
|
||||
This MOD for Minetest adds more use for Mese and Obsidian. Add more variety of tools and blocks.
|
||||
Further Description added by MisterE:
|
||||
Tools added:
|
||||
obsidianmese_sword- a good sword that can be crafted with obsidian and mese
|
||||
obsidianmese_sword_engraved - a uncraftable sword that shoots shards that deal damage, or explode if they hit a node, removing 1 node and causing damage in a radius of 4. THIS IS SUPPOSED TO BE DROPPED BY DIFFICULT MOBS
|
||||
|
||||
obsidianmese_pick - a good pickaxe that can be made with obsidian and mese
|
||||
obsidianmese_pick_engraved - a good pickaxe that can be made with obsidian and diamond
|
||||
obsidianmese_axe - cuts down all tree nodes above the one chopped
|
||||
obsidianmese_hoe - can be used to hoe 4 dirt nodes at once
|
||||
obsidianmese_shovel - a good shovel, or can be used to compact soil to form paths
|
||||
|
||||
also adds: meseapple, 4 of which are craftable from a mese block and 4 apples. It restores full health when eaten.
|
||||
|
||||
Original mod included: obsidianmese_boat, which was a boat for lava. It was removed by MisterE from this version.
|
||||
Original mod included: balrog sword, this is still in the mod, but commented out. It failed testing by MisterE, and was left commented out.
|
||||
|
||||
|
||||
## Boat -- removed from mod in this modification version
|
||||
|
||||
* Originally by PilzAdam (MIT)
|
||||
* Various Minetest developers and contributors (MIT)
|
||||
* SaKeL (2018)
|
||||
|
||||
### Textures
|
||||
|
||||
* SaKeL (CC BY-SA 3.0)
|
||||
|
||||
### Mesh model -- removed from mod in this modification version
|
||||
|
||||
Boat mesh (`models/mcl_boats_boat.b3d`) created by 22i.
|
||||
Source: https://github.com/22i/minecraft-voxel-blender-models
|
||||
|
||||
License of boat model:
|
||||
GNU GPLv3 <https://www.gnu.org/licenses/gpl-3.0.html>
|
|
@ -0,0 +1,531 @@
|
|||
obsidianmese = {}
|
||||
-- save how many bullets owner fired
|
||||
obsidianmese.fired_table = {}
|
||||
local enable_particles = minetest.settings:get_bool("enable_particles")
|
||||
|
||||
local function bound(x, minb, maxb)
|
||||
if x < minb then
|
||||
return minb
|
||||
elseif x > maxb then
|
||||
return maxb
|
||||
else
|
||||
return x
|
||||
end
|
||||
end
|
||||
|
||||
--- Punch damage calculator.
|
||||
-- By default, this just calculates damage in the vanilla way. Switch it out for something else to change the default damage mechanism for mobs.
|
||||
-- @param ObjectRef player
|
||||
-- @param ?ObjectRef puncher
|
||||
-- @param number time_from_last_punch
|
||||
-- @param table tool_capabilities
|
||||
-- @param ?vector direction
|
||||
-- @param ?Id attacker
|
||||
-- @return number The calculated damage
|
||||
-- @author raymoo
|
||||
function obsidianmese.damage_calculator(player, puncher, tflp, caps, direction, attacker)
|
||||
local a_groups = player:get_armor_groups() or {}
|
||||
local full_punch_interval = caps.full_punch_interval or 1.4
|
||||
local time_prorate = bound(tflp / full_punch_interval, 0, 1)
|
||||
|
||||
local damage = 0
|
||||
for group, damage_rating in pairs(caps.damage_groups or {}) do
|
||||
local armor_rating = a_groups[group] or 0
|
||||
damage = damage + damage_rating * (armor_rating / 100)
|
||||
end
|
||||
|
||||
return math.floor(damage * time_prorate)
|
||||
end
|
||||
|
||||
-- particles
|
||||
function obsidianmese.add_effects(pos)
|
||||
if not enable_particles then return end
|
||||
|
||||
return minetest.add_particlespawner({
|
||||
amount = 2,
|
||||
time = 0,
|
||||
minpos = {x=pos.x-1, y=pos.y+0.5, z=pos.z-1},
|
||||
maxpos = {x=pos.x+1, y=pos.y+1.5, z=pos.z+1},
|
||||
minvel = {x=-0.1, y=-0.1, z=-0.1},
|
||||
maxvel = {x=0.3, y=-0.3, z=0.3},
|
||||
minacc = vector.new(),
|
||||
maxacc = vector.new(),
|
||||
minexptime = 1,
|
||||
maxexptime = 5,
|
||||
minsize = .5,
|
||||
maxsize = 1.5,
|
||||
texture = "obsidianmese_chest_particle.png",
|
||||
glow = 7
|
||||
})
|
||||
end
|
||||
|
||||
-- check for player near by to activate particles
|
||||
function obsidianmese.check_around_radius(pos)
|
||||
local player_near = false
|
||||
|
||||
for _,obj in ipairs(minetest.get_objects_inside_radius(pos, 16)) do
|
||||
if obj:is_player() then
|
||||
player_near = true
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
return player_near
|
||||
end
|
||||
|
||||
-- check if within physical map limits (-30911 to 30927)
|
||||
function obsidianmese.within_limits(pos, radius)
|
||||
if (pos.x - radius) > -30913
|
||||
and (pos.x + radius) < 30928
|
||||
and (pos.y - radius) > -30913
|
||||
and (pos.y + radius) < 30928
|
||||
and (pos.z - radius) > -30913
|
||||
and (pos.z + radius) < 30928 then
|
||||
return true -- within limits
|
||||
end
|
||||
|
||||
return false -- beyond limits
|
||||
end
|
||||
|
||||
-- remember how many bullets player fired i.e. {SaKeL: 1,...}
|
||||
function obsidianmese.sync_fired_table(owner)
|
||||
if obsidianmese.fired_table[owner] ~= nil then
|
||||
if obsidianmese.fired_table[owner] < 0 then
|
||||
obsidianmese.fired_table[owner] = 0
|
||||
else
|
||||
obsidianmese.fired_table[owner] = obsidianmese.fired_table[owner] - 1
|
||||
end
|
||||
-- print(minetest.serialize(fired_table))
|
||||
end
|
||||
end
|
||||
|
||||
function obsidianmese.fire_sword(itemstack, user, pointed_thing)
|
||||
if not user:get_player_control().RMB then return end
|
||||
|
||||
local speed = 8
|
||||
local pos = user:getpos()
|
||||
local v = user:get_look_dir()
|
||||
local player_name = user:get_player_name()
|
||||
|
||||
if not obsidianmese.fired_table[player_name] or obsidianmese.fired_table[player_name] < 0 then
|
||||
obsidianmese.fired_table[player_name] = 0
|
||||
end
|
||||
|
||||
if obsidianmese.fired_table[player_name] >= 1 then
|
||||
minetest.chat_send_player(player_name, "You can shoot 1 shot at the time!")
|
||||
return itemstack
|
||||
end
|
||||
|
||||
obsidianmese.fired_table[player_name] = obsidianmese.fired_table[player_name] + 1
|
||||
|
||||
-- print(minetest.serialize(obsidianmese.fired_table))
|
||||
|
||||
-- adjust position from where the bullet will be fired based on the look direction
|
||||
-- prevents hitting the node when looking/shooting down from the edge
|
||||
pos.x = pos.x + v.x
|
||||
pos.z = pos.z + v.z
|
||||
if v.y > 0.4 or v.y < -0.4 then
|
||||
pos.y = pos.y + v.y
|
||||
else
|
||||
pos.y = pos.y + 1
|
||||
end
|
||||
|
||||
-- play shoot attack sound
|
||||
minetest.sound_play("obsidianmese_throwing", {
|
||||
pos = pos,
|
||||
gain = 1.0, -- default
|
||||
max_hear_distance = 10,
|
||||
})
|
||||
|
||||
local obj = minetest.add_entity(pos, "obsidianmese:sword_bullet")
|
||||
local ent = obj:get_luaentity()
|
||||
|
||||
if ent then
|
||||
ent._owner = player_name
|
||||
|
||||
v.x = v.x * speed
|
||||
v.y = v.y * speed
|
||||
v.z = v.z * speed
|
||||
|
||||
obj:setvelocity(v)
|
||||
end
|
||||
|
||||
-- wear tool
|
||||
local wdef = itemstack:get_definition()
|
||||
itemstack:add_wear(65535 / (150 - 1), pointed_thing.above)
|
||||
-- Tool break sound
|
||||
if itemstack:get_count() == 0 and wdef.sound and wdef.sound.breaks then
|
||||
minetest.sound_play(wdef.sound.breaks, {pos = pointed_thing.above, gain = 0.5})
|
||||
end
|
||||
return itemstack
|
||||
end
|
||||
|
||||
function obsidianmese.add_wear(itemstack, pos)
|
||||
-- wear tool
|
||||
local wdef = itemstack:get_definition()
|
||||
itemstack:add_wear(65535 / (400 - 1))
|
||||
-- Tool break sound
|
||||
if itemstack:get_count() == 0 and wdef.sound and wdef.sound.breaks then
|
||||
minetest.sound_play(wdef.sound.breaks, {pos = pos, gain = 0.5})
|
||||
end
|
||||
|
||||
return itemstack
|
||||
end
|
||||
|
||||
-- prevent pick axe engraved of placing item when clicken on one of the items from this list
|
||||
local pick_engraved_place_blacklist = {
|
||||
["xdecor:itemframe"] = true
|
||||
}
|
||||
|
||||
function obsidianmese.pick_engraved_place(itemstack, placer, pointed_thing)
|
||||
local idx = placer:get_wield_index() + 1 -- item to right of wielded tool
|
||||
local inv = placer:get_inventory()
|
||||
local stack = inv:get_stack("main", idx) -- stack to right of tool
|
||||
local stack_name = stack:get_name()
|
||||
local under = pointed_thing.under
|
||||
local above = pointed_thing.above
|
||||
local node_under = minetest.get_node(under)
|
||||
local udef = {}
|
||||
local temp_stack = ""
|
||||
|
||||
-- handle nodes
|
||||
if pointed_thing.type == "node" then
|
||||
local pos = minetest.get_pointed_thing_position(pointed_thing)
|
||||
local pointed_node = minetest.get_node(pos)
|
||||
|
||||
-- check if we have to use default on_place first
|
||||
if pick_engraved_place_blacklist[pointed_node.name] ~= nil then
|
||||
return minetest.item_place(itemstack, placer, pointed_thing)
|
||||
end
|
||||
|
||||
if pointed_node ~= nil and stack_name ~= "" then
|
||||
local stack_def = minetest.registered_nodes[stack_name]
|
||||
local stack_name_split = string.split(stack_name, ":")
|
||||
local stack_mod = stack_name_split[1]
|
||||
|
||||
udef = minetest.registered_nodes[stack_name]
|
||||
-- print(dump(udef))
|
||||
|
||||
-- not for farming - that should be part of a hoe
|
||||
if stack_mod ~= "farming" or stack_mod ~= "farming_addons" then
|
||||
if udef and udef.on_place then
|
||||
temp_stack = udef.on_place(stack, placer, pointed_thing) or stack
|
||||
inv:set_stack("main", idx, temp_stack)
|
||||
|
||||
-- itemstack = obsidianmese.add_wear(itemstack)
|
||||
|
||||
-- play sound
|
||||
-- if udef.sounds then
|
||||
-- if udef.sounds.place then
|
||||
-- udef.sounds.place.to_player = placer:get_player_name()
|
||||
-- minetest.sound_play(udef.sounds.place)
|
||||
-- end
|
||||
-- end
|
||||
|
||||
return itemstack
|
||||
elseif udef and udef.on_use then
|
||||
temp_stack = udef.on_use(stack, placer, pointed_thing) or stack
|
||||
inv:set_stack("main", idx, temp_stack)
|
||||
|
||||
-- itemstack = obsidianmese.add_wear(itemstack)
|
||||
return itemstack
|
||||
end
|
||||
end
|
||||
|
||||
-- handle default torch placement
|
||||
if stack_name == "default:torch" then
|
||||
local wdir = minetest.dir_to_wallmounted(vector.subtract(under, above))
|
||||
local fakestack = stack
|
||||
|
||||
if wdir == 0 then
|
||||
fakestack:set_name("default:torch_ceiling")
|
||||
elseif wdir == 1 then
|
||||
fakestack:set_name("default:torch")
|
||||
else
|
||||
fakestack:set_name("default:torch_wall")
|
||||
end
|
||||
|
||||
temp_stack = minetest.item_place(fakestack, placer, pointed_thing, wdir)
|
||||
|
||||
temp_stack:set_name("default:torch")
|
||||
inv:set_stack("main", idx, temp_stack)
|
||||
|
||||
-- itemstack = obsidianmese.add_wear(itemstack)
|
||||
|
||||
-- play sound
|
||||
-- if udef and udef.sounds then
|
||||
-- if udef.sounds.place then
|
||||
-- udef.sounds.place.to_player = placer:get_player_name()
|
||||
-- minetest.sound_play(udef.sounds.place)
|
||||
-- end
|
||||
-- end
|
||||
|
||||
return itemstack
|
||||
end
|
||||
end
|
||||
-- if everything else fails use default on_place
|
||||
stack = minetest.item_place(stack, placer, pointed_thing)
|
||||
inv:set_stack("main", idx, stack)
|
||||
|
||||
-- play sound
|
||||
-- if udef and udef.sounds then
|
||||
-- if udef.sounds.place then
|
||||
-- udef.sounds.place.to_player = placer:get_player_name()
|
||||
-- minetest.sound_play(udef.sounds.place)
|
||||
-- end
|
||||
-- end
|
||||
|
||||
return itemstack
|
||||
end
|
||||
end
|
||||
|
||||
function obsidianmese.shovel_place(itemstack, placer, pointed_thing)
|
||||
local pt = pointed_thing
|
||||
|
||||
-- check if pointing at a node
|
||||
if not pt then
|
||||
return
|
||||
end
|
||||
if pt.type ~= "node" then
|
||||
return
|
||||
end
|
||||
|
||||
local under = minetest.get_node(pt.under)
|
||||
local p = {x=pt.under.x, y=pt.under.y+1, z=pt.under.z}
|
||||
local above = minetest.get_node(p)
|
||||
|
||||
-- return if any of the nodes is not registered
|
||||
if not minetest.registered_nodes[under.name] then
|
||||
return
|
||||
end
|
||||
if not minetest.registered_nodes[above.name] then
|
||||
return
|
||||
end
|
||||
|
||||
-- check if the node above the pointed thing is air
|
||||
if above.name ~= "air" then
|
||||
return
|
||||
end
|
||||
|
||||
if minetest.is_protected(pt.under, placer:get_player_name()) then
|
||||
minetest.record_protection_violation(pt.under, placer:get_player_name())
|
||||
return
|
||||
end
|
||||
|
||||
-- dirt path
|
||||
if under.name == "default:dirt" and
|
||||
under.name ~= "obsidianmese:path_dirt" then
|
||||
minetest.set_node(pt.under, {name = "obsidianmese:path_dirt"})
|
||||
|
||||
-- grass path
|
||||
elseif (under.name == "default:dirt_with_grass" or
|
||||
under.name == "default:dirt_with_grass_footsteps" or
|
||||
under.name == "default:dirt_with_dry_grass" or
|
||||
under.name == "default:dirt_with_snow" or
|
||||
under.name == "default:dirt_with_rainforest_litter") and
|
||||
under.name ~= "obsidianmese:path_grass" then
|
||||
minetest.set_node(pt.under, {name = "obsidianmese:path_grass"})
|
||||
|
||||
-- sand path
|
||||
elseif under.name == "default:sand" and
|
||||
under.name ~= "obsidianmese:path_sand" then
|
||||
minetest.set_node(pt.under, {name = "obsidianmese:path_sand"})
|
||||
|
||||
-- desert sand path
|
||||
elseif under.name == "default:desert_sand" and
|
||||
under.name ~= "obsidianmese:path_desert_sand" then
|
||||
minetest.set_node(pt.under, {name = "obsidianmese:path_desert_sand"})
|
||||
|
||||
-- silver sand path
|
||||
elseif under.name == "default:silver_sand" and
|
||||
under.name ~= "obsidianmese:path_silver_sand" then
|
||||
minetest.set_node(pt.under, {name = "obsidianmese:path_silver_sand"})
|
||||
|
||||
-- snow path
|
||||
elseif under.name == "default:snowblock" and
|
||||
under.name ~= "obsidianmese:path_snowblock" then
|
||||
minetest.set_node(pt.under, {name = "obsidianmese:path_snowblock"})
|
||||
|
||||
else
|
||||
return
|
||||
end
|
||||
|
||||
-- play sound
|
||||
minetest.sound_play("default_dig_crumbly", {
|
||||
pos = pt.under,
|
||||
gain = 0.5
|
||||
})
|
||||
-- add wear
|
||||
itemstack = obsidianmese.add_wear(itemstack)
|
||||
return itemstack
|
||||
end
|
||||
|
||||
-- axe dig upwards
|
||||
function obsidianmese.dig_up(pos, node, digger)
|
||||
if not digger then
|
||||
return
|
||||
end
|
||||
|
||||
local wielditemname = digger:get_wielded_item():get_name()
|
||||
local whitelist = {
|
||||
["obsidianmese:axe"] = true,
|
||||
["obsidianmese:enchanted_axe_durable"] = true,
|
||||
["obsidianmese:enchanted_axe_fast"] = true
|
||||
}
|
||||
|
||||
if not whitelist[wielditemname] then
|
||||
return
|
||||
end
|
||||
|
||||
local np = {x = pos.x, y = pos.y + 1, z = pos.z}
|
||||
local nn = minetest.get_node(np)
|
||||
|
||||
if nn.name == node.name then
|
||||
local branches_pos = minetest.find_nodes_in_area(
|
||||
{x = np.x - 1, y = np.y, z = np.z - 1},
|
||||
{x = np.x + 1, y = np.y + 1, z = np.z + 1},
|
||||
node.name
|
||||
)
|
||||
|
||||
minetest.node_dig(np, nn, digger)
|
||||
|
||||
-- try to find a node texture
|
||||
local def = minetest.registered_nodes[nn.name]
|
||||
local texture = "default_dirt.png"
|
||||
|
||||
if def then
|
||||
if def.tiles then
|
||||
if #def.tiles > 0 then
|
||||
if type(def.tiles[1]) == "string" then
|
||||
texture = def.tiles[1]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- add particles only when not too far
|
||||
minetest.add_particlespawner({
|
||||
amount = math.random(1, 3),
|
||||
time = 0.5,
|
||||
minpos = {x=np.x-0.7, y=np.y, z=np.z-0.7},
|
||||
maxpos = {x=np.x+0.7, y=np.y+0.75, z=np.z+0.7},
|
||||
minvel = {x = -0.5, y = -4, z = -0.5},
|
||||
maxvel = {x = 0.5, y = -2, z = 0.5},
|
||||
minacc = {x = -0.5, y = -4, z = -0.5},
|
||||
maxacc = {x = 0.5, y = -2, z = 0.5},
|
||||
minexptime = 0.5,
|
||||
maxexptime = 1,
|
||||
minsize = 0.5,
|
||||
maxsize = 2,
|
||||
collisiondetection = true,
|
||||
texture = texture
|
||||
})
|
||||
|
||||
if #branches_pos > 0 then
|
||||
for i = 1, #branches_pos do
|
||||
-- prevent infinite loop when node protected
|
||||
if minetest.is_protected(branches_pos[i], digger:get_player_name()) then
|
||||
break
|
||||
end
|
||||
|
||||
obsidianmese.dig_up({x = branches_pos[i].x, y = branches_pos[i].y - 1, z = branches_pos[i].z}, node, digger)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function obsidianmese.register_capitator()
|
||||
local trees = {
|
||||
"default:tree",
|
||||
"default:jungletree",
|
||||
"default:pine_tree",
|
||||
"default:acacia_tree",
|
||||
"default:aspen_tree"
|
||||
}
|
||||
|
||||
for i = 1, #trees do
|
||||
local ndef = minetest.registered_nodes[trees[i]]
|
||||
local prev_after_dig = ndef.after_dig_node
|
||||
local func = function(pos, node, metadata, digger)
|
||||
obsidianmese.dig_up(pos, node, digger)
|
||||
end
|
||||
|
||||
if prev_after_dig then
|
||||
func = function(pos, node, metadata, digger)
|
||||
prev_after_dig(pos, node, metadata, digger)
|
||||
obsidianmese.dig_up(pos, node, digger)
|
||||
end
|
||||
end
|
||||
minetest.override_item(trees[i], {after_dig_node = func})
|
||||
end
|
||||
end
|
||||
|
||||
-- Taken from WorldEdit
|
||||
-- Determines the axis in which a player is facing, returning an axis ("x", "y", or "z") and the sign (1 or -1)
|
||||
function obsidianmese.player_axis(player)
|
||||
local dir = player:get_look_dir()
|
||||
local x, y, z = math.abs(dir.x), math.abs(dir.y), math.abs(dir.z)
|
||||
if x > y then
|
||||
if x > z then
|
||||
return "x", dir.x > 0 and 1 or -1
|
||||
end
|
||||
elseif y > z then
|
||||
return "y", dir.y > 0 and 1 or -1
|
||||
end
|
||||
return "z", dir.z > 0 and 1 or -1
|
||||
end
|
||||
|
||||
function obsidianmese.hoe_on_use(itemstack, user, pointed_thing)
|
||||
local pt = pointed_thing
|
||||
-- check if pointing at a node
|
||||
if not pt then
|
||||
return
|
||||
end
|
||||
if pt.type ~= "node" then
|
||||
return
|
||||
end
|
||||
|
||||
local under = minetest.get_node(pt.under)
|
||||
local p = {x=pt.under.x, y=pt.under.y+1, z=pt.under.z}
|
||||
local above = minetest.get_node(p)
|
||||
|
||||
-- return if any of the nodes is not registered
|
||||
if not minetest.registered_nodes[under.name] then
|
||||
return
|
||||
end
|
||||
if not minetest.registered_nodes[above.name] then
|
||||
return
|
||||
end
|
||||
|
||||
-- check if the node above the pointed thing is air
|
||||
if above.name ~= "air" then
|
||||
return
|
||||
end
|
||||
|
||||
-- check if pointing at soil
|
||||
if minetest.get_item_group(under.name, "soil") ~= 1 then
|
||||
return
|
||||
end
|
||||
|
||||
-- check if (wet) soil defined
|
||||
local regN = minetest.registered_nodes
|
||||
if regN[under.name].soil == nil or regN[under.name].soil.wet == nil or regN[under.name].soil.dry == nil then
|
||||
return
|
||||
end
|
||||
|
||||
if minetest.is_protected(pt.under, user:get_player_name()) then
|
||||
minetest.record_protection_violation(pt.under, user:get_player_name())
|
||||
return
|
||||
end
|
||||
if minetest.is_protected(pt.above, user:get_player_name()) then
|
||||
minetest.record_protection_violation(pt.above, user:get_player_name())
|
||||
return
|
||||
end
|
||||
|
||||
-- turn the node into soil and play sound
|
||||
minetest.set_node(pt.under, {name = regN[under.name].soil.dry})
|
||||
minetest.sound_play("default_dig_crumbly", {
|
||||
pos = pt.under,
|
||||
gain = 0.5,
|
||||
})
|
||||
end
|
|
@ -0,0 +1,90 @@
|
|||
--
|
||||
-- Craft Items
|
||||
--
|
||||
|
||||
-- mese apple
|
||||
minetest.register_craftitem("obsidianmese:mese_apple", {
|
||||
description = "Mese apple [restores full health]",
|
||||
inventory_image = "obsidianmese_apple.png",
|
||||
on_use = function(itemstack, user, pointed_thing)
|
||||
|
||||
minetest.sound_play("obsidianmese_apple_eat", {
|
||||
pos = user:getpos(),
|
||||
max_hear_distance = 32,
|
||||
gain = 0.5,
|
||||
})
|
||||
|
||||
user:set_hp(20)
|
||||
itemstack:take_item()
|
||||
return itemstack
|
||||
end
|
||||
})
|
||||
|
||||
--
|
||||
-- Crafting
|
||||
-- no craft for engraved sword, that is rare item obtained only by drops
|
||||
--
|
||||
|
||||
|
||||
minetest.register_craft({
|
||||
output = "obsidianmese:sword",
|
||||
recipe = {
|
||||
{"", "default:mese_crystal", ""},
|
||||
{"default:obsidian_shard", "default:mese_crystal", "default:obsidian_shard"},
|
||||
{"", "default:obsidian_shard", ""},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "obsidianmese:pick",
|
||||
recipe = {
|
||||
{"default:mese_crystal", "default:mese_crystal", "default:mese_crystal"},
|
||||
{"", "default:obsidian_shard", ""},
|
||||
{"", "default:obsidian_shard", ""},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "obsidianmese:shovel",
|
||||
recipe = {
|
||||
{"default:mese_crystal"},
|
||||
{"default:obsidian_shard"},
|
||||
{"default:obsidian_shard"},
|
||||
}
|
||||
})
|
||||
-- a tree capitator axe is powerful, so I changed one of the required mese crystals into a mese block
|
||||
minetest.register_craft({
|
||||
output = "obsidianmese:axe",
|
||||
recipe = {
|
||||
{"default:mese_crystal", "default:mese"},
|
||||
{"default:mese_crystal", "default:obsidian_shard"},
|
||||
{"", "default:obsidian_shard"},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "obsidianmese:hoe",
|
||||
recipe = {
|
||||
{"default:mese_crystal", "default:mese_crystal", ""},
|
||||
{"", "default:obsidian_shard", ""},
|
||||
{"", "default:obsidian_shard", ""},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "obsidianmese:pick_engraved",
|
||||
recipe = {
|
||||
{"default:diamond", "default:diamond", "default:diamond"},
|
||||
{"", "default:obsidian_shard", ""},
|
||||
{"", "default:obsidian_shard", ""},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "obsidianmese:mese_apple 4",
|
||||
recipe = {
|
||||
{"", "default:apple", ""},
|
||||
{"default:apple","default:mese", "default:apple"},
|
||||
{"", "default:apple", ""},
|
||||
}
|
||||
})
|
|
@ -0,0 +1,2 @@
|
|||
default
|
||||
tnt
|
|
@ -0,0 +1 @@
|
|||
This MOD for Minetest adds obsidian and mese tools and items.
|
|
@ -0,0 +1,14 @@
|
|||
--
|
||||
-- Init
|
||||
--
|
||||
|
||||
dofile(minetest.get_modpath("obsidianmese").."/api.lua")
|
||||
dofile(minetest.get_modpath("obsidianmese").."/tools.lua")
|
||||
dofile(minetest.get_modpath("obsidianmese").."/nodes.lua")
|
||||
|
||||
|
||||
dofile(minetest.get_modpath("obsidianmese").."/crafting.lua")
|
||||
|
||||
obsidianmese.register_capitator()
|
||||
|
||||
print("[Mod] ObsidianMese Loaded.")
|
|
@ -0,0 +1,64 @@
|
|||
License of source code
|
||||
----------------------
|
||||
|
||||
The MIT License (MIT)
|
||||
Copyright (C) 2012-2016 PilzAdam
|
||||
Copyright (C) 2012-2016 Various Minetest developers and contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this
|
||||
software and associated documentation files (the "Software"), to deal in the Software
|
||||
without restriction, including without limitation the rights to use, copy, modify, merge,
|
||||
publish, distribute, sublicense, and/or sell copies of the Software, and to permit
|
||||
persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or
|
||||
substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
|
||||
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
|
||||
FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
|
||||
For more details:
|
||||
https://opensource.org/licenses/MIT
|
||||
|
||||
note: this minetest mod has been modified from the version found on minetest_gamers repositories. Latest Modifications are by MisterE
|
||||
|
||||
Licenses of media (textures and model)
|
||||
--------------------------------------
|
||||
|
||||
Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0)
|
||||
Copyright (C) 2012-2016 Zeg9
|
||||
Copyright (C) 2012-2016 thetoon
|
||||
Copyright (C) 2012-2016 PavelS(SokolovPavel)
|
||||
Copyright (C) 2016 sofar (sofar@foo-projects.org)
|
||||
|
||||
You are free to:
|
||||
Share — copy and redistribute the material in any medium or format.
|
||||
Adapt — remix, transform, and build upon the material for any purpose, even commercially.
|
||||
The licensor cannot revoke these freedoms as long as you follow the license terms.
|
||||
|
||||
Under the following terms:
|
||||
|
||||
Attribution — You must give appropriate credit, provide a link to the license, and
|
||||
indicate if changes were made. You may do so in any reasonable manner, but not in any way
|
||||
that suggests the licensor endorses you or your use.
|
||||
|
||||
ShareAlike — If you remix, transform, or build upon the material, you must distribute
|
||||
your contributions under the same license as the original.
|
||||
|
||||
No additional restrictions — You may not apply legal terms or technological measures that
|
||||
legally restrict others from doing anything the license permits.
|
||||
|
||||
Notices:
|
||||
|
||||
You do not have to comply with the license for elements of the material in the public
|
||||
domain or where your use is permitted by an applicable exception or limitation.
|
||||
No warranties are given. The license may not give you all of the permissions necessary
|
||||
for your intended use. For example, other rights such as publicity, privacy, or moral
|
||||
rights may limit how you use the material.
|
||||
|
||||
For more details:
|
||||
http://creativecommons.org/licenses/by-sa/3.0/
|
|
@ -0,0 +1,3 @@
|
|||
name = obsidianmese
|
||||
description = This MOD for Minetest adds obsidian and mese tools and items.
|
||||
depends = default, tnt
|
|
@ -0,0 +1,155 @@
|
|||
--
|
||||
-- Nodes
|
||||
--
|
||||
|
||||
-- dirt path
|
||||
minetest.register_node("obsidianmese:path_dirt", {
|
||||
description = "Dirt Path",
|
||||
drawtype = "nodebox",
|
||||
tiles = {"obsidianmese_dirt_path_top.png", "obsidianmese_dirt_path_top.png", "obsidianmese_dirt_path_side.png"},
|
||||
is_ground_content = false,
|
||||
paramtype = "light",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {-1/2, -1/2, -1/2, 1/2, 1/2-1/16, 1/2},
|
||||
},
|
||||
collision_box = {
|
||||
type = "fixed",
|
||||
fixed = {-1/2, -1/2, -1/2, 1/2, 1/2-1/16, 1/2},
|
||||
},
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {-1/2, -1/2, -1/2, 1/2, 1/2-1/16, 1/2},
|
||||
},
|
||||
drop = "default:dirt",
|
||||
is_ground_content = false,
|
||||
groups = {crumbly = 3, not_in_creative_inventory = 1},
|
||||
sounds = default.node_sound_dirt_defaults(),
|
||||
})
|
||||
|
||||
-- grass path
|
||||
minetest.register_node("obsidianmese:path_grass", {
|
||||
description = "Grass Path",
|
||||
drawtype = "nodebox",
|
||||
tiles = {"obsidianmese_grass_path_top.png", "obsidianmese_dirt_path_top.png", "obsidianmese_dirt_path_side.png"},
|
||||
is_ground_content = false,
|
||||
paramtype = "light",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {-1/2, -1/2, -1/2, 1/2, 1/2-1/16, 1/2},
|
||||
},
|
||||
collision_box = {
|
||||
type = "fixed",
|
||||
fixed = {-1/2, -1/2, -1/2, 1/2, 1/2-1/16, 1/2},
|
||||
},
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {-1/2, -1/2, -1/2, 1/2, 1/2-1/16, 1/2},
|
||||
},
|
||||
drop = "default:dirt",
|
||||
is_ground_content = false,
|
||||
groups = {crumbly = 3, not_in_creative_inventory = 1},
|
||||
sounds = default.node_sound_dirt_defaults({
|
||||
footstep = {name = "default_grass_footstep", gain = 0.25},
|
||||
}),
|
||||
})
|
||||
|
||||
-- sand path
|
||||
minetest.register_node("obsidianmese:path_sand", {
|
||||
description = "Sand Path",
|
||||
drawtype = "nodebox",
|
||||
tiles = {"obsidianmese_sand_path_top.png", "obsidianmese_sand_path_top.png", "obsidianmese_sand_path_side.png"},
|
||||
is_ground_content = false,
|
||||
paramtype = "light",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {-1/2, -1/2, -1/2, 1/2, 1/2-1/16, 1/2},
|
||||
},
|
||||
collision_box = {
|
||||
type = "fixed",
|
||||
fixed = {-1/2, -1/2, -1/2, 1/2, 1/2-1/16, 1/2},
|
||||
},
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {-1/2, -1/2, -1/2, 1/2, 1/2-1/16, 1/2},
|
||||
},
|
||||
drop = "default:sand",
|
||||
groups = {crumbly = 3, falling_node = 1, not_in_creative_inventory = 1},
|
||||
sounds = default.node_sound_sand_defaults(),
|
||||
})
|
||||
|
||||
-- desert sand path
|
||||
minetest.register_node("obsidianmese:path_desert_sand", {
|
||||
description = "Desert Sand Path",
|
||||
drawtype = "nodebox",
|
||||
tiles = {"obsidianmese_desert_sand_path_top.png", "obsidianmese_desert_sand_path_top.png", "obsidianmese_desert_sand_path_side.png"},
|
||||
is_ground_content = false,
|
||||
paramtype = "light",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {-1/2, -1/2, -1/2, 1/2, 1/2-1/16, 1/2},
|
||||
},
|
||||
collision_box = {
|
||||
type = "fixed",
|
||||
fixed = {-1/2, -1/2, -1/2, 1/2, 1/2-1/16, 1/2},
|
||||
},
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {-1/2, -1/2, -1/2, 1/2, 1/2-1/16, 1/2},
|
||||
},
|
||||
drop = "default:desert_sand",
|
||||
groups = {crumbly = 3, falling_node = 1, not_in_creative_inventory = 1},
|
||||
sounds = default.node_sound_sand_defaults(),
|
||||
})
|
||||
|
||||
-- silver sand
|
||||
minetest.register_node("obsidianmese:path_silver_sand", {
|
||||
description = "Silver Sand Path",
|
||||
drawtype = "nodebox",
|
||||
tiles = {"obsidianmese_silver_sand_path_top.png", "obsidianmese_silver_sand_path_top.png", "obsidianmese_silver_sand_path_side.png"},
|
||||
is_ground_content = false,
|
||||
paramtype = "light",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {-1/2, -1/2, -1/2, 1/2, 1/2-1/16, 1/2},
|
||||
},
|
||||
collision_box = {
|
||||
type = "fixed",
|
||||
fixed = {-1/2, -1/2, -1/2, 1/2, 1/2-1/16, 1/2},
|
||||
},
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {-1/2, -1/2, -1/2, 1/2, 1/2-1/16, 1/2},
|
||||
},
|
||||
drop = "default:silver_sand",
|
||||
groups = {crumbly = 3, falling_node = 1, not_in_creative_inventory = 1},
|
||||
sounds = default.node_sound_sand_defaults(),
|
||||
})
|
||||
|
||||
-- snow path
|
||||
minetest.register_node("obsidianmese:path_snowblock", {
|
||||
description = "Snow Path",
|
||||
drawtype = "nodebox",
|
||||
tiles = {"obsidianmese_snow_path_top.png", "obsidianmese_snow_path_top.png", "obsidianmese_snow_path_side.png"},
|
||||
is_ground_content = false,
|
||||
paramtype = "light",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {-1/2, -1/2, -1/2, 1/2, 1/2-1/16, 1/2},
|
||||
},
|
||||
collision_box = {
|
||||
type = "fixed",
|
||||
fixed = {-1/2, -1/2, -1/2, 1/2, 1/2-1/16, 1/2},
|
||||
},
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {-1/2, -1/2, -1/2, 1/2, 1/2-1/16, 1/2},
|
||||
},
|
||||
drop = "default:snowblock",
|
||||
groups = {crumbly = 3, puts_out_fire = 1, cools_lava = 1, snowy = 1, not_in_creative_inventory = 1},
|
||||
sounds = default.node_sound_dirt_defaults({
|
||||
footstep = {name = "default_snow_footstep", gain = 0.15},
|
||||
dug = {name = "default_snow_footstep", gain = 0.2},
|
||||
dig = {name = "default_snow_footstep", gain = 0.2}
|
||||
}),
|
||||
})
|
After Width: | Height: | Size: 223 B |
After Width: | Height: | Size: 177 B |
After Width: | Height: | Size: 251 B |
After Width: | Height: | Size: 198 B |
After Width: | Height: | Size: 220 B |
After Width: | Height: | Size: 209 B |
After Width: | Height: | Size: 207 B |
After Width: | Height: | Size: 225 B |
After Width: | Height: | Size: 262 B |
After Width: | Height: | Size: 254 B |
After Width: | Height: | Size: 242 B |
After Width: | Height: | Size: 188 B |
After Width: | Height: | Size: 110 B |
After Width: | Height: | Size: 193 B |
After Width: | Height: | Size: 245 B |
After Width: | Height: | Size: 188 B |
After Width: | Height: | Size: 211 B |
After Width: | Height: | Size: 261 B |
After Width: | Height: | Size: 185 B |
After Width: | Height: | Size: 212 B |
After Width: | Height: | Size: 194 B |
|
@ -0,0 +1,409 @@
|
|||
--
|
||||
-- Tools
|
||||
--
|
||||
|
||||
-- sword
|
||||
minetest.register_tool("obsidianmese:sword", {
|
||||
description = "Obsidian Mese Sword",
|
||||
inventory_image = "obsidianmese_sword.png",
|
||||
wield_scale = {x=1.5, y=2, z=1},
|
||||
tool_capabilities = {
|
||||
full_punch_interval = 0.45,
|
||||
max_drop_level=1,
|
||||
groupcaps={
|
||||
fleshy={times={[1]=2.00, [2]=0.65, [3]=0.25}, uses=400, maxlevel=3},
|
||||
snappy={times={[1]=1.90, [2]=0.70, [3]=0.25}, uses=350, maxlevel=3},
|
||||
choppy={times={[3]=0.65}, uses=300, maxlevel=0}
|
||||
},
|
||||
damage_groups = {fleshy=8},
|
||||
},
|
||||
sound = {breaks = "default_tool_breaks"}
|
||||
})
|
||||
|
||||
-- boss sword - balrog - left commented out as I found it, because it does not seem to work, debugging required.
|
||||
--[[ minetest.register_tool("obsidianmese:sword_balrog_boss", {
|
||||
description = "Boss Sword",
|
||||
inventory_image = "obsidianmese_sword_balrog_boss.png",
|
||||
wield_scale = {x=2.2, y=2.7, z=1.7},
|
||||
tool_capabilities = {
|
||||
full_punch_interval = 2,
|
||||
max_drop_level=1,
|
||||
groupcaps={
|
||||
snappy={times={[1]=1.90, [2]=0.90, [3]=0.30}, uses=20, maxlevel=3},
|
||||
}
|
||||
},
|
||||
damage_groups = {fleshy=10},
|
||||
sound = {breaks = "default_tool_breaks"},
|
||||
on_use = function(itemstack, user, pointed_thing)
|
||||
print("on_use")
|
||||
print(dump(pointed_thing))
|
||||
end,
|
||||
after_use = function(itemstack, user, node, digparams)
|
||||
print("after_use")
|
||||
itemstack:add_wear(digparams.wear)
|
||||
return itemstack
|
||||
end
|
||||
}) ]]--
|
||||
|
||||
-- sword engraved - bullet entity
|
||||
minetest.register_entity("obsidianmese:sword_bullet", {
|
||||
physical = false,
|
||||
visual = "sprite",
|
||||
visual_size = { x = 1, y = 1 },
|
||||
textures = { "obsidianmese_shard.png" },
|
||||
collisionbox = {-0.25, -0.25, -0.25, 0.25, 0.25, 0.25},
|
||||
_lifetime = 9, -- seconds before removing
|
||||
_timer = 0, -- initial value
|
||||
_owner = "unknown", -- initial value
|
||||
_trigger_sd = 0,
|
||||
|
||||
on_activate = function(self, staticdata, dtime_s)
|
||||
local table = minetest.deserialize(staticdata)
|
||||
-- check - initial values are empty
|
||||
if table then
|
||||
self._owner = table._owner
|
||||
self._timer = table._timer
|
||||
end
|
||||
self.object:set_armor_groups({ immortal = 1 })
|
||||
end,
|
||||
|
||||
-- should return a string that will be passed to `on_activate` when the object is instantiated the next time
|
||||
get_staticdata = function(self)
|
||||
self._trigger_sd = self._trigger_sd + 1
|
||||
|
||||
-- staticdata are triggered before object appears and before it hides from the World, so remove it before it hides
|
||||
if self._trigger_sd % 2 == 0 then
|
||||
self.object:remove()
|
||||
obsidianmese.sync_fired_table(self._owner)
|
||||
end
|
||||
|
||||
-- insurance - makes sure staticdata are updated when objects activates again (because somehow wasn't removed yet)
|
||||
local table = {
|
||||
_owner = self._owner,
|
||||
_timer = self._timer
|
||||
}
|
||||
return minetest.serialize(table)
|
||||
end,
|
||||
|
||||
-- when the entity gets punched
|
||||
on_punch = function (self, puncher, time_from_last_punch, tool_capabilities, dir)
|
||||
local full_punch_interval = tool_capabilities.full_punch_interval or 1
|
||||
|
||||
-- only on full punch
|
||||
if time_from_last_punch < full_punch_interval then return end
|
||||
|
||||
local v = math.random(1, 8)
|
||||
local velocity = dir
|
||||
|
||||
velocity.x = velocity.x * v
|
||||
velocity.y = velocity.y * v
|
||||
velocity.z = velocity.z * v
|
||||
self.object:setvelocity(velocity)
|
||||
end,
|
||||
|
||||
on_step = function(self, dtime)
|
||||
local pos = self.object:getpos()
|
||||
local node = minetest.get_node_or_nil(pos)
|
||||
|
||||
-- print("self._owner: ", self._owner)
|
||||
-- print("self._timer: ", self._timer)
|
||||
|
||||
self._timer = self._timer + dtime
|
||||
if self._timer > self._lifetime or
|
||||
not obsidianmese.within_limits(pos, 0) then
|
||||
self.object:remove()
|
||||
obsidianmese.sync_fired_table(self._owner)
|
||||
return
|
||||
end
|
||||
|
||||
-- hit node
|
||||
if node
|
||||
and minetest.registered_nodes[node.name]
|
||||
and minetest.registered_nodes[node.name].walkable then
|
||||
self.object:remove()
|
||||
obsidianmese.sync_fired_table(self._owner)
|
||||
|
||||
-- dont damage anything if area protected or next to water
|
||||
if minetest.find_node_near(pos, 1, {"group:water"})
|
||||
or minetest.is_protected(pos, "") then
|
||||
return
|
||||
end
|
||||
-- this is where the shot shard can explode when it hets a node. It was commented out,
|
||||
-- I uncommented it, but changed the explosion radius to 1, and the damage to 4. That should make it non-griefy.
|
||||
tnt.boom(pos, {
|
||||
radius = 1,
|
||||
damage_radius = 4,
|
||||
ignore_protection = false,
|
||||
ignore_on_blast = false,
|
||||
disable_drops = false
|
||||
})
|
||||
return
|
||||
end
|
||||
|
||||
-- hit player or mob
|
||||
for k, obj in ipairs(minetest.get_objects_inside_radius(pos, 1)) do
|
||||
if obj:is_player() then
|
||||
-- pvp block
|
||||
if minetest.global_exists("pvp_block") then
|
||||
local dmg = obsidianmese.damage_calculator(
|
||||
obj,
|
||||
minetest.get_player_by_name(self._owner),
|
||||
1.0,
|
||||
{
|
||||
full_punch_interval = 1.0,
|
||||
damage_groups = {fleshy = 8},
|
||||
},
|
||||
nil,
|
||||
nil
|
||||
)
|
||||
|
||||
pvp_block.register_on_punchplayer(
|
||||
obj, -- player
|
||||
minetest.get_player_by_name(self._owner), --hitter
|
||||
1.0, -- time_from_last_punch
|
||||
{
|
||||
full_punch_interval = 1.0,
|
||||
damage_groups = {fleshy = 8},
|
||||
}, -- tool_capabilities
|
||||
nil, -- dir
|
||||
dmg -- damage i.e. {fleshy = 8}
|
||||
)
|
||||
end
|
||||
|
||||
-- punch player
|
||||
obj:punch(self.object, 1.0, {
|
||||
full_punch_interval = 1.0,
|
||||
damage_groups = {fleshy = 8},
|
||||
}, nil)
|
||||
|
||||
self.object:remove()
|
||||
obsidianmese.sync_fired_table(self._owner)
|
||||
|
||||
break
|
||||
-- punch entity
|
||||
elseif not obj:is_player() and
|
||||
obj:get_luaentity() and
|
||||
obj:get_luaentity().name ~= "__builtin:item" then
|
||||
local entity = obj:get_luaentity()
|
||||
|
||||
if entity.name ~= self.object:get_luaentity().name then
|
||||
obj:punch(self.object, 1.0, {
|
||||
full_punch_interval = 1.0,
|
||||
damage_groups = {fleshy = 8},
|
||||
}, nil)
|
||||
|
||||
self.object:remove()
|
||||
obsidianmese.sync_fired_table(self._owner)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
-- sword engraved
|
||||
minetest.register_tool("obsidianmese:sword_engraved", {
|
||||
description = "Obsidian Mese Sword Engraved - right click shoot 1 shot",
|
||||
inventory_image = "obsidianmese_sword_diamond_engraved.png",
|
||||
wield_scale = {x=1.5, y=2, z=1},
|
||||
tool_capabilities = {
|
||||
full_punch_interval = 0.6,
|
||||
max_drop_level=1,
|
||||
groupcaps={
|
||||
snappy={times={[1]=1.90, [2]=0.90, [3]=0.30}, uses=300, maxlevel=3},
|
||||
},
|
||||
damage_groups = {fleshy=8},
|
||||
},
|
||||
sound = {breaks = "default_tool_breaks"},
|
||||
on_secondary_use = obsidianmese.fire_sword
|
||||
})
|
||||
|
||||
-- pick axe
|
||||
minetest.register_tool("obsidianmese:pick", {
|
||||
description = "Obsidian Mese Pickaxe",
|
||||
inventory_image = "obsidianmese_pick.png",
|
||||
tool_capabilities = {
|
||||
full_punch_interval = 0.9,
|
||||
max_drop_level=3,
|
||||
groupcaps={
|
||||
cracky={times={[1]=2.0, [2]=1.0, [3]=0.50}, uses=250, maxlevel=3},
|
||||
crumbly={times={[1]=2.0, [2]=1.0, [3]=0.5}, uses=350, maxlevel=3},
|
||||
snappy={times={[1]=2.0, [2]=1.0, [3]=0.5}, uses=300, maxlevel=3}
|
||||
},
|
||||
damage_groups = {fleshy=5},
|
||||
},
|
||||
sound = {breaks = "default_tool_breaks"},
|
||||
})
|
||||
|
||||
-- pick axe engraved
|
||||
minetest.register_tool("obsidianmese:pick_engraved", {
|
||||
description = "Obsidian Mese Pickaxe Engraved - right click to place item next to the pickaxe in your inventory slot",
|
||||
inventory_image = "obsidianmese_pick_engraved.png",
|
||||
tool_capabilities = {
|
||||
full_punch_interval = 0.9,
|
||||
max_drop_level=3,
|
||||
groupcaps={
|
||||
cracky={times={[1]=2.0, [2]=1.0, [3]=0.50}, uses=200, maxlevel=3}
|
||||
},
|
||||
damage_groups = {fleshy=5},
|
||||
},
|
||||
sound = {breaks = "default_tool_breaks"},
|
||||
on_place = obsidianmese.pick_engraved_place
|
||||
})
|
||||
|
||||
-- shovel
|
||||
minetest.register_tool("obsidianmese:shovel", {
|
||||
description = "Obsidian Mese Shovel - right click (secondary click) for creating a path",
|
||||
inventory_image = "obsidianmese_shovel.png",
|
||||
wield_image = "obsidianmese_shovel.png^[transformR90",
|
||||
wield_scale = {x=1.5, y=1.5, z=1.5},
|
||||
tool_capabilities = {
|
||||
full_punch_interval = 0.9,
|
||||
max_drop_level=1,
|
||||
groupcaps={
|
||||
crumbly = {times={[1]=1.10, [2]=0.50, [3]=0.30}, uses=50, maxlevel=3},
|
||||
},
|
||||
damage_groups = {fleshy=4},
|
||||
},
|
||||
sound = {breaks = "default_tool_breaks"},
|
||||
on_place = obsidianmese.shovel_place
|
||||
})
|
||||
|
||||
-- axe
|
||||
minetest.register_tool("obsidianmese:axe", {
|
||||
description = "Obsidian Mese Axe - Tree Capitator",
|
||||
inventory_image = "obsidianmese_axe.png",
|
||||
wield_scale = {x=1.5, y=2, z=1},
|
||||
tool_capabilities = {
|
||||
full_punch_interval = 0.9,
|
||||
max_drop_level=1,
|
||||
groupcaps={
|
||||
choppy={times={[1]=2.10, [2]=0.90, [3]=0.50}, uses=30, maxlevel=3},
|
||||
},
|
||||
damage_groups = {fleshy=7},
|
||||
},
|
||||
sound = {breaks = "default_tool_breaks"},
|
||||
})
|
||||
|
||||
--hoe
|
||||
minetest.register_tool("obsidianmese:hoe", {
|
||||
description = "Obsidian Mese Hoe",
|
||||
inventory_image = "obsidianmese_hoe.png",
|
||||
sound = {breaks = "default_tool_breaks"},
|
||||
on_use = function(itemstack, user, pointed_thing)
|
||||
local axis, dir = obsidianmese.player_axis(user)
|
||||
local pt = pointed_thing
|
||||
local under = pt.under
|
||||
if not under then return end
|
||||
local wdef = itemstack:get_definition()
|
||||
local uses = 500
|
||||
|
||||
for i = 0, 4 do
|
||||
|
||||
if axis == "x" then
|
||||
pt.under = {
|
||||
x = under.x + (i * dir),
|
||||
y = under.y,
|
||||
z = under.z
|
||||
}
|
||||
|
||||
elseif axis == "z" then
|
||||
pt.under = {
|
||||
x = under.x,
|
||||
y = under.y,
|
||||
z = under.z + (i * dir)
|
||||
}
|
||||
end
|
||||
|
||||
-- print(obsidianmese.player_axis(user))
|
||||
|
||||
obsidianmese.hoe_on_use(itemstack, user, pointed_thing)
|
||||
|
||||
if not (creative and creative.is_enabled_for
|
||||
and creative.is_enabled_for(user:get_player_name())) then
|
||||
-- wear tool
|
||||
itemstack:add_wear(65535/(uses-1))
|
||||
-- tool break sound
|
||||
if itemstack:get_count() == 0 and wdef.sound and wdef.sound.breaks then
|
||||
minetest.sound_play(wdef.sound.breaks, {pos = pt.above, gain = 0.5})
|
||||
end
|
||||
end
|
||||
end
|
||||
return itemstack
|
||||
end,
|
||||
on_place = function(itemstack, placer, pointed_thing)
|
||||
local idx = placer:get_wield_index() + 1 -- item to right of wielded tool
|
||||
local inv = placer:get_inventory()
|
||||
local stack = inv:get_stack("main", idx) -- stack to right of tool
|
||||
local stack_name = stack:get_name()
|
||||
local axis, dir = obsidianmese.player_axis(placer)
|
||||
local pt = pointed_thing
|
||||
local above = pt.above
|
||||
local under = pt.under
|
||||
if not above or not under then return end
|
||||
local udef = {}
|
||||
local temp_stack = {}
|
||||
|
||||
if pt.type == "node" then
|
||||
local pos = minetest.get_pointed_thing_position(pt)
|
||||
local pointed_node = minetest.get_node(pos)
|
||||
|
||||
if pointed_node ~= nil and stack_name ~= "" then
|
||||
local stack_name_split = string.split(stack_name, ":")
|
||||
local stack_mod = stack_name_split[1]
|
||||
|
||||
udef = minetest.registered_nodes[stack_name]
|
||||
|
||||
-- handle default farming and farming_addons placement
|
||||
if stack_mod == "farming" or stack_mod == "farming_addons" then
|
||||
for i = 0, 4 do
|
||||
print("farming.place_seed")
|
||||
|
||||
if axis == "x" then
|
||||
pt.above = {
|
||||
x = above.x + (i * dir),
|
||||
y = above.y,
|
||||
z = above.z
|
||||
}
|
||||
pt.under = {
|
||||
x = under.x + (i * dir),
|
||||
y = under.y,
|
||||
z = under.z
|
||||
}
|
||||
|
||||
elseif axis == "z" then
|
||||
pt.above = {
|
||||
x = above.x,
|
||||
y = above.y,
|
||||
z = above.z + (i * dir)
|
||||
}
|
||||
pt.under = {
|
||||
x = under.x,
|
||||
y = under.y,
|
||||
z = under.z + (i * dir)
|
||||
}
|
||||
end
|
||||
|
||||
udef = minetest.registered_nodes[stack_name]
|
||||
|
||||
if udef and udef.on_place then
|
||||
temp_stack = udef.on_place(stack, placer, pt) or stack
|
||||
elseif udef and udef.on_use then
|
||||
temp_stack = udef.on_use(stack, placer, pt) or stack
|
||||
end
|
||||
|
||||
-- temp_stack = obsidianmese.place_seed(stack, placer, pt, stack_name)
|
||||
inv:set_stack("main", idx, temp_stack)
|
||||
|
||||
-- itemstack = obsidianmese.add_wear(itemstack)
|
||||
-- return itemstack
|
||||
end
|
||||
end
|
||||
end
|
||||
-- if everything else fails use default on_place
|
||||
-- stack = minetest.item_place(stack, placer, pt)
|
||||
-- inv:set_stack("main", idx, stack)
|
||||
return itemstack
|
||||
end
|
||||
end,
|
||||
})
|