2013-10-27 22:01:13 +01:00
|
|
|
local mining_lasers_list = {
|
2013-12-04 03:51:57 +01:00
|
|
|
-- {<num>, <range of the laser shots>, <max_charge>, <charge_per_shot>},
|
|
|
|
{"1", 7, 50000, 1000},
|
|
|
|
{"2", 14, 200000, 2000},
|
|
|
|
{"3", 21, 650000, 3000},
|
2013-10-27 22:01:13 +01:00
|
|
|
}
|
2018-07-21 19:10:32 +02:00
|
|
|
local allow_entire_discharging = true
|
2013-10-27 22:01:13 +01:00
|
|
|
|
|
|
|
local S = technic.getter
|
|
|
|
|
2013-10-30 20:18:18 +01:00
|
|
|
minetest.register_craft({
|
2018-07-21 19:10:32 +02:00
|
|
|
output = "technic:laser_mk1",
|
2013-10-30 20:18:18 +01:00
|
|
|
recipe = {
|
2018-10-31 01:29:28 +01:00
|
|
|
{"default:diamond", "basic_materials:brass_ingot", "default:obsidian_glass"},
|
|
|
|
{"", "basic_materials:brass_ingot", "technic:red_energy_crystal"},
|
2018-07-21 19:10:32 +02:00
|
|
|
{"", "", "default:copper_ingot"},
|
2013-12-04 03:45:33 +01:00
|
|
|
}
|
|
|
|
})
|
|
|
|
minetest.register_craft({
|
2018-07-21 19:10:32 +02:00
|
|
|
output = "technic:laser_mk2",
|
2013-12-04 03:45:33 +01:00
|
|
|
recipe = {
|
2018-07-21 19:10:32 +02:00
|
|
|
{"default:diamond", "technic:carbon_steel_ingot", "technic:laser_mk1"},
|
|
|
|
{"", "technic:carbon_steel_ingot", "technic:green_energy_crystal"},
|
|
|
|
{"", "", "default:copper_ingot"},
|
2013-12-04 03:45:33 +01:00
|
|
|
}
|
|
|
|
})
|
|
|
|
minetest.register_craft({
|
2018-07-21 19:10:32 +02:00
|
|
|
output = "technic:laser_mk3",
|
2013-12-04 03:45:33 +01:00
|
|
|
recipe = {
|
2018-07-21 19:10:32 +02:00
|
|
|
{"default:diamond", "technic:carbon_steel_ingot", "technic:laser_mk2"},
|
|
|
|
{"", "technic:carbon_steel_ingot", "technic:blue_energy_crystal"},
|
|
|
|
{"", "", "default:copper_ingot"},
|
2013-10-30 20:18:18 +01:00
|
|
|
}
|
|
|
|
})
|
|
|
|
|
2014-09-25 02:32:36 +02:00
|
|
|
local function laser_node(pos, node, player)
|
|
|
|
local def = minetest.registered_nodes[node.name]
|
2018-07-21 19:10:32 +02:00
|
|
|
if def.liquidtype ~= "none" and def.buildable_to then
|
2013-10-27 22:01:13 +01:00
|
|
|
minetest.remove_node(pos)
|
2014-09-16 15:36:13 +02:00
|
|
|
minetest.add_particle({
|
|
|
|
pos = pos,
|
2018-07-21 19:10:32 +02:00
|
|
|
velocity = {x = 0, y = 1.5 + math.random(), z = 0},
|
|
|
|
acceleration = {x = 0, y = -1, z = 0},
|
2014-09-25 02:32:36 +02:00
|
|
|
size = 6 + math.random() * 2,
|
|
|
|
texture = "smoke_puff.png^[transform" .. math.random(0, 7),
|
2014-09-16 15:36:13 +02:00
|
|
|
})
|
2013-10-27 22:01:13 +01:00
|
|
|
return
|
|
|
|
end
|
2020-06-27 17:29:50 +02:00
|
|
|
def.on_dig(pos, node, player)
|
2013-10-27 22:01:13 +01:00
|
|
|
end
|
|
|
|
|
2018-07-21 19:10:32 +02:00
|
|
|
local keep_node = {air = true}
|
|
|
|
local function can_keep_node(name)
|
|
|
|
if keep_node[name] ~= nil then
|
|
|
|
return keep_node[name]
|
|
|
|
end
|
|
|
|
keep_node[name] = minetest.get_item_group(name, "hot") ~= 0
|
|
|
|
return keep_node[name]
|
|
|
|
end
|
|
|
|
|
2013-10-27 22:01:13 +01:00
|
|
|
local function laser_shoot(player, range, particle_texture, sound)
|
2019-09-14 12:55:41 +02:00
|
|
|
local player_pos = player:get_pos()
|
2014-09-25 02:32:36 +02:00
|
|
|
local player_name = player:get_player_name()
|
2013-10-27 22:01:13 +01:00
|
|
|
local dir = player:get_look_dir()
|
|
|
|
|
2014-09-25 02:32:36 +02:00
|
|
|
local start_pos = vector.new(player_pos)
|
|
|
|
-- Adjust to head height
|
2018-07-21 19:10:32 +02:00
|
|
|
start_pos.y = start_pos.y + (player:get_properties().eye_height or 1.625)
|
2014-09-16 15:36:13 +02:00
|
|
|
minetest.add_particle({
|
2018-07-21 19:10:32 +02:00
|
|
|
pos = start_pos,
|
2016-03-22 00:44:05 +01:00
|
|
|
velocity = dir,
|
|
|
|
acceleration = vector.multiply(dir, 50),
|
2018-07-21 19:10:32 +02:00
|
|
|
expirationtime = (math.sqrt(1 + 100 * (range + 0.4)) - 1) / 50,
|
2014-09-16 15:36:13 +02:00
|
|
|
size = 1,
|
2014-09-25 02:32:36 +02:00
|
|
|
texture = particle_texture .. "^[transform" .. math.random(0, 7),
|
2014-09-16 15:36:13 +02:00
|
|
|
})
|
2014-09-25 02:32:36 +02:00
|
|
|
minetest.sound_play(sound, {pos = player_pos, max_hear_distance = range})
|
2016-03-22 02:24:26 +01:00
|
|
|
for pos in technic.trace_node_ray_fat(start_pos, dir, range) do
|
2014-09-25 02:32:36 +02:00
|
|
|
if minetest.is_protected(pos, player_name) then
|
|
|
|
minetest.record_protection_violation(pos, player_name)
|
|
|
|
break
|
|
|
|
end
|
2018-07-21 19:10:32 +02:00
|
|
|
local node = minetest.get_node(pos)
|
|
|
|
if node.name == "ignore"
|
|
|
|
or not minetest.registered_nodes[node.name] then
|
2014-09-25 02:32:36 +02:00
|
|
|
break
|
|
|
|
end
|
2018-07-21 19:10:32 +02:00
|
|
|
if not can_keep_node(node.name) then
|
2014-09-25 02:32:36 +02:00
|
|
|
laser_node(pos, node, player)
|
|
|
|
end
|
2014-09-16 15:36:13 +02:00
|
|
|
end
|
2013-10-27 22:01:13 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
for _, m in pairs(mining_lasers_list) do
|
|
|
|
technic.register_power_tool("technic:laser_mk"..m[1], m[3])
|
|
|
|
minetest.register_tool("technic:laser_mk"..m[1], {
|
|
|
|
description = S("Mining Laser Mk%d"):format(m[1]),
|
|
|
|
inventory_image = "technic_mining_laser_mk"..m[1]..".png",
|
2018-07-21 19:10:32 +02:00
|
|
|
range = 0,
|
2013-10-27 22:01:13 +01:00
|
|
|
stack_max = 1,
|
Genericise handling of multiple meanings of wear
The tool workshop is meant to repair mechanical damage to tools, so
is at risk of `repairing' tools that use the wear bar to represent
something other than mechanical wear. It had special-case recognition
of the water and lava cans, which use the wear bar to represent how much
content they're carrying, and wouldn't repair them. But it didn't avoid
`repairing' RE chargeable items, which use the wear bar to represent
how much energy they have stored. It would modify the wear bar without
actually affecting the charge, so the wear bar would jump back to the
correct place when the next charging or discharging event occurred.
To genericise, introduce a new item property, "wear_represents", which
indicates how the wear bar is used for this item. Currently defined
values are "mechanical_wear" (straightforward damage to tools that
start out perfect), "technic_RE_charge" (electrical energy, canonically
represented in the meta rather than the wear bar), and "content_level"
(how full a container is). For backcompat, nil is interpreted as
"mechanical_wear". The tool workshop will only repair "mechanical_wear"
tools. As a bonus, set_RE_wear() will only set the wear bar for
"technic_RE_charge" items: this means developers will notice if they
forget to declare wear_represents, but also means that with no further
changes it's possible to have an RE chargeable item that uses its wear
bar to represent something else.
2014-04-28 11:44:07 +02:00
|
|
|
wear_represents = "technic_RE_charge",
|
2014-04-30 11:49:54 +02:00
|
|
|
on_refill = technic.refill_RE_charge,
|
2013-10-27 22:01:13 +01:00
|
|
|
on_use = function(itemstack, user)
|
2013-12-17 19:56:37 +01:00
|
|
|
local meta = minetest.deserialize(itemstack:get_metadata())
|
2018-07-21 19:10:32 +02:00
|
|
|
if not meta or not meta.charge or meta.charge == 0 then
|
2013-10-27 22:01:13 +01:00
|
|
|
return
|
|
|
|
end
|
2013-12-04 03:51:57 +01:00
|
|
|
|
2018-07-21 19:10:32 +02:00
|
|
|
local range = m[2]
|
|
|
|
if meta.charge < m[4] then
|
|
|
|
if not allow_entire_discharging then
|
|
|
|
return
|
2015-03-01 05:28:16 +01:00
|
|
|
end
|
2018-07-21 19:10:32 +02:00
|
|
|
-- If charge is too low, give the laser a shorter range
|
|
|
|
range = range * meta.charge / m[4]
|
|
|
|
end
|
|
|
|
laser_shoot(user, range, "technic_laser_beam_mk" .. m[1] .. ".png",
|
|
|
|
"technic_laser_mk" .. m[1])
|
|
|
|
if not technic.creative_mode then
|
|
|
|
meta.charge = math.max(meta.charge - m[4], 0)
|
|
|
|
technic.set_RE_wear(itemstack, meta.charge, m[3])
|
|
|
|
itemstack:set_metadata(minetest.serialize(meta))
|
2013-10-27 22:01:13 +01:00
|
|
|
end
|
|
|
|
return itemstack
|
|
|
|
end,
|
|
|
|
})
|
|
|
|
end
|