Add laser beam nodes for energy transfer
134
basis/laser_lib.lua
Normal file
@ -0,0 +1,134 @@
|
||||
--[[
|
||||
|
||||
TechAge
|
||||
=======
|
||||
|
||||
Copyright (C) 2019-2021 Joachim Stolberg
|
||||
|
||||
GPL v3
|
||||
See LICENSE.txt for more information
|
||||
|
||||
Laser basis functions
|
||||
|
||||
]]--
|
||||
|
||||
local Entities = {}
|
||||
local SIZES = {1, 2, 3, 6, 12, 24, 48} -- for laser entities
|
||||
local GAP_MIN = 1 -- between 2 blocks
|
||||
local GAP_MAX = 2 * 48 -- between 2 blocks
|
||||
|
||||
-- Return the area (pos1,pos2) for a destination node
|
||||
local function get_pos_range(pos, dir)
|
||||
local pos1 = vector.add(pos, vector.multiply(dir, GAP_MIN + 1)) -- min
|
||||
local pos2 = vector.add(pos, vector.multiply(dir, GAP_MAX + 1)) -- max
|
||||
return pos1, pos2
|
||||
end
|
||||
|
||||
-- Return first pos after start pos and the destination pos
|
||||
local function get_positions(pos, mem, dir)
|
||||
local pos1 = vector.add(pos, dir) -- start pos
|
||||
local _, pos2 = get_pos_range(pos, dir) -- last pos
|
||||
local _, pos3 = minetest.line_of_sight(pos1, pos2)
|
||||
pos3 = pos3 or pos2 -- destination node pos
|
||||
if not mem.peer_node_pos or not vector.equals(pos3, mem.peer_node_pos) then
|
||||
mem.peer_node_pos = pos3
|
||||
local dist = vector.distance(pos1, pos3)
|
||||
if dist > GAP_MIN and dist <= GAP_MAX then
|
||||
return pos1, pos3
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- return both both laser entities the pos and length
|
||||
local function get_laser_length_and_pos(pos1, pos2, dir)
|
||||
local dist = vector.distance(pos1, pos2)
|
||||
|
||||
for _, size in ipairs(SIZES) do
|
||||
if dist <= (size * 2) then
|
||||
pos1 = vector.add (pos1, vector.multiply(dir, (size / 2) - 0.5))
|
||||
pos2 = vector.subtract(pos2, vector.multiply(dir, (size / 2) + 0.5))
|
||||
return size, pos1, pos2
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function del_laser(pos)
|
||||
local key = minetest.hash_node_position(pos)
|
||||
local items = Entities[key]
|
||||
if items then
|
||||
local laser1, laser2 = items[1], items[2]
|
||||
laser1:remove()
|
||||
laser2:remove()
|
||||
Entities[key] = nil
|
||||
end
|
||||
return key
|
||||
end
|
||||
|
||||
local function add_laser(pos, pos1, pos2, size, param2)
|
||||
local key = del_laser(pos)
|
||||
|
||||
local laser1 = minetest.add_entity(pos1, "techage:laser" .. size)
|
||||
if laser1 then
|
||||
local yaw = math.pi / 2 * (param2 + 1)
|
||||
laser1:set_rotation({x = 0, y = yaw, z = 0})
|
||||
end
|
||||
|
||||
local laser2 = minetest.add_entity(pos2, "techage:laser" .. size)
|
||||
if laser2 then
|
||||
param2 = (param2 + 2) % 4 -- flip dir
|
||||
local yaw = math.pi / 2 * (param2 + 1)
|
||||
laser2:set_rotation({x = 0, y = yaw, z = 0})
|
||||
end
|
||||
|
||||
Entities[key] = {laser1, laser2}
|
||||
end
|
||||
|
||||
for _, size in ipairs(SIZES) do
|
||||
minetest.register_entity("techage:laser" .. size, {
|
||||
initial_properties = {
|
||||
visual = "cube",
|
||||
textures = {
|
||||
"techage_laser.png",
|
||||
"techage_laser.png",
|
||||
"techage_laser.png",
|
||||
"techage_laser.png",
|
||||
"techage_laser.png",
|
||||
"techage_laser.png",
|
||||
},
|
||||
use_texture_alpha = true,
|
||||
physical = false,
|
||||
collide_with_objects = false,
|
||||
pointable = false,
|
||||
static_save = false,
|
||||
visual_size = {x = size, y = 0.05, z = 0.05},
|
||||
glow = 14,
|
||||
shaded = true,
|
||||
},
|
||||
})
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- API functions
|
||||
-------------------------------------------------------------------------------
|
||||
-- if force is not true, do not redraw the laser if nothing has changed
|
||||
function techage.renew_laser(pos, force)
|
||||
local mem = techage.get_mem(pos)
|
||||
if force then
|
||||
mem.peer_node_pos = nil
|
||||
mem.param2 = nil
|
||||
end
|
||||
mem.param2 = mem.param2 or minetest.get_node(pos).param2
|
||||
local dir = minetest.facedir_to_dir(mem.param2)
|
||||
local pos1, pos2 = get_positions(pos, mem, dir)
|
||||
if pos1 then
|
||||
local size, pos3, pos4 = get_laser_length_and_pos(pos1, pos2, dir)
|
||||
if size then
|
||||
add_laser(pos, pos3, pos4, size, mem.param2)
|
||||
return pos1, pos2
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
-- techage.del_laser(pos)
|
||||
techage.del_laser = del_laser
|
4
init.lua
@ -85,6 +85,7 @@ dofile(MP.."/basis/networks.lua")
|
||||
dofile(MP.."/basis/recipe_lib.lua")
|
||||
dofile(MP.."/basis/formspec_update.lua")
|
||||
dofile(MP.."/basis/windturbine_lib.lua")
|
||||
dofile(MP.."/basis/laser_lib.lua")
|
||||
|
||||
-- Main doc
|
||||
dofile(MP.."/doc/manual_DE.lua")
|
||||
@ -112,6 +113,7 @@ dofile(MP.."/power/powerswitch.lua")
|
||||
dofile(MP.."/power/protection.lua")
|
||||
dofile(MP.."/power/power_line.lua")
|
||||
dofile(MP.."/power/ta4_cable.lua")
|
||||
dofile(MP.."/power/laser.lua")
|
||||
|
||||
-- Iron Age
|
||||
dofile(MP.."/iron_age/main.lua")
|
||||
@ -215,7 +217,7 @@ dofile(MP.."/oil/drillbox.lua")
|
||||
dofile(MP.."/oil/pumpjack.lua")
|
||||
dofile(MP.."/oil/distiller.lua")
|
||||
dofile(MP.."/oil/reboiler.lua")
|
||||
-- dofile(MP.."/oil/gasflare.lua")
|
||||
-- dofile(MP.."/oil/gasflare.lua")
|
||||
|
||||
-- TA3 power based
|
||||
dofile(MP.."/ta3_power/tiny_generator.lua")
|
||||
|
@ -16,7 +16,7 @@
|
||||
local S = techage.S
|
||||
|
||||
|
||||
if not minetest.global_exists("bakedclay") then
|
||||
if not minetest.get_modpath("bakedclay") then
|
||||
minetest.register_node("techage:cement_block", {
|
||||
description = S("Cement Block"),
|
||||
tiles = {"default_clay.png^[colorize:#FFFFFF:160"},
|
||||
@ -33,6 +33,17 @@ if not minetest.global_exists("bakedclay") then
|
||||
|
||||
techage.add_grinder_recipe({input="techage:cement_block", output="techage:cement_powder"})
|
||||
else
|
||||
-- The block should not exist when the mod baked clay is loaded.
|
||||
-- But this block was active due to an error and can therefore no longer be deleted.
|
||||
minetest.register_node("techage:cement_block", {
|
||||
description = S("Cement Block"),
|
||||
tiles = {"default_clay.png^[colorize:#FFFFFF:160"},
|
||||
is_ground_content = false,
|
||||
groups = {cracky = 2, stone = 1},
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
})
|
||||
|
||||
techage.add_grinder_recipe({input="techage:cement_block", output="techage:cement_powder"})
|
||||
techage.add_grinder_recipe({input="bakedclay:white", output="techage:cement_powder"})
|
||||
end
|
||||
|
||||
|
115
power/laser.lua
Normal file
@ -0,0 +1,115 @@
|
||||
--[[
|
||||
|
||||
TechAge
|
||||
=======
|
||||
|
||||
Copyright (C) 2019-2021 Joachim Stolberg
|
||||
|
||||
GPL v3
|
||||
See LICENSE.txt for more information
|
||||
|
||||
TA4 Laser beam emitter and receiver
|
||||
|
||||
]]--
|
||||
|
||||
-- for lazy programmers
|
||||
local P2S = function(pos) if pos then return minetest.pos_to_string(pos) end end
|
||||
local S2P = minetest.string_to_pos
|
||||
local M = minetest.get_meta
|
||||
local S = techage.S
|
||||
|
||||
local Cable = techage.ElectricCable
|
||||
local power = techage.power
|
||||
local networks = techage.networks
|
||||
|
||||
minetest.register_node("techage:laser_emitter", {
|
||||
description = S("TA4 Laser Beam Emitter"),
|
||||
tiles = {
|
||||
-- up, down, right, left, back, front
|
||||
"techage_filling_ta4.png^techage_frame_ta4_top.png",
|
||||
"techage_filling_ta4.png^techage_frame_ta4.png",
|
||||
"techage_filling_ta4.png^techage_frame_ta4.png^techage_appl_laser.png",
|
||||
"techage_filling_ta4.png^techage_frame_ta4.png^techage_appl_laser.png",
|
||||
"techage_filling_ta4.png^techage_frame_ta4.png^techage_appl_laser_hole.png",
|
||||
"techage_filling_ta4.png^techage_frame_ta4.png^techage_appl_hole_electric.png",
|
||||
},
|
||||
|
||||
after_place_node = function(pos, placer)
|
||||
local tube_dir = networks.side_to_outdir(pos, "F")
|
||||
Cable:prepare_pairing(pos, tube_dir, "")
|
||||
Cable:after_place_node(pos, {tube_dir})
|
||||
|
||||
local pos1, pos2 = techage.renew_laser(pos, true)
|
||||
if pos1 then
|
||||
local node = techage.get_node_lvm(pos2)
|
||||
if node.name == "techage:laser_receiver" then
|
||||
Cable:pairing(pos2, "laser")
|
||||
Cable:pairing(pos, "laser")
|
||||
else
|
||||
minetest.chat_send_player(placer:get_player_name(), S("Valid destination positions:") .. " " .. P2S(pos1) .. " " .. S("to") .. " " .. P2S(pos2))
|
||||
end
|
||||
else
|
||||
minetest.chat_send_player(placer:get_player_name(), S("The line of sight is blocked"))
|
||||
end
|
||||
minetest.get_node_timer(pos):start(2)
|
||||
end,
|
||||
|
||||
on_timer = function(pos, elapsed)
|
||||
local pos1, pos2 = techage.renew_laser(pos)
|
||||
if pos1 then
|
||||
local node = techage.get_node_lvm(pos2)
|
||||
if node.name == "techage:laser_receiver" then
|
||||
Cable:pairing(pos2, "laser")
|
||||
Cable:pairing(pos, "laser")
|
||||
end
|
||||
end
|
||||
return true
|
||||
end,
|
||||
|
||||
after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
||||
techage.del_laser(pos)
|
||||
Cable:stop_pairing(pos, oldmetadata, "")
|
||||
local tube_dir = tonumber(oldmetadata.fields.tube_dir or 0)
|
||||
Cable:after_dig_node(pos, {tube_dir})
|
||||
end,
|
||||
|
||||
paramtype2 = "facedir",
|
||||
groups = {choppy=2, cracky=2, crumbly=2},
|
||||
is_ground_content = false,
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
})
|
||||
|
||||
minetest.register_node("techage:laser_receiver", {
|
||||
description = S("TA4 Laser Beam Receiver"),
|
||||
tiles = {
|
||||
-- up, down, right, left, back, front
|
||||
"techage_filling_ta4.png^techage_frame_ta4_top.png",
|
||||
"techage_filling_ta4.png^techage_frame_ta4.png",
|
||||
"techage_filling_ta4.png^techage_frame_ta4.png^techage_appl_laser.png",
|
||||
"techage_filling_ta4.png^techage_frame_ta4.png^techage_appl_laser.png",
|
||||
"techage_filling_ta4.png^techage_frame_ta4.png^techage_appl_laser_hole.png",
|
||||
"techage_filling_ta4.png^techage_frame_ta4.png^techage_appl_hole_electric.png",
|
||||
},
|
||||
|
||||
after_place_node = function(pos, placer)
|
||||
local tube_dir = networks.side_to_outdir(pos, "F")
|
||||
Cable:prepare_pairing(pos, tube_dir, "")
|
||||
Cable:after_place_node(pos, {tube_dir})
|
||||
end,
|
||||
|
||||
after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
||||
Cable:stop_pairing(pos, oldmetadata, "")
|
||||
local tube_dir = tonumber(oldmetadata.fields.tube_dir or 0)
|
||||
Cable:after_dig_node(pos, {tube_dir})
|
||||
end,
|
||||
|
||||
paramtype2 = "facedir",
|
||||
groups = {choppy=2, cracky=2, crumbly=2},
|
||||
is_ground_content = false,
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
})
|
||||
|
||||
Cable:add_secondary_node_names({"techage:laser_emitter", "techage:laser_receiver"})
|
||||
Cable:set_valid_sides("techage:laser_emitter", {"F"})
|
||||
Cable:set_valid_sides("techage:laser_receiver", {"F"})
|
||||
|
@ -5,7 +5,7 @@ print(">>> Convert")
|
||||
for filename in os.listdir("./"):
|
||||
if fnmatch.fnmatch(filename, "*.png"):
|
||||
print(filename)
|
||||
os.system("pngquant --skip-if-larger --quality=60-80 --strip --output ./%s.new ./%s" % (filename, filename))
|
||||
os.system("pngquant --skip-if-larger --quality=80 --strip --output ./%s.new ./%s" % (filename, filename))
|
||||
|
||||
print("\n>>> Copy")
|
||||
for filename in os.listdir("./"):
|
||||
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 280 B After Width: | Height: | Size: 259 B |
Before Width: | Height: | Size: 688 B After Width: | Height: | Size: 624 B |
Before Width: | Height: | Size: 432 B After Width: | Height: | Size: 385 B |
Before Width: | Height: | Size: 199 B After Width: | Height: | Size: 178 B |
BIN
textures/techage_appl_laser.png
Normal file
After Width: | Height: | Size: 567 B |
BIN
textures/techage_appl_laser_hole.png
Normal file
After Width: | Height: | Size: 134 B |
Before Width: | Height: | Size: 167 B After Width: | Height: | Size: 164 B |
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 565 B |
Before Width: | Height: | Size: 262 B After Width: | Height: | Size: 261 B |
Before Width: | Height: | Size: 963 B After Width: | Height: | Size: 942 B |
Before Width: | Height: | Size: 223 B After Width: | Height: | Size: 216 B |
Before Width: | Height: | Size: 177 B After Width: | Height: | Size: 152 B |
Before Width: | Height: | Size: 367 B After Width: | Height: | Size: 364 B |
Before Width: | Height: | Size: 427 B After Width: | Height: | Size: 405 B |
Before Width: | Height: | Size: 335 B After Width: | Height: | Size: 296 B |
Before Width: | Height: | Size: 322 B After Width: | Height: | Size: 226 B |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 940 B |
Before Width: | Height: | Size: 276 B After Width: | Height: | Size: 191 B |
Before Width: | Height: | Size: 425 B After Width: | Height: | Size: 364 B |
Before Width: | Height: | Size: 328 B After Width: | Height: | Size: 306 B |
Before Width: | Height: | Size: 297 B After Width: | Height: | Size: 277 B |
Before Width: | Height: | Size: 819 B After Width: | Height: | Size: 751 B |
Before Width: | Height: | Size: 254 B After Width: | Height: | Size: 233 B |
Before Width: | Height: | Size: 257 B After Width: | Height: | Size: 219 B |
Before Width: | Height: | Size: 296 B After Width: | Height: | Size: 275 B |
Before Width: | Height: | Size: 704 B After Width: | Height: | Size: 609 B |
Before Width: | Height: | Size: 670 B After Width: | Height: | Size: 644 B |
Before Width: | Height: | Size: 487 B After Width: | Height: | Size: 407 B |
Before Width: | Height: | Size: 263 B After Width: | Height: | Size: 262 B |
Before Width: | Height: | Size: 432 B After Width: | Height: | Size: 431 B |
Before Width: | Height: | Size: 428 B After Width: | Height: | Size: 407 B |
Before Width: | Height: | Size: 428 B After Width: | Height: | Size: 407 B |
Before Width: | Height: | Size: 432 B After Width: | Height: | Size: 411 B |
Before Width: | Height: | Size: 398 B After Width: | Height: | Size: 377 B |
Before Width: | Height: | Size: 398 B After Width: | Height: | Size: 377 B |
Before Width: | Height: | Size: 401 B After Width: | Height: | Size: 333 B |
Before Width: | Height: | Size: 508 B After Width: | Height: | Size: 425 B |
Before Width: | Height: | Size: 381 B After Width: | Height: | Size: 340 B |
Before Width: | Height: | Size: 402 B After Width: | Height: | Size: 359 B |
BIN
textures/techage_laser.png
Normal file
After Width: | Height: | Size: 604 B |
Before Width: | Height: | Size: 924 B After Width: | Height: | Size: 793 B |
Before Width: | Height: | Size: 281 B After Width: | Height: | Size: 234 B |
Before Width: | Height: | Size: 662 B After Width: | Height: | Size: 563 B |
Before Width: | Height: | Size: 346 B After Width: | Height: | Size: 288 B |
Before Width: | Height: | Size: 162 B After Width: | Height: | Size: 157 B |
Before Width: | Height: | Size: 397 B After Width: | Height: | Size: 349 B |
Before Width: | Height: | Size: 265 B After Width: | Height: | Size: 219 B |
Before Width: | Height: | Size: 827 B After Width: | Height: | Size: 734 B |
Before Width: | Height: | Size: 346 B After Width: | Height: | Size: 286 B |
Before Width: | Height: | Size: 168 B After Width: | Height: | Size: 166 B |
Before Width: | Height: | Size: 879 B After Width: | Height: | Size: 750 B |
Before Width: | Height: | Size: 593 B After Width: | Height: | Size: 592 B |
Before Width: | Height: | Size: 385 B After Width: | Height: | Size: 350 B |
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 256 B After Width: | Height: | Size: 255 B |
Before Width: | Height: | Size: 125 B After Width: | Height: | Size: 115 B |
Before Width: | Height: | Size: 242 B After Width: | Height: | Size: 229 B |
Before Width: | Height: | Size: 201 B After Width: | Height: | Size: 183 B |
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.7 KiB |
Before Width: | Height: | Size: 297 B After Width: | Height: | Size: 277 B |
Before Width: | Height: | Size: 319 B After Width: | Height: | Size: 311 B |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 878 B |