Merge branch 'master' into master
1
.gitignore
vendored
|
@ -48,7 +48,6 @@ local.properties
|
|||
*_p.c
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.pgc
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
default
|
||||
technic_worldgen
|
||||
concrete
|
||||
unifieddyes?
|
||||
intllib?
|
||||
moreblocks?
|
||||
|
|
|
@ -101,3 +101,87 @@ if minetest.get_modpath("moreblocks") then
|
|||
register_technic_stairs_alias("stairsplus", "marble_bricks", "technic", "marble_bricks")
|
||||
|
||||
end
|
||||
|
||||
local iclip_def = {
|
||||
description = "Insulator/cable clip",
|
||||
drawtype = "mesh",
|
||||
mesh = "technic_insulator_clip.obj",
|
||||
tiles = {"technic_insulator_clip.png"},
|
||||
is_ground_content = false,
|
||||
groups = {choppy=1, snappy=1, oddly_breakable_by_hand=1 },
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
}
|
||||
|
||||
local iclipfence_def = {
|
||||
description = "Insulator/cable clip",
|
||||
tiles = {"technic_insulator_clip.png"},
|
||||
is_ground_content = false,
|
||||
paramtype = "light",
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "connected",
|
||||
fixed = {
|
||||
{ -0.25, 0.75, -0.25, 0.25, 1.25, 0.25 }, -- the clip on top
|
||||
{ -0.125, 0.6875, -0.125, 0.125, 0.75, 0.125 },
|
||||
{ -0.1875, 0.625, -0.1875, 0.1875, 0.6875, 0.1875 },
|
||||
{ -0.125, 0.5625, -0.125, 0.125, 0.625, 0.125 },
|
||||
{ -0.1875, 0.5, -0.1875, 0.1875, 0.5625, 0.1875 },
|
||||
{ -0.125, 0.4375, -0.125, 0.125, 0.5, 0.125 },
|
||||
{ -0.1875, 0.375, -0.1875, 0.1875, 0.4375, 0.1875 },
|
||||
{ -0.125, -0.5, -0.125, 0.125, 0.375, 0.125 }, -- the post, slightly short
|
||||
},
|
||||
-- connect_top =
|
||||
-- connect_bottom =
|
||||
connect_front = {{-1/16,3/16,-1/2,1/16,5/16,-1/8},
|
||||
{-1/16,-5/16,-1/2,1/16,-3/16,-1/8}},
|
||||
connect_left = {{-1/2,3/16,-1/16,-1/8,5/16,1/16},
|
||||
{-1/2,-5/16,-1/16,-1/8,-3/16,1/16}},
|
||||
connect_back = {{-1/16,3/16,1/8,1/16,5/16,1/2},
|
||||
{-1/16,-5/16,1/8,1/16,-3/16,1/2}},
|
||||
connect_right = {{1/8,3/16,-1/16,1/2,5/16,1/16},
|
||||
{1/8,-5/16,-1/16,1/2,-3/16,1/16}},
|
||||
},
|
||||
connects_to = {"group:fence", "group:wood", "group:tree"},
|
||||
groups = {fence=1, choppy=1, snappy=1, oddly_breakable_by_hand=1 },
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
}
|
||||
|
||||
if minetest.get_modpath("unifieddyes") then
|
||||
iclip_def.paramtype2 = "colorwallmounted"
|
||||
iclip_def.palette = "unifieddyes_palette_colorwallmounted.png"
|
||||
iclip_def.after_place_node = function(pos, placer, itemstack, pointed_thing)
|
||||
unifieddyes.fix_rotation(pos, placer, itemstack, pointed_thing)
|
||||
unifieddyes.recolor_on_place(pos, placer, itemstack, pointed_thing)
|
||||
end
|
||||
iclip_def.after_dig_node = unifieddyes.after_dig_node
|
||||
iclip_def.groups = {choppy=1, snappy=1, oddly_breakable_by_hand=1, ud_param2_colorable = 1}
|
||||
|
||||
iclipfence_def.paramtype2 = "color"
|
||||
iclipfence_def.palette = "unifieddyes_palette_extended.png"
|
||||
iclipfence_def.on_construct = unifieddyes.on_construct
|
||||
iclipfence_def.after_place_node = unifieddyes.recolor_on_place
|
||||
iclipfence_def.after_dig_node = unifieddyes.after_dig_node
|
||||
iclipfence_def.groups = {fence=1, choppy=1, snappy=1, oddly_breakable_by_hand=1, ud_param2_colorable = 1}
|
||||
iclipfence_def.place_param2 = 171 -- medium amber, low saturation, closest color to default:wood
|
||||
end
|
||||
|
||||
minetest.register_node(":technic:insulator_clip", iclip_def)
|
||||
minetest.register_node(":technic:insulator_clip_fencepost", iclipfence_def)
|
||||
|
||||
minetest.register_craft({
|
||||
output = "technic:insulator_clip",
|
||||
recipe = {
|
||||
{ "", "dye:white", ""},
|
||||
{ "", "technic:raw_latex", ""},
|
||||
{ "technic:raw_latex", "default:stone", "technic:raw_latex"},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "technic:insulator_clip_fencepost 2",
|
||||
recipe = {
|
||||
{ "", "dye:white", ""},
|
||||
{ "", "technic:raw_latex", ""},
|
||||
{ "technic:raw_latex", "default:fence_wood", "technic:raw_latex"},
|
||||
}
|
||||
})
|
||||
|
|
173
extranodes/models/technic_insulator_clip.obj
Normal file
|
@ -0,0 +1,173 @@
|
|||
# Blender v2.72 (sub 0) OBJ File: ''
|
||||
# www.blender.org
|
||||
o Cube
|
||||
v -0.500000 -0.500000 0.500000
|
||||
v -0.500000 -0.500000 -0.500000
|
||||
v 0.500000 -0.500000 -0.500000
|
||||
v 0.500000 -0.500000 0.500000
|
||||
v -0.249997 0.500000 0.249997
|
||||
v -0.249997 0.500000 -0.249997
|
||||
v 0.249997 0.500000 -0.249997
|
||||
v 0.249997 0.500000 0.249997
|
||||
v -0.187500 0.500000 0.187500
|
||||
v -0.187500 0.500000 -0.187500
|
||||
v 0.187500 0.500000 -0.187500
|
||||
v 0.187500 0.500000 0.187500
|
||||
v -0.187500 0.750000 0.187500
|
||||
v -0.187500 0.750000 -0.187500
|
||||
v 0.187500 0.750000 -0.187500
|
||||
v 0.187500 0.750000 0.187500
|
||||
v -0.250000 0.750000 0.250000
|
||||
v -0.250000 0.750000 -0.250000
|
||||
v 0.250000 0.750000 -0.250000
|
||||
v 0.250000 0.750000 0.250000
|
||||
v -0.250000 1.250000 0.250000
|
||||
v -0.250000 1.250000 -0.250000
|
||||
v 0.250000 1.250000 -0.250000
|
||||
v 0.250000 1.250000 0.250000
|
||||
v -0.500000 0.312500 0.500000
|
||||
v -0.500000 0.312500 -0.500000
|
||||
v 0.500000 0.312500 -0.500000
|
||||
v 0.500000 0.312500 0.500000
|
||||
v 0.187500 0.625000 0.187500
|
||||
v 0.187500 0.625000 -0.187500
|
||||
v -0.187500 0.625000 -0.187500
|
||||
v -0.187500 0.625000 0.187500
|
||||
v 0.187500 0.562500 0.187500
|
||||
v 0.187500 0.687500 -0.187500
|
||||
v -0.187500 0.687500 -0.187500
|
||||
v -0.187500 0.562500 0.187500
|
||||
v 0.187500 0.687500 0.187500
|
||||
v 0.187500 0.562500 -0.187500
|
||||
v -0.187500 0.562500 -0.187500
|
||||
v -0.187500 0.687500 0.187500
|
||||
v 0.168668 0.531250 0.168668
|
||||
v 0.168668 0.718750 -0.168668
|
||||
v -0.168668 0.718750 -0.168668
|
||||
v -0.168668 0.531250 0.168668
|
||||
v 0.168668 0.656250 0.168668
|
||||
v 0.168668 0.593750 -0.168668
|
||||
v -0.168668 0.593750 -0.168668
|
||||
v -0.168668 0.656250 0.168668
|
||||
v 0.168668 0.593750 0.168668
|
||||
v 0.168668 0.656250 -0.168668
|
||||
v -0.168668 0.656250 -0.168668
|
||||
v -0.168668 0.593750 0.168668
|
||||
v 0.168668 0.718750 0.168668
|
||||
v 0.168668 0.531250 -0.168668
|
||||
v -0.168668 0.531250 -0.168668
|
||||
v -0.168668 0.718750 0.168668
|
||||
vt 1.000000 0.000000
|
||||
vt 1.000000 1.000000
|
||||
vt 0.000000 1.000000
|
||||
vt 0.000000 0.000000
|
||||
vt 0.749997 0.749997
|
||||
vt 0.749997 0.250003
|
||||
vt 0.250003 0.250003
|
||||
vt 0.250003 0.749997
|
||||
vt 0.000000 0.812500
|
||||
vt 1.000000 0.812500
|
||||
vt 0.312500 0.312500
|
||||
vt 0.312500 0.687500
|
||||
vt 0.687500 0.312500
|
||||
vt 0.687500 0.687500
|
||||
vt 0.331332 1.218750
|
||||
vt 0.668668 1.218750
|
||||
vt 0.687500 1.250000
|
||||
vt 0.312500 1.250000
|
||||
vt 0.750000 1.250000
|
||||
vt 0.750000 1.750000
|
||||
vt 0.250000 1.750000
|
||||
vt 0.250000 1.250000
|
||||
vt 0.331332 1.093750
|
||||
vt 0.668668 1.093750
|
||||
vt 0.687500 1.125000
|
||||
vt 0.312500 1.125000
|
||||
vt 0.331332 1.093750
|
||||
vt 0.668668 1.093750
|
||||
vt 0.331332 1.156250
|
||||
vt 0.668668 1.156250
|
||||
vt 0.687500 1.187500
|
||||
vt 0.312500 1.187500
|
||||
vt 0.331332 1.156250
|
||||
vt 0.668668 1.156250
|
||||
vt 0.331332 1.031250
|
||||
vt 0.668668 1.031250
|
||||
vt 0.687500 1.062500
|
||||
vt 0.312500 1.062500
|
||||
vt 0.312500 1.000000
|
||||
vt 0.687500 1.000000
|
||||
vn 0.000000 -1.000000 -0.000000
|
||||
vn -0.600000 0.800000 -0.000000
|
||||
vn 0.000000 0.800000 -0.600000
|
||||
vn 0.600000 0.800000 0.000000
|
||||
vn -0.000000 0.000000 1.000000
|
||||
vn 0.000000 1.000000 0.000000
|
||||
vn 0.856500 -0.516200 0.000000
|
||||
vn 0.000000 -0.516200 -0.856500
|
||||
vn -0.000000 -0.516200 0.856500
|
||||
vn -0.856500 -0.516200 -0.000000
|
||||
vn -1.000000 0.000000 -0.000000
|
||||
vn 0.000000 -0.000000 -1.000000
|
||||
vn 1.000000 -0.000000 0.000000
|
||||
vn -0.000000 0.800000 0.600000
|
||||
vn 0.856500 0.516200 0.000000
|
||||
vn 0.000000 0.516200 -0.856500
|
||||
vn -0.000000 0.516200 0.856500
|
||||
vn -0.856500 0.516200 -0.000000
|
||||
g Cube_Cube_Material
|
||||
s off
|
||||
f 1/1/1 2/2/1 3/3/1 4/4/1
|
||||
f 25/2/2 5/5/2 6/6/2 26/1/2
|
||||
f 26/1/3 6/6/3 7/7/3 27/4/3
|
||||
f 27/4/4 7/7/4 8/8/4 28/3/4
|
||||
f 25/9/5 1/4/5 4/1/5 28/10/5
|
||||
f 8/8/6 7/7/6 11/11/6 12/12/6
|
||||
f 7/7/6 6/6/6 10/13/6 11/11/6
|
||||
f 5/5/6 8/8/6 12/12/6 9/14/6
|
||||
f 6/6/6 5/5/6 9/14/6 10/13/6
|
||||
f 53/15/7 42/16/7 15/17/7 16/18/7
|
||||
f 42/15/8 43/16/8 14/17/8 15/18/8
|
||||
f 56/15/9 53/16/9 16/17/9 13/18/9
|
||||
f 43/15/10 56/16/10 13/17/10 14/18/10
|
||||
f 14/4/1 18/4/1 19/4/1 15/4/1
|
||||
f 17/19/11 21/20/11 22/21/11 18/22/11
|
||||
f 18/19/12 22/20/12 23/21/12 19/22/12
|
||||
f 19/19/13 23/20/13 24/21/13 20/22/13
|
||||
f 21/21/5 17/22/5 20/19/5 24/20/5
|
||||
f 21/5/6 24/8/6 23/7/6 22/6/6
|
||||
f 15/4/1 19/4/1 20/4/1 16/4/1
|
||||
f 16/4/1 20/4/1 17/4/1 13/4/1
|
||||
f 13/4/1 17/4/1 18/4/1 14/4/1
|
||||
f 1/1/11 25/10/11 26/9/11 2/4/11
|
||||
f 2/1/12 26/10/12 27/9/12 3/4/12
|
||||
f 3/1/13 27/10/13 28/9/13 4/4/13
|
||||
f 5/5/14 25/2/14 28/3/14 8/8/14
|
||||
f 49/23/7 46/24/7 30/25/7 29/26/7
|
||||
f 46/27/8 47/28/8 31/25/8 30/26/8
|
||||
f 52/23/9 49/24/9 29/25/9 32/26/9
|
||||
f 47/23/10 52/24/10 32/25/10 31/26/10
|
||||
f 45/29/7 50/30/7 34/31/7 37/32/7
|
||||
f 50/33/8 51/34/8 35/31/8 34/32/8
|
||||
f 48/33/9 45/34/9 37/31/9 40/32/9
|
||||
f 51/29/10 48/30/10 40/31/10 35/32/10
|
||||
f 41/35/7 54/36/7 38/37/7 33/38/7
|
||||
f 54/35/8 55/36/8 39/37/8 38/38/8
|
||||
f 44/35/9 41/36/9 33/37/9 36/38/9
|
||||
f 55/35/10 44/36/10 36/37/10 39/38/10
|
||||
f 37/32/15 34/31/15 42/16/15 53/15/15
|
||||
f 34/32/16 35/31/16 43/16/16 42/15/16
|
||||
f 40/32/17 37/31/17 53/16/17 56/15/17
|
||||
f 35/32/18 40/31/18 56/16/18 43/15/18
|
||||
f 33/38/15 38/37/15 46/24/15 49/23/15
|
||||
f 38/38/16 39/37/16 47/28/16 46/27/16
|
||||
f 36/38/17 33/37/17 49/24/17 52/23/17
|
||||
f 39/38/18 36/37/18 52/24/18 47/23/18
|
||||
f 29/26/15 30/25/15 50/30/15 45/29/15
|
||||
f 30/26/16 31/25/16 51/34/16 50/33/16
|
||||
f 32/26/17 29/25/17 45/34/17 48/33/17
|
||||
f 31/26/18 32/25/18 48/30/18 51/29/18
|
||||
f 12/39/15 11/40/15 54/36/15 41/35/15
|
||||
f 11/39/16 10/40/16 55/36/16 54/35/16
|
||||
f 9/39/17 12/40/17 41/36/17 44/35/17
|
||||
f 10/39/18 9/40/18 44/36/18 55/35/18
|
BIN
extranodes/textures/technic_insulator_clip.png
Normal file
After Width: | Height: | Size: 226 B |
|
@ -766,14 +766,12 @@ source than by actual attenuation. Dirt halves radiation in 2.4 m,
|
|||
and stone in 1.7 m. When a shield must be deliberately constructed,
|
||||
the preferred materials are metals, the denser the better. Iron and
|
||||
steel halve radiation in 1.1 m, copper in 1.0 m, and silver in 0.95 m.
|
||||
Lead would halve in 0.69 m if it were in the game, but it's not, which
|
||||
poses a bit of a problem due to the drawbacks of the three materials in
|
||||
the game that are better shielding than silver. Gold halves radiation
|
||||
Lead would halve in 0.69 m (its in-game shielding value is 80). Gold halves radiation
|
||||
in 0.53 m (factor of 3.7 per meter), but is a bit scarce to use for
|
||||
this purpose. Uranium halves radiation in 0.31 m (factor of 9.4 per
|
||||
meter), but is itself radioactive. The very best shielding in the game
|
||||
is nyancat material (nyancats and their rainbow blocks), which halves
|
||||
radiation in 0.22 m (factor of 24 per meter), but is extremely scarce.
|
||||
radiation in 0.22 m (factor of 24 per meter), but is extremely scarce. See [technic/technic/radiation.lua](https://github.com/minetest-technic/technic/blob/master/technic/radiation.lua) for the in-game shielding values, which are different from real-life values.
|
||||
|
||||
If the theoretical radiation damage from a particular source is
|
||||
sufficiently small, due to distance and shielding, then no damage at all
|
||||
|
|
|
@ -25,3 +25,11 @@ RealBadAngel: (WTFPL)
|
|||
* Everything else.
|
||||
|
||||
CC BY-SA 3.0: <http://creativecommons.org/licenses/by-sa/3.0/>
|
||||
|
||||
Sound licenses:
|
||||
|
||||
veikk0 (Veikko Mäkelä) (CC BY-SA 4.0):
|
||||
* technic_hv_nuclear_reactor_siren_danger_loop.ogg
|
||||
* Derived from "Nuclear alarm.wav" by Freesound.org user rene___ from <https://freesound.org/people/rene___/sounds/56778/>. Originally licensed under CC0 1.0 <https://creativecommons.org/publicdomain/zero/1.0/>
|
||||
|
||||
CC BY-SA 4.0: <https://creativecommons.org/licenses/by-sa/4.0/>
|
|
@ -9,6 +9,9 @@ local defaults = {
|
|||
enable_wind_mill = "false",
|
||||
enable_frames = "false",
|
||||
enable_corium_griefing = "true",
|
||||
enable_radiation_protection = "true",
|
||||
enable_entity_radiation_damage = "true",
|
||||
enable_longterm_radiation_damage = "true",
|
||||
}
|
||||
|
||||
for k, v in pairs(defaults) do
|
||||
|
|
|
@ -191,3 +191,14 @@ minetest.register_craft({
|
|||
},
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "default:dirt 2",
|
||||
type = "shapeless",
|
||||
replacements = {{"bucket:bucket_water","bucket:bucket_empty"}},
|
||||
recipe = {
|
||||
"technic:stone_dust",
|
||||
"group:leaves",
|
||||
"bucket:bucket_water",
|
||||
"group:sand",
|
||||
},
|
||||
})
|
||||
|
|
|
@ -35,6 +35,9 @@ dofile(modpath.."/crafts.lua")
|
|||
-- Register functions
|
||||
dofile(modpath.."/register.lua")
|
||||
|
||||
-- Radiation
|
||||
dofile(modpath.."/radiation.lua")
|
||||
|
||||
-- Machines
|
||||
dofile(modpath.."/machines/init.lua")
|
||||
|
||||
|
|
|
@ -194,14 +194,16 @@ for p = 0, 35 do
|
|||
-- a natural (0.7%-fissile) uranium block having the activity of
|
||||
-- 9 uranium ore blocks (due to 9 ingots per block). The group
|
||||
-- value is proportional to the square root of the activity, and
|
||||
-- uranium ore has radioactive=1000. This yields radioactive=2065
|
||||
-- for a fully-depleted uranium block and radioactive=5286 for
|
||||
-- uranium ore has radioactive=1. This yields radioactive=1.0
|
||||
-- for a fully-depleted uranium block and radioactive=2.6 for
|
||||
-- a 3.5%-fissile uranium block.
|
||||
local radioactivity = math.floor(math.sqrt((1+5.55*p/35) * 18 / (1+5.55*7/35)) + 0.5);
|
||||
(ov or minetest.register_node)(block, {
|
||||
description = string.format(S("%.1f%%-Fissile Uranium Block"), p/10),
|
||||
tiles = {"technic_uranium_block.png"},
|
||||
is_ground_content = true,
|
||||
groups = {uranium_block=1, not_in_creative_inventory=nici, cracky=1, level=2, radioactive=math.floor(1000*math.sqrt((1+5.55*p/35) * 9 / (1+5.55*7/35)) + 0.5)},
|
||||
groups = {uranium_block=1, not_in_creative_inventory=nici,
|
||||
cracky=1, level=2, radioactive=radioactivity},
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
});
|
||||
if not ov then
|
||||
|
@ -219,3 +221,4 @@ for p = 0, 35 do
|
|||
})
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -26,8 +26,8 @@ Graphite = Lastra in graffite
|
|||
Carbon Cloth = Fibra di carbonio
|
||||
Raw Latex = Latex grezzo
|
||||
Rubber Fiber = Fibra di gomma
|
||||
%.1f%%-Fissile Uranium Ingot =
|
||||
%.1f%%-Fissile Uranium Block =
|
||||
%.1f%%-Fissile Uranium Ingot = %.1f%%-Lingotto di uranio fissile
|
||||
%.1f%%-Fissile Uranium Block = %.1f%%-Blocco di uranio fissile
|
||||
|
||||
## Machine misc
|
||||
Machine cannot be removed because it is not empty = La macchina non può essere rimossa perchè non è vuota
|
||||
|
@ -36,7 +36,7 @@ Inventory move disallowed due to protection = Impossibile muovere l'inventario a
|
|||
@1 Active (@2 EU) = @1 Attivo (@2 EU)
|
||||
%s Active = %s Attivo
|
||||
%s Disabled = %s Disabilitato
|
||||
%s Enabled =
|
||||
%s Enabled = %s Abilitato
|
||||
%s Idle = %s Inattivo
|
||||
%s Improperly Placed = %s Piazzato impropiamente
|
||||
%s Unpowered = %s Non alimentato
|
||||
|
@ -46,18 +46,18 @@ Inventory move disallowed due to protection = Impossibile muovere l'inventario a
|
|||
%s Finished = %s Finito
|
||||
Enable/Disable = Abilita/Disabilita
|
||||
Range = Raggio
|
||||
Upgrade Slots =
|
||||
Upgrade Slots = Alloggi di aggiornamento
|
||||
In: = Ingresso:
|
||||
Out: = Uscita:
|
||||
Slot %d =
|
||||
Slot %d = Alloggio %d
|
||||
Itemwise = Singolo elemento
|
||||
Stackwise = pila completa
|
||||
Owner: =
|
||||
Unlocked =
|
||||
Locked =
|
||||
Radius: =
|
||||
Enabled =
|
||||
Disabled =
|
||||
Owner: = Proprietario:
|
||||
Unlocked = Non chiuso a chiave
|
||||
Locked = Chiuso a chiave
|
||||
Radius: = Raggio:
|
||||
Enabled = Abilitato
|
||||
Disabled = Disabilitato
|
||||
|
||||
## Machine names
|
||||
# $1: Tier
|
||||
|
@ -84,10 +84,10 @@ Self-Contained Injector = Ignettore
|
|||
Constructor Mk%d = Costruttore Mk%d
|
||||
Frame = Cornice
|
||||
Frame Motor = Cornice del motore
|
||||
Template =
|
||||
Template (replacing) = Template (rimpiazzato)
|
||||
Template Motor =
|
||||
Template Tool =
|
||||
Template = Sagoma
|
||||
Template (replacing) = Sagoma (di rimpiazzo)
|
||||
Template Motor = Motore per sagome
|
||||
Template Tool = Strumento per sagome
|
||||
Battery Box = Box batterie
|
||||
Supply Converter = Trasformatore
|
||||
Switching Station = Stazione di controllo
|
||||
|
@ -96,7 +96,7 @@ Fuel-Fired Furnace = Fornace a carbone
|
|||
Wind Mill Frame = Pala eolica
|
||||
Forcefield = Campo di forza
|
||||
Nuclear Reactor Rod Compartment = Compartimento combustibile nucleare
|
||||
Administrative World Anchor =
|
||||
Administrative World Anchor = Ancora-mondo amministrativa
|
||||
|
||||
## Machine-specific
|
||||
# $1: Pruduced EU
|
||||
|
@ -111,12 +111,12 @@ Production at %d%% = Produzione a %d%%
|
|||
Choose Milling Program: = Scegliere un programma di Fresatura
|
||||
Slim Elements half / normal height: = Metà elementi sottili / altezza normale:
|
||||
Current track %s = Traccia corrente %s
|
||||
Stopped =
|
||||
Keeping %d/%d map blocks loaded =
|
||||
Digging not started =
|
||||
Digging finished =
|
||||
Digging %d m above machine =
|
||||
Digging %d m below machine =
|
||||
Stopped = Fermato
|
||||
Keeping %d/%d map blocks loaded = Mantenimento di %d/%d blocchi mappa caricati
|
||||
Digging not started = Scavo non iniziato
|
||||
Digging finished = Scavo finito
|
||||
Digging %d m above machine = Scavo di %d m sopra la macchina
|
||||
Digging %d m below machine = Scavo di %d m sotto la macchina
|
||||
|
||||
## CNC
|
||||
Cylinder = Cilindro
|
||||
|
@ -174,10 +174,10 @@ Talinite = Talinite
|
|||
Tin = Stagno
|
||||
Wrought Iron = Ferro Battuto
|
||||
Zinc = Zinco
|
||||
%.1f%%-Fissile Uranium =
|
||||
%.1f%%-Fissile Uranium = %.1f%%-Uranio fissile
|
||||
|
||||
## Tools
|
||||
RE Battery =
|
||||
RE Battery = Batteria RE
|
||||
Water Can = Serbatoio d'acqua
|
||||
Lava Can = Serbatoio di lava
|
||||
Chainsaw = Motosega
|
||||
|
|
|
@ -110,18 +110,17 @@ section through the middle:
|
|||
|
||||
CCCC CCCC
|
||||
CBBB BBBC
|
||||
CBSS SSBC
|
||||
CBSWWWSBC
|
||||
CBSW#WSBC
|
||||
CBSW|WSBC
|
||||
CBSS|SSBC
|
||||
CBLL LLBC
|
||||
CBLWWWLBC
|
||||
CBLW#WLBC
|
||||
CBLW|WLBC
|
||||
CBLL|LLBC
|
||||
CBBB|BBBC
|
||||
CCCC|CCCC
|
||||
C = Concrete, B = Blast-resistant concrete, S = Stainless Steel,
|
||||
C = Concrete, B = Blast-resistant concrete, L = Lead,
|
||||
W = water node, # = reactor core, | = HV cable
|
||||
|
||||
The man-hole and the HV cable are only in the middle, and the man-hole
|
||||
is optional.
|
||||
The man-hole is optional (but necessary for refueling).
|
||||
|
||||
For the reactor to operate and not melt down, it insists on the inner
|
||||
7x7x7 portion (from the core out to the blast-resistant concrete)
|
||||
|
@ -139,6 +138,9 @@ be mandatory, and for historical reasons (that it predates the
|
|||
implementation of radiation) it needs to continue being adequate
|
||||
shielding of legacy reactors. If it ever ceases to be adequate
|
||||
shielding for new reactors, legacy ones should be grandfathered.
|
||||
|
||||
For legacy reasons, if the reactor has a stainless steel layer instead
|
||||
of a lead layer it will be converted to a lead layer.
|
||||
--]]
|
||||
local function reactor_structure_badness(pos)
|
||||
local vm = VoxelManip()
|
||||
|
@ -149,11 +151,12 @@ local function reactor_structure_badness(pos)
|
|||
local area = VoxelArea:new({MinEdge=MinEdge, MaxEdge=MaxEdge})
|
||||
|
||||
local c_blast_concrete = minetest.get_content_id("technic:blast_resistant_concrete")
|
||||
local c_stainless_steel = minetest.get_content_id("technic:stainless_steel_block")
|
||||
local c_lead = minetest.get_content_id("technic:lead_block")
|
||||
local c_steel = minetest.get_content_id("technic:stainless_steel_block")
|
||||
local c_water_source = minetest.get_content_id("default:water_source")
|
||||
local c_water_flowing = minetest.get_content_id("default:water_flowing")
|
||||
|
||||
local blastlayer, steellayer, waterlayer = 0, 0, 0
|
||||
local blast_layer, steel_layer, lead_layer, water_layer = 0, 0, 0, 0
|
||||
|
||||
for z = pos1.z, pos2.z do
|
||||
for y = pos1.y, pos2.y do
|
||||
|
@ -163,28 +166,51 @@ local function reactor_structure_badness(pos)
|
|||
y == pos1.y or y == pos2.y or
|
||||
z == pos1.z or z == pos2.z then
|
||||
if cid == c_blast_concrete then
|
||||
blastlayer = blastlayer + 1
|
||||
blast_layer = blast_layer + 1
|
||||
end
|
||||
elseif x == pos1.x+1 or x == pos2.x-1 or
|
||||
y == pos1.y+1 or y == pos2.y-1 or
|
||||
z == pos1.z+1 or z == pos2.z-1 then
|
||||
if cid == c_stainless_steel then
|
||||
steellayer = steellayer + 1
|
||||
y == pos1.y+1 or y == pos2.y-1 or
|
||||
z == pos1.z+1 or z == pos2.z-1 then
|
||||
if cid == c_lead then
|
||||
lead_layer = lead_layer + 1
|
||||
elseif cid == c_steel then
|
||||
steel_layer = steel_layer + 1
|
||||
end
|
||||
elseif x == pos1.x+2 or x == pos2.x-2 or
|
||||
y == pos1.y+2 or y == pos2.y-2 or
|
||||
z == pos1.z+2 or z == pos2.z-2 then
|
||||
y == pos1.y+2 or y == pos2.y-2 or
|
||||
z == pos1.z+2 or z == pos2.z-2 then
|
||||
if cid == c_water_source or cid == c_water_flowing then
|
||||
waterlayer = waterlayer + 1
|
||||
water_layer = water_layer + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if waterlayer > 25 then waterlayer = 25 end
|
||||
if steellayer > 96 then steellayer = 96 end
|
||||
if blastlayer > 216 then blastlayer = 216 end
|
||||
return (25 - waterlayer) + (96 - steellayer) + (216 - blastlayer)
|
||||
|
||||
if steel_layer >= 96 then
|
||||
for z = pos1.z+1, pos2.z-1 do
|
||||
for y = pos1.y+1, pos2.y-1 do
|
||||
for x = pos1.x+1, pos2.x-1 do
|
||||
local vi = area:index(x, y, z)
|
||||
if x == pos1.x+1 or x == pos2.x-1 or
|
||||
y == pos1.y+1 or y == pos2.y-1 or
|
||||
z == pos1.z+1 or z == pos2.z-1 then
|
||||
if data[vi] == c_steel then
|
||||
data[vi] = c_lead
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
vm:set_data(data)
|
||||
vm:write_to_map()
|
||||
lead_layer = steel_layer
|
||||
end
|
||||
|
||||
if water_layer > 25 then water_layer = 25 end
|
||||
if lead_layer > 96 then lead_layer = 96 end
|
||||
if blast_layer > 216 then blast_layer = 216 end
|
||||
return (25 - water_layer) + (96 - lead_layer) + (216 - blast_layer)
|
||||
end
|
||||
|
||||
|
||||
|
@ -292,7 +318,7 @@ minetest.register_node("technic:hv_nuclear_reactor_core", {
|
|||
minetest.register_node("technic:hv_nuclear_reactor_core_active", {
|
||||
tiles = {"technic_hv_nuclear_reactor_core.png"},
|
||||
groups = {cracky=1, technic_machine=1, technic_hv=1,
|
||||
radioactive=11000, not_in_creative_inventory=1},
|
||||
radioactive=4, not_in_creative_inventory=1},
|
||||
legacy_facedir_simple = true,
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
drop = "technic:hv_nuclear_reactor_core",
|
||||
|
@ -339,399 +365,3 @@ minetest.register_node("technic:hv_nuclear_reactor_core_active", {
|
|||
technic.register_machine("HV", "technic:hv_nuclear_reactor_core", technic.producer)
|
||||
technic.register_machine("HV", "technic:hv_nuclear_reactor_core_active", technic.producer)
|
||||
|
||||
--[[
|
||||
Radioactivity
|
||||
|
||||
Radiation resistance represents the extent to which a material
|
||||
attenuates radiation passing through it; i.e., how good a radiation
|
||||
shield it is. This is identified per node type. For materials that
|
||||
exist in real life, the radiation resistance value that this system
|
||||
uses for a node type consisting of a solid cube of that material is the
|
||||
(approximate) number of halvings of ionising radiation that is achieved
|
||||
by a meter of the material in real life. This is approximately
|
||||
proportional to density, which provides a good way to estimate it.
|
||||
Homogeneous mixtures of materials have radiation resistance computed
|
||||
by a simple weighted mean. Note that the amount of attenuation that
|
||||
a material achieves in-game is not required to be (and is not) the
|
||||
same as the attenuation achieved in real life.
|
||||
|
||||
Radiation resistance for a node type may be specified in the node
|
||||
definition, under the key "radiation_resistance". As an interim
|
||||
measure, until node definitions widely include this, this code
|
||||
knows a bunch of values for particular node types in several mods,
|
||||
and values for groups of node types. The node definition takes
|
||||
precedence if it specifies a value. Nodes for which no value at
|
||||
all is known are taken to provide no radiation resistance at all;
|
||||
this is appropriate for the majority of node types. Only node types
|
||||
consisting of a fairly homogeneous mass of material should report
|
||||
non-zero radiation resistance; anything with non-uniform geometry
|
||||
or complex internal structure should show no radiation resistance.
|
||||
Fractional resistance values are permitted.
|
||||
--]]
|
||||
|
||||
local default_radiation_resistance_per_node = {
|
||||
["default:brick"] = 13,
|
||||
["default:bronzeblock"] = 45,
|
||||
["default:clay"] = 15,
|
||||
["default:coalblock"] = 9.6,
|
||||
["default:cobble"] = 15,
|
||||
["default:copperblock"] = 46,
|
||||
["default:desert_cobble"] = 15,
|
||||
["default:desert_sand"] = 10,
|
||||
["default:desert_stone"] = 17,
|
||||
["default:desert_stonebrick"] = 17,
|
||||
["default:diamondblock"] = 24,
|
||||
["default:dirt"] = 8.2,
|
||||
["default:dirt_with_grass"] = 8.2,
|
||||
["default:dirt_with_grass_footsteps"] = 8.2,
|
||||
["default:dirt_with_snow"] = 8.2,
|
||||
["default:glass"] = 17,
|
||||
["default:goldblock"] = 170,
|
||||
["default:gravel"] = 10,
|
||||
["default:ice"] = 5.6,
|
||||
["default:lava_flowing"] = 8.5,
|
||||
["default:lava_source"] = 17,
|
||||
["default:mese"] = 21,
|
||||
["default:mossycobble"] = 15,
|
||||
["default:nyancat"] = 1000,
|
||||
["default:nyancat_rainbow"] = 1000,
|
||||
["default:obsidian"] = 18,
|
||||
["default:obsidian_glass"] = 18,
|
||||
["default:sand"] = 10,
|
||||
["default:sandstone"] = 15,
|
||||
["default:sandstonebrick"] = 15,
|
||||
["default:snowblock"] = 1.7,
|
||||
["default:steelblock"] = 40,
|
||||
["default:stone"] = 17,
|
||||
["default:stone_with_coal"] = 16,
|
||||
["default:stone_with_copper"] = 20,
|
||||
["default:stone_with_diamond"] = 18,
|
||||
["default:stone_with_gold"] = 34,
|
||||
["default:stone_with_iron"] = 20,
|
||||
["default:stone_with_mese"] = 17,
|
||||
["default:stonebrick"] = 17,
|
||||
["default:water_flowing"] = 2.8,
|
||||
["default:water_source"] = 5.6,
|
||||
["farming:desert_sand_soil"] = 10,
|
||||
["farming:desert_sand_soil_wet"] = 10,
|
||||
["farming:soil"] = 8.2,
|
||||
["farming:soil_wet"] = 8.2,
|
||||
["glooptest:akalin_crystal_glass"] = 21,
|
||||
["glooptest:akalinblock"] = 40,
|
||||
["glooptest:alatro_crystal_glass"] = 21,
|
||||
["glooptest:alatroblock"] = 40,
|
||||
["glooptest:amethystblock"] = 18,
|
||||
["glooptest:arol_crystal_glass"] = 21,
|
||||
["glooptest:crystal_glass"] = 21,
|
||||
["glooptest:emeraldblock"] = 19,
|
||||
["glooptest:heavy_crystal_glass"] = 21,
|
||||
["glooptest:mineral_akalin"] = 20,
|
||||
["glooptest:mineral_alatro"] = 20,
|
||||
["glooptest:mineral_amethyst"] = 17,
|
||||
["glooptest:mineral_arol"] = 20,
|
||||
["glooptest:mineral_desert_coal"] = 16,
|
||||
["glooptest:mineral_desert_iron"] = 20,
|
||||
["glooptest:mineral_emerald"] = 17,
|
||||
["glooptest:mineral_kalite"] = 20,
|
||||
["glooptest:mineral_ruby"] = 18,
|
||||
["glooptest:mineral_sapphire"] = 18,
|
||||
["glooptest:mineral_talinite"] = 20,
|
||||
["glooptest:mineral_topaz"] = 18,
|
||||
["glooptest:reinforced_crystal_glass"] = 21,
|
||||
["glooptest:rubyblock"] = 27,
|
||||
["glooptest:sapphireblock"] = 27,
|
||||
["glooptest:talinite_crystal_glass"] = 21,
|
||||
["glooptest:taliniteblock"] = 40,
|
||||
["glooptest:topazblock"] = 24,
|
||||
["mesecons_extrawires:mese_powered"] = 21,
|
||||
["moreblocks:cactus_brick"] = 13,
|
||||
["moreblocks:cactus_checker"] = 8.5,
|
||||
["moreblocks:circle_stone_bricks"] = 17,
|
||||
["moreblocks:clean_glass"] = 17,
|
||||
["moreblocks:coal_checker"] = 9.0,
|
||||
["moreblocks:coal_glass"] = 17,
|
||||
["moreblocks:coal_stone"] = 17,
|
||||
["moreblocks:coal_stone_bricks"] = 17,
|
||||
["moreblocks:glow_glass"] = 17,
|
||||
["moreblocks:grey_bricks"] = 15,
|
||||
["moreblocks:iron_checker"] = 11,
|
||||
["moreblocks:iron_glass"] = 17,
|
||||
["moreblocks:iron_stone"] = 17,
|
||||
["moreblocks:iron_stone_bricks"] = 17,
|
||||
["moreblocks:plankstone"] = 9.3,
|
||||
["moreblocks:split_stone_tile"] = 15,
|
||||
["moreblocks:split_stone_tile_alt"] = 15,
|
||||
["moreblocks:stone_tile"] = 15,
|
||||
["moreblocks:super_glow_glass"] = 17,
|
||||
["moreblocks:tar"] = 7.0,
|
||||
["moreblocks:wood_tile"] = 1.7,
|
||||
["moreblocks:wood_tile_center"] = 1.7,
|
||||
["moreblocks:wood_tile_down"] = 1.7,
|
||||
["moreblocks:wood_tile_flipped"] = 1.7,
|
||||
["moreblocks:wood_tile_full"] = 1.7,
|
||||
["moreblocks:wood_tile_left"] = 1.7,
|
||||
["moreblocks:wood_tile_right"] = 1.7,
|
||||
["moreblocks:wood_tile_up"] = 1.7,
|
||||
["moreores:mineral_mithril"] = 18,
|
||||
["moreores:mineral_silver"] = 21,
|
||||
["moreores:mineral_tin"] = 19,
|
||||
["moreores:mithril_block"] = 26,
|
||||
["moreores:silver_block"] = 53,
|
||||
["moreores:tin_block"] = 37,
|
||||
["snow:snow_brick"] = 2.8,
|
||||
["technic:brass_block"] = 43,
|
||||
["technic:carbon_steel_block"] = 40,
|
||||
["technic:cast_iron_block"] = 40,
|
||||
["technic:chernobylite_block"] = 40,
|
||||
["technic:chromium_block"] = 37,
|
||||
["technic:corium_flowing"] = 40,
|
||||
["technic:corium_source"] = 80,
|
||||
["technic:granite"] = 18,
|
||||
["technic:lead_block"] = 80,
|
||||
["technic:marble"] = 18,
|
||||
["technic:marble_bricks"] = 18,
|
||||
["technic:mineral_chromium"] = 19,
|
||||
["technic:mineral_uranium"] = 71,
|
||||
["technic:mineral_zinc"] = 19,
|
||||
["technic:stainless_steel_block"] = 40,
|
||||
["technic:zinc_block"] = 36,
|
||||
["tnt:tnt"] = 11,
|
||||
["tnt:tnt_burning"] = 11,
|
||||
}
|
||||
local default_radiation_resistance_per_group = {
|
||||
concrete = 16,
|
||||
tree = 3.4,
|
||||
uranium_block = 500,
|
||||
wood = 1.7,
|
||||
}
|
||||
local cache_radiation_resistance = {}
|
||||
local function node_radiation_resistance(node_name)
|
||||
local eff = cache_radiation_resistance[node_name]
|
||||
if eff then return eff end
|
||||
local def = minetest.registered_nodes[node_name]
|
||||
eff = def and def.radiation_resistance or
|
||||
default_radiation_resistance_per_node[node_name]
|
||||
if def and not eff then
|
||||
for g, v in pairs(def.groups) do
|
||||
if v > 0 and default_radiation_resistance_per_group[g] then
|
||||
eff = default_radiation_resistance_per_group[g]
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
if not eff then eff = 0 end
|
||||
cache_radiation_resistance[node_name] = eff
|
||||
return eff
|
||||
end
|
||||
|
||||
--[[
|
||||
Radioactive nodes cause damage to nearby players. The damage
|
||||
effect depends on the intrinsic strength of the radiation source,
|
||||
the distance between the source and the player, and the shielding
|
||||
effect of the intervening material. These determine a rate of damage;
|
||||
total damage caused is the integral of this over time.
|
||||
|
||||
In the absence of effective shielding, for a specific source the
|
||||
damage rate varies realistically in inverse proportion to the square
|
||||
of the distance. (Distance is measured to the player's abdomen,
|
||||
not to the nominal player position which corresponds to the foot.)
|
||||
However, if the player is inside a non-walkable (liquid or gaseous)
|
||||
radioactive node, the nominal distance could go to zero, yielding
|
||||
infinite damage. In that case, the player's body is displacing the
|
||||
radioactive material, so the effective distance should remain non-zero.
|
||||
We therefore apply a lower distance bound of sqrt(0.75), which is
|
||||
the maximum distance one can get from the node center within the node.
|
||||
|
||||
A radioactive node is identified by being in the "radioactive" group,
|
||||
and the group value signifies the strength of the radiation source.
|
||||
The group value is 1000 times the distance from a node at which
|
||||
an unshielded player will be damaged by 0.25 HP/s. Or, equivalently,
|
||||
it is 2000 times the square root of the damage rate in HP/s that an
|
||||
unshielded player 1 node away will take.
|
||||
|
||||
Shielding is assessed by adding the shielding values of all nodes
|
||||
between the source node and the player, ignoring the source node itself.
|
||||
As in reality, shielding causes exponential attenuation of radiation.
|
||||
However, the effect is scaled down relative to real life. A node with
|
||||
radiation resistance value R yields attenuation of sqrt(R) * 0.1 nepers.
|
||||
(In real life it would be about R * 0.69 nepers, by the definition
|
||||
of the radiation resistance values.) The sqrt part of this formula
|
||||
scales down the differences between shielding types, reflecting the
|
||||
game's simplification of making expensive materials such as gold
|
||||
readily available in cubes. The multiplicative factor in the
|
||||
formula scales down the difference between shielded and unshielded
|
||||
safe distances, avoiding the latter becoming impractically large.
|
||||
|
||||
Damage is processed at rates down to 0.25 HP/s, which in the absence of
|
||||
shielding is attained at the distance specified by the "radioactive"
|
||||
group value. Computed damage rates below 0.25 HP/s result in no
|
||||
damage at all to the player. This gives the player an opportunity
|
||||
to be safe, and limits the range at which source/player interactions
|
||||
need to be considered.
|
||||
--]]
|
||||
local abdomen_offset = vector.new(0, 1, 0)
|
||||
local abdomen_offset_length = vector.length(abdomen_offset)
|
||||
local cache_scaled_shielding = {}
|
||||
|
||||
local function dmg_player(pos, o, strength)
|
||||
local pl_pos = vector.add(o:getpos(), abdomen_offset)
|
||||
local shielding = 0
|
||||
local dist = vector.distance(pos, pl_pos)
|
||||
for ray_pos in technic.trace_node_ray(pos,
|
||||
vector.direction(pos, pl_pos), dist) do
|
||||
if not vector.equals(ray_pos, pos) then
|
||||
local shield_name = minetest.get_node(ray_pos).name
|
||||
local shield_val = cache_scaled_shielding[sname]
|
||||
if not shield_val then
|
||||
shield_val = math.sqrt(node_radiation_resistance(shield_name)) * 0.025
|
||||
cache_scaled_shielding[shield_name] = shield_val
|
||||
end
|
||||
shielding = shielding + shield_val
|
||||
end
|
||||
end
|
||||
local dmg = (0.25e-6 * strength * strength) /
|
||||
(math.max(0.75, dist * dist) * math.exp(shielding))
|
||||
if dmg >= 0.25 then
|
||||
local dmg_int = math.floor(dmg)
|
||||
-- The closer you are to getting one more damage point,
|
||||
-- the more likely it will be added.
|
||||
if math.random() < dmg - dmg_int then
|
||||
dmg_int = dmg_int + 1
|
||||
end
|
||||
if dmg_int > 0 then
|
||||
o:set_hp(math.max(o:get_hp() - dmg_int, 0))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function dmg_abm(pos, node)
|
||||
local strength = minetest.get_item_group(node.name, "radioactive")
|
||||
for _, o in pairs(minetest.get_objects_inside_radius(pos,
|
||||
strength * 0.001 + abdomen_offset_length)) do
|
||||
if o:is_player() then
|
||||
dmg_player(pos, o, strength)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
if minetest.setting_getbool("enable_damage") then
|
||||
minetest.register_abm({
|
||||
nodenames = {"group:radioactive"},
|
||||
interval = 1,
|
||||
chance = 1,
|
||||
action = dmg_abm,
|
||||
})
|
||||
end
|
||||
|
||||
-- Radioactive materials that can result from destroying a reactor
|
||||
local griefing = technic.config:get_bool("enable_corium_griefing")
|
||||
|
||||
for _, state in pairs({"flowing", "source"}) do
|
||||
minetest.register_node("technic:corium_"..state, {
|
||||
description = S(state == "source" and "Corium Source" or "Flowing Corium"),
|
||||
drawtype = (state == "source" and "liquid" or "flowingliquid"),
|
||||
[state == "source" and "tiles" or "special_tiles"] = {{
|
||||
name = "technic_corium_"..state.."_animated.png",
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 16,
|
||||
aspect_h = 16,
|
||||
length = 3.0,
|
||||
},
|
||||
}},
|
||||
paramtype = "light",
|
||||
paramtype2 = (state == "flowing" and "flowingliquid" or nil),
|
||||
light_source = (state == "source" and 8 or 5),
|
||||
walkable = false,
|
||||
pointable = false,
|
||||
diggable = false,
|
||||
buildable_to = true,
|
||||
drop = "",
|
||||
drowning = 1,
|
||||
liquidtype = state,
|
||||
liquid_alternative_flowing = "technic:corium_flowing",
|
||||
liquid_alternative_source = "technic:corium_source",
|
||||
liquid_viscosity = LAVA_VISC,
|
||||
liquid_renewable = false,
|
||||
damage_per_second = 6,
|
||||
post_effect_color = {a=192, r=80, g=160, b=80},
|
||||
groups = {
|
||||
liquid = 2,
|
||||
hot = 3,
|
||||
igniter = (griefing and 1 or 0),
|
||||
radioactive = (state == "source" and 32000 or 16000),
|
||||
not_in_creative_inventory = (state == "flowing" and 1 or nil),
|
||||
},
|
||||
})
|
||||
end
|
||||
|
||||
if rawget(_G, "bucket") and bucket.register_liquid then
|
||||
bucket.register_liquid(
|
||||
"technic:corium_source",
|
||||
"technic:corium_flowing",
|
||||
"technic:bucket_corium",
|
||||
"technic_bucket_corium.png",
|
||||
"Corium Bucket"
|
||||
)
|
||||
end
|
||||
|
||||
minetest.register_node("technic:chernobylite_block", {
|
||||
description = S("Chernobylite Block"),
|
||||
tiles = {"technic_chernobylite_block.png"},
|
||||
is_ground_content = true,
|
||||
groups = {cracky=1, radioactive=5000, level=2},
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
light_source = 2,
|
||||
})
|
||||
|
||||
minetest.register_abm({
|
||||
nodenames = {"group:water"},
|
||||
neighbors = {"technic:corium_source"},
|
||||
interval = 1,
|
||||
chance = 1,
|
||||
action = function(pos, node)
|
||||
minetest.remove_node(pos)
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_abm({
|
||||
nodenames = {"technic:corium_flowing"},
|
||||
neighbors = {"group:water"},
|
||||
interval = 1,
|
||||
chance = 1,
|
||||
action = function(pos, node)
|
||||
minetest.set_node(pos, {name="technic:chernobylite_block"})
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_abm({
|
||||
nodenames = {"technic:corium_flowing"},
|
||||
interval = 5,
|
||||
chance = (griefing and 10 or 1),
|
||||
action = function(pos, node)
|
||||
minetest.set_node(pos, {name="technic:chernobylite_block"})
|
||||
end,
|
||||
})
|
||||
|
||||
if griefing then
|
||||
minetest.register_abm({
|
||||
nodenames = {"technic:corium_source", "technic:corium_flowing"},
|
||||
interval = 4,
|
||||
chance = 4,
|
||||
action = function(pos, node)
|
||||
for _, offset in ipairs({
|
||||
vector.new(1,0,0),
|
||||
vector.new(-1,0,0),
|
||||
vector.new(0,0,1),
|
||||
vector.new(0,0,-1),
|
||||
vector.new(0,-1,0),
|
||||
}) do
|
||||
if math.random(8) == 1 then
|
||||
minetest.dig_node(vector.add(pos, offset))
|
||||
end
|
||||
end
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ minetest.register_craft({
|
|||
local quarry_dig_above_nodes = 3 -- How far above the quarry we will dig nodes
|
||||
local quarry_max_depth = 100
|
||||
local quarry_demand = 10000
|
||||
local quarry_eject_dir = vector.new(0, 1, 0)
|
||||
|
||||
local function set_quarry_formspec(meta)
|
||||
local radius = meta:get_int("size")
|
||||
|
@ -83,7 +84,7 @@ local function quarry_handle_purge(pos)
|
|||
if stack then
|
||||
local item = stack:to_table()
|
||||
if item then
|
||||
technic.tube_inject_item(pos, pos, vector.new(0, 1, 0), item)
|
||||
technic.tube_inject_item(pos, pos, quarry_eject_dir, item)
|
||||
stack:clear()
|
||||
inv:set_stack("cache", i, stack)
|
||||
break
|
||||
|
@ -217,6 +218,16 @@ minetest.register_node("technic:quarry", {
|
|||
connect_sides = {"bottom", "front", "left", "right"},
|
||||
tube = {
|
||||
connect_sides = {top = 1},
|
||||
-- lower priority than other tubes, so that quarries will prefer any
|
||||
-- other tube to another quarry, which could lead to server freezes
|
||||
-- in certain quarry placements (2x2 for example would never eject)
|
||||
priority = 10,
|
||||
can_go = function(pos, node, velocity, stack)
|
||||
-- always eject the same, even if items came in another way
|
||||
-- this further mitigates loops and generally avoids random sideway movement
|
||||
-- that can be expected in certain quarry placements
|
||||
return { quarry_eject_dir }
|
||||
end
|
||||
},
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
|
|
|
@ -17,19 +17,21 @@ minetest.register_craft({
|
|||
|
||||
local function check_node_around_mill(pos)
|
||||
local node = minetest.get_node(pos)
|
||||
if node.name == "default:water_flowing" or
|
||||
node.name == "default:water_source" then
|
||||
return true
|
||||
if node.name == "default:water_flowing"
|
||||
or node.name == "default:river_water_flowing" then
|
||||
return node.param2 -- returns approx. water flow, if any
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local run = function(pos, node)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local water_nodes = 0
|
||||
local water_flow = 0
|
||||
local lava_nodes = 0
|
||||
local production_level = 0
|
||||
local eu_supply = 0
|
||||
local max_output = 35 * 45 -- four param2's at 15 makes 60, cap it lower for "overload protection"
|
||||
-- (plus we want the gen to report 100% if three sides have full flow)
|
||||
|
||||
local positions = {
|
||||
{x=pos.x+1, y=pos.y, z=pos.z},
|
||||
|
@ -41,12 +43,12 @@ local run = function(pos, node)
|
|||
for _, p in pairs(positions) do
|
||||
local check = check_node_around_mill(p)
|
||||
if check then
|
||||
water_nodes = water_nodes + 1
|
||||
water_flow = water_flow + check
|
||||
end
|
||||
end
|
||||
|
||||
production_level = 25 * water_nodes
|
||||
eu_supply = 30 * water_nodes
|
||||
eu_supply = math.min(35 * water_flow, max_output)
|
||||
production_level = math.floor(100 * eu_supply / max_output)
|
||||
|
||||
if production_level > 0 then
|
||||
meta:set_int("LV_EU_supply", eu_supply)
|
||||
|
|
|
@ -8,6 +8,7 @@ dofile(path.."/MV/init.lua")
|
|||
dofile(path.."/HV/init.lua")
|
||||
|
||||
dofile(path.."/switching_station.lua")
|
||||
dofile(path.."/power_monitor.lua")
|
||||
dofile(path.."/supply_converter.lua")
|
||||
|
||||
dofile(path.."/other/init.lua")
|
||||
|
|
|
@ -21,7 +21,7 @@ local function deploy_node(inv, slot_name, pos, node, machine_node)
|
|||
end
|
||||
if remove_to then
|
||||
for i = 1, remove_to do
|
||||
inv:remove_item(drops[i])
|
||||
inv:remove_item(slot_name, drops[i])
|
||||
end
|
||||
else
|
||||
minetest.remove_node(pos)
|
||||
|
|
67
technic/machines/power_monitor.lua
Normal file
|
@ -0,0 +1,67 @@
|
|||
-- POWER MONITOR
|
||||
-- The power monitor can be used to monitor how much power is available on a network,
|
||||
-- similarly to the old "slave" switching stations.
|
||||
|
||||
local S = technic.getter
|
||||
|
||||
minetest.register_craft({
|
||||
output = "technic:power_monitor",
|
||||
recipe = {
|
||||
{"", "", ""},
|
||||
{"", "technic:machine_casing", "default:copper_ingot"},
|
||||
{"technic:lv_cable", "technic:lv_cable", "technic:lv_cable"}
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_node("technic:power_monitor",{
|
||||
description = S("Power Monitor"),
|
||||
tiles = {
|
||||
"technic_power_monitor_sides.png",
|
||||
"technic_power_monitor_bottom_back.png",
|
||||
"technic_power_monitor_sides.png",
|
||||
"technic_power_monitor_sides.png",
|
||||
"technic_power_monitor_bottom_back.png",
|
||||
"technic_power_monitor_front.png"
|
||||
},
|
||||
paramtype2 = "facedir",
|
||||
groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2, technic_all_tiers=1, technic_machine=1},
|
||||
connect_sides = {"bottom", "back"},
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string("infotext", S("Power Monitor"))
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_abm({
|
||||
nodenames = {"technic:power_monitor"},
|
||||
label = "Power Monitor",
|
||||
interval = 1,
|
||||
chance = 1,
|
||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local network_hash = technic.cables[minetest.hash_node_position(pos)]
|
||||
local network = network_hash and minetest.get_position_from_hash(network_hash)
|
||||
local sw_pos = network and {x=network.x,y=network.y+1,z=network.z}
|
||||
local timeout = 0
|
||||
for tier in pairs(technic.machines) do
|
||||
timeout = math.max(meta:get_int(tier.."_EU_timeout"),timeout)
|
||||
end
|
||||
if timeout > 0 and sw_pos and minetest.get_node(sw_pos).name == "technic:switching_station" then
|
||||
local sw_meta = minetest.get_meta(sw_pos)
|
||||
local supply = sw_meta:get_int("supply")
|
||||
local demand = sw_meta:get_int("demand")
|
||||
meta:set_string("infotext",
|
||||
S("Power Monitor. Supply: @1 Demand: @2",
|
||||
technic.pretty_num(supply), technic.pretty_num(demand)))
|
||||
else
|
||||
meta:set_string("infotext",S("Power Monitor Has No Network"))
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
for tier in pairs(technic.machines) do
|
||||
-- RE in order to use the "timeout" functions, although it consumes 0 power
|
||||
technic.register_machine(tier, "technic:power_monitor", "RE")
|
||||
end
|
||||
|
|
@ -11,8 +11,110 @@ function technic.get_cable_tier(name)
|
|||
return cable_tier[name]
|
||||
end
|
||||
|
||||
local function clear_networks()
|
||||
technic.networks = {}
|
||||
local function check_connections(pos)
|
||||
-- Build a table of all machines
|
||||
local machines = {}
|
||||
for tier,list in pairs(technic.machines) do
|
||||
for k,v in pairs(list) do
|
||||
machines[k] = v
|
||||
end
|
||||
end
|
||||
local connections = {}
|
||||
local positions = {
|
||||
{x=pos.x+1, y=pos.y, z=pos.z},
|
||||
{x=pos.x-1, y=pos.y, z=pos.z},
|
||||
{x=pos.x, y=pos.y+1, z=pos.z},
|
||||
{x=pos.x, y=pos.y-1, z=pos.z},
|
||||
{x=pos.x, y=pos.y, z=pos.z+1},
|
||||
{x=pos.x, y=pos.y, z=pos.z-1}}
|
||||
for _,connected_pos in pairs(positions) do
|
||||
local name = minetest.get_node(connected_pos).name
|
||||
if machines[name] or technic.get_cable_tier(name) then
|
||||
table.insert(connections,connected_pos)
|
||||
end
|
||||
end
|
||||
return connections
|
||||
end
|
||||
|
||||
local function clear_networks(pos)
|
||||
local node = minetest.get_node(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local placed = node.name ~= "air"
|
||||
local positions = check_connections(pos)
|
||||
if #positions < 1 then return end
|
||||
local dead_end = #positions == 1
|
||||
for _,connected_pos in pairs(positions) do
|
||||
local net = technic.cables[minetest.hash_node_position(connected_pos)]
|
||||
if net and technic.networks[net] then
|
||||
if dead_end and placed then
|
||||
-- Dead end placed, add it to the network
|
||||
-- Get the network
|
||||
local network_id = technic.cables[minetest.hash_node_position(positions[1])]
|
||||
if not network_id then
|
||||
-- We're evidently not on a network, nothing to add ourselves to
|
||||
return
|
||||
end
|
||||
local sw_pos = minetest.get_position_from_hash(network_id)
|
||||
sw_pos.y = sw_pos.y + 1
|
||||
local network = technic.networks[network_id]
|
||||
local tier = network.tier
|
||||
|
||||
-- Actually add it to the (cached) network
|
||||
-- This is similar to check_node_subp
|
||||
technic.cables[minetest.hash_node_position(pos)] = network_id
|
||||
pos.visited = 1
|
||||
if technic.is_tier_cable(name, tier) then
|
||||
table.insert(network.all_nodes,pos)
|
||||
elseif technic.machines[tier][node.name] then
|
||||
meta:set_string(tier.."_network",minetest.pos_to_string(sw_pos))
|
||||
if technic.machines[tier][node.name] == technic.producer then
|
||||
table.insert(network.PR_nodes,pos)
|
||||
elseif technic.machines[tier][node.name] == technic.receiver then
|
||||
table.insert(network.RE_nodes,pos)
|
||||
elseif technic.machines[tier][node.name] == technic.producer_receiver then
|
||||
table.insert(network.PR_nodes,pos)
|
||||
table.insert(network.RE_nodes,pos)
|
||||
elseif technic.machines[tier][node.name] == "SPECIAL" and
|
||||
(pos.x ~= sw_pos.x or pos.y ~= sw_pos.y or pos.z ~= sw_pos.z) and
|
||||
from_below then
|
||||
table.insert(network.SP_nodes,pos)
|
||||
elseif technic.machines[tier][node.name] == technic.battery then
|
||||
table.insert(network.BA_nodes,pos)
|
||||
end
|
||||
end
|
||||
elseif dead_end and not placed then
|
||||
-- Dead end removed, remove it from the network
|
||||
-- Get the network
|
||||
local network_id = technic.cables[minetest.hash_node_position(positions[1])]
|
||||
if not network_id then
|
||||
-- We're evidently not on a network, nothing to add ourselves to
|
||||
return
|
||||
end
|
||||
local network = technic.networks[network_id]
|
||||
|
||||
-- Search for and remove machine
|
||||
technic.cables[minetest.hash_node_position(pos)] = nil
|
||||
for tblname,table in pairs(network) do
|
||||
if tblname ~= "tier" then
|
||||
for machinenum,machine in pairs(table) do
|
||||
if machine.x == pos.x
|
||||
and machine.y == pos.y
|
||||
and machine.z == pos.z then
|
||||
table[machinenum] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
-- Not a dead end, so the whole network needs to be recalculated
|
||||
for _,v in pairs(technic.networks[net].all_nodes) do
|
||||
local pos1 = minetest.hash_node_position(v)
|
||||
technic.cables[pos1] = nil
|
||||
end
|
||||
technic.networks[net] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function technic.register_cable(tier, size)
|
||||
|
@ -55,7 +157,7 @@ end
|
|||
local function clear_nets_if_machine(pos, node)
|
||||
for tier, machine_list in pairs(technic.machines) do
|
||||
if machine_list[node.name] ~= nil then
|
||||
return clear_networks()
|
||||
return clear_networks(pos)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -14,6 +14,8 @@ local recipes = {
|
|||
{ "technic:bronze_dust 4", "technic:copper_dust 3", "technic:tin_dust" },
|
||||
{ "technic:stainless_steel_dust 4", "technic:wrought_iron_dust 3", "technic:chromium_dust" },
|
||||
{ "technic:brass_dust 3", "technic:copper_dust 2", "technic:zinc_dust" },
|
||||
{ "technic:chernobylite_dust", "default:sand", "technic:uranium3_dust" },
|
||||
{ "default:dirt 4", "default:sand", "default:gravel", "default:clay_lump 2" },
|
||||
}
|
||||
|
||||
local function uranium_dust(p)
|
||||
|
@ -34,5 +36,5 @@ if minetest.get_modpath("farming") then
|
|||
end
|
||||
|
||||
for _, data in pairs(recipes) do
|
||||
technic.register_separating_recipe({ input = { data[1] }, output = { data[2], data[3] } })
|
||||
technic.register_separating_recipe({ input = { data[1] }, output = { data[2], data[3], data[4] } })
|
||||
end
|
||||
|
|
|
@ -10,21 +10,22 @@ end
|
|||
|
||||
local recipes = {
|
||||
-- Dusts
|
||||
{"default:coal_lump", "technic:coal_dust 2"},
|
||||
{"default:copper_lump", "technic:copper_dust 2"},
|
||||
{"default:desert_stone", "default:desert_sand"},
|
||||
{"default:gold_lump", "technic:gold_dust 2"},
|
||||
{"default:iron_lump", "technic:wrought_iron_dust 2"},
|
||||
{"technic:chromium_lump", "technic:chromium_dust 2"},
|
||||
{"technic:uranium_lump", "technic:uranium_dust 2"},
|
||||
{"technic:zinc_lump", "technic:zinc_dust 2"},
|
||||
{"technic:lead_lump", "technic:lead_dust 2"},
|
||||
{"technic:sulfur_lump", "technic:sulfur_dust 2"},
|
||||
{"default:coal_lump", "technic:coal_dust 2"},
|
||||
{"default:copper_lump", "technic:copper_dust 2"},
|
||||
{"default:desert_stone", "default:desert_sand"},
|
||||
{"default:gold_lump", "technic:gold_dust 2"},
|
||||
{"default:iron_lump", "technic:wrought_iron_dust 2"},
|
||||
{"technic:chromium_lump", "technic:chromium_dust 2"},
|
||||
{"technic:uranium_lump", "technic:uranium_dust 2"},
|
||||
{"technic:zinc_lump", "technic:zinc_dust 2"},
|
||||
{"technic:lead_lump", "technic:lead_dust 2"},
|
||||
{"technic:sulfur_lump", "technic:sulfur_dust 2"},
|
||||
{"default:stone", "technic:stone_dust"},
|
||||
{"default:sand", "technic:stone_dust"},
|
||||
|
||||
-- Other
|
||||
{"default:cobble", "default:gravel"},
|
||||
{"default:gravel", "default:dirt"},
|
||||
{"default:stone", "default:sand"},
|
||||
{"default:gravel", "default:sand"},
|
||||
{"default:sandstone", "default:sand 2"}, -- reverse recipe can be found in the compressor
|
||||
}
|
||||
|
||||
|
@ -91,6 +92,7 @@ register_dust("Brass", "technic:brass_ingot")
|
|||
register_dust("Bronze", "default:bronze_ingot")
|
||||
register_dust("Carbon Steel", "technic:carbon_steel_ingot")
|
||||
register_dust("Cast Iron", "technic:cast_iron_ingot")
|
||||
register_dust("Chernobylite", "technic:chernobylite_block")
|
||||
register_dust("Chromium", "technic:chromium_ingot")
|
||||
register_dust("Coal", nil)
|
||||
register_dust("Copper", "default:copper_ingot")
|
||||
|
@ -99,6 +101,7 @@ register_dust("Gold", "default:gold_ingot")
|
|||
register_dust("Mithril", "moreores:mithril_ingot")
|
||||
register_dust("Silver", "moreores:silver_ingot")
|
||||
register_dust("Stainless Steel", "technic:stainless_steel_ingot")
|
||||
register_dust("Stone", "default:stone")
|
||||
register_dust("Sulfur", nil)
|
||||
register_dust("Tin", "moreores:tin_ingot")
|
||||
register_dust("Wrought Iron", "technic:wrought_iron_ingot")
|
||||
|
|
|
@ -9,12 +9,75 @@
|
|||
|
||||
local S = technic.getter
|
||||
|
||||
local run = function(pos, node)
|
||||
local demand = 10000
|
||||
local function set_supply_converter_formspec(meta)
|
||||
local formspec = "size[5,2.25]"..
|
||||
"field[0.3,0.5;2,1;power;"..S("Input Power")..";"..meta:get_int("power").."]"
|
||||
-- The names for these toggle buttons are explicit about which
|
||||
-- state they'll switch to, so that multiple presses (arising
|
||||
-- from the ambiguity between lag and a missed press) only make
|
||||
-- the single change that the user expects.
|
||||
if meta:get_int("mesecon_mode") == 0 then
|
||||
formspec = formspec.."button[0,1;5,1;mesecon_mode_1;"..S("Ignoring Mesecon Signal").."]"
|
||||
else
|
||||
formspec = formspec.."button[0,1;5,1;mesecon_mode_0;"..S("Controlled by Mesecon Signal").."]"
|
||||
end
|
||||
if meta:get_int("enabled") == 0 then
|
||||
formspec = formspec.."button[0,1.75;5,1;enable;"..S("%s Disabled"):format(S("Supply Converter")).."]"
|
||||
else
|
||||
formspec = formspec.."button[0,1.75;5,1;disable;"..S("%s Enabled"):format(S("Supply Converter")).."]"
|
||||
end
|
||||
meta:set_string("formspec", formspec)
|
||||
end
|
||||
|
||||
local supply_converter_receive_fields = function(pos, formname, fields, sender)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local power = nil
|
||||
if fields.power then
|
||||
power = tonumber(fields.power) or 0
|
||||
power = 100 * math.floor(power / 100)
|
||||
power = math.max(power, 0)
|
||||
power = math.min(power, 10000)
|
||||
if power == meta:get_int("power") then power = nil end
|
||||
end
|
||||
if power then meta:set_int("power", power) end
|
||||
if fields.enable then meta:set_int("enabled", 1) end
|
||||
if fields.disable then meta:set_int("enabled", 0) end
|
||||
if fields.mesecon_mode_0 then meta:set_int("mesecon_mode", 0) end
|
||||
if fields.mesecon_mode_1 then meta:set_int("mesecon_mode", 1) end
|
||||
set_supply_converter_formspec(meta)
|
||||
end
|
||||
|
||||
local mesecons = {
|
||||
effector = {
|
||||
action_on = function(pos, node)
|
||||
minetest.get_meta(pos):set_int("mesecon_effect", 1)
|
||||
end,
|
||||
action_off = function(pos, node)
|
||||
minetest.get_meta(pos):set_int("mesecon_effect", 0)
|
||||
end
|
||||
}
|
||||
}
|
||||
|
||||
local run = function(pos, node, run_stage)
|
||||
-- run only in producer stage.
|
||||
if run_stage == technic.receiver then
|
||||
return
|
||||
end
|
||||
|
||||
local remain = 0.9
|
||||
-- Machine information
|
||||
local machine_name = S("Supply Converter")
|
||||
local meta = minetest.get_meta(pos)
|
||||
local enabled = meta:get_string("enabled")
|
||||
if enabled == "" then
|
||||
-- Backwards compatibility
|
||||
minetest.registered_nodes["technic:supply_converter"].on_construct(pos)
|
||||
enabled = true
|
||||
else
|
||||
enabled = enabled == "1"
|
||||
end
|
||||
enabled = enabled and (meta:get_int("mesecon_mode") == 0 or meta:get_int("mesecon_effect") ~= 0)
|
||||
local demand = enabled and meta:get_int("power") or 0
|
||||
|
||||
local pos_up = {x=pos.x, y=pos.y+1, z=pos.z}
|
||||
local pos_down = {x=pos.x, y=pos.y-1, z=pos.z}
|
||||
|
@ -53,12 +116,19 @@ minetest.register_node("technic:supply_converter", {
|
|||
technic_machine=1, technic_all_tiers=1},
|
||||
connect_sides = {"top", "bottom"},
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
on_receive_fields = supply_converter_receive_fields,
|
||||
on_construct = function(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string("infotext", S("Supply Converter"))
|
||||
meta:set_float("active", false)
|
||||
meta:set_int("power", 10000)
|
||||
meta:set_int("enabled", 1)
|
||||
meta:set_int("mesecon_mode", 0)
|
||||
meta:set_int("mesecon_effect", 0)
|
||||
set_supply_converter_formspec(meta)
|
||||
end,
|
||||
mesecons = mesecons,
|
||||
technic_run = run,
|
||||
technic_on_disable = run,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
-- This way the supplies are separated per network.
|
||||
|
||||
technic.networks = {}
|
||||
technic.cables = {}
|
||||
|
||||
local S = technic.getter
|
||||
|
||||
|
@ -57,6 +58,11 @@ minetest.register_node("technic:switching_station",{
|
|||
meta:set_string("infotext", S("Switching Station"))
|
||||
meta:set_string("active", 1)
|
||||
end,
|
||||
after_dig_node = function(pos)
|
||||
minetest.forceload_free_block(pos)
|
||||
pos.y = pos.y - 1
|
||||
minetest.forceload_free_block(pos)
|
||||
end,
|
||||
})
|
||||
|
||||
--------------------------------------------------
|
||||
|
@ -64,7 +70,8 @@ minetest.register_node("technic:switching_station",{
|
|||
--------------------------------------------------
|
||||
|
||||
-- Add a wire node to the LV/MV/HV network
|
||||
local add_new_cable_node = function(nodes, pos)
|
||||
local add_new_cable_node = function(nodes, pos, network_id)
|
||||
technic.cables[minetest.hash_node_position(pos)] = network_id
|
||||
-- Ignore if the node has already been added
|
||||
for i = 1, #nodes do
|
||||
if pos.x == nodes[i].x and
|
||||
|
@ -78,31 +85,31 @@ local add_new_cable_node = function(nodes, pos)
|
|||
end
|
||||
|
||||
-- Generic function to add found connected nodes to the right classification array
|
||||
local check_node_subp = function(PR_nodes, RE_nodes, BA_nodes, SP_nodes, all_nodes, pos, machines, tier, sw_pos, from_below)
|
||||
local check_node_subp = function(PR_nodes, RE_nodes, BA_nodes, SP_nodes, all_nodes, pos, machines, tier, sw_pos, from_below, network_id)
|
||||
technic.get_or_load_node(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local name = minetest.get_node(pos).name
|
||||
|
||||
if technic.is_tier_cable(name, tier) then
|
||||
add_new_cable_node(all_nodes, pos)
|
||||
add_new_cable_node(all_nodes, pos,network_id)
|
||||
elseif machines[name] then
|
||||
--dprint(name.." is a "..machines[name])
|
||||
meta:set_string(tier.."_network",minetest.pos_to_string(sw_pos))
|
||||
if machines[name] == technic.producer then
|
||||
add_new_cable_node(PR_nodes, pos)
|
||||
add_new_cable_node(PR_nodes, pos, network_id)
|
||||
elseif machines[name] == technic.receiver then
|
||||
add_new_cable_node(RE_nodes, pos)
|
||||
add_new_cable_node(RE_nodes, pos, network_id)
|
||||
elseif machines[name] == technic.producer_receiver then
|
||||
add_new_cable_node(PR_nodes, pos)
|
||||
add_new_cable_node(RE_nodes, pos)
|
||||
add_new_cable_node(PR_nodes, pos, network_id)
|
||||
add_new_cable_node(RE_nodes, pos, network_id)
|
||||
elseif machines[name] == "SPECIAL" and
|
||||
(pos.x ~= sw_pos.x or pos.y ~= sw_pos.y or pos.z ~= sw_pos.z) and
|
||||
from_below then
|
||||
-- Another switching station -> disable it
|
||||
add_new_cable_node(SP_nodes, pos)
|
||||
add_new_cable_node(SP_nodes, pos, network_id)
|
||||
meta:set_int("active", 0)
|
||||
meta:set_string("active_pos", minetest.serialize(sw_pos))
|
||||
elseif machines[name] == technic.battery then
|
||||
add_new_cable_node(BA_nodes, pos)
|
||||
add_new_cable_node(BA_nodes, pos, network_id)
|
||||
end
|
||||
|
||||
meta:set_int(tier.."_EU_timeout", 2) -- Touch node
|
||||
|
@ -110,7 +117,7 @@ local check_node_subp = function(PR_nodes, RE_nodes, BA_nodes, SP_nodes, all_nod
|
|||
end
|
||||
|
||||
-- Traverse a network given a list of machines and a cable type name
|
||||
local traverse_network = function(PR_nodes, RE_nodes, BA_nodes, SP_nodes, all_nodes, i, machines, tier, sw_pos)
|
||||
local traverse_network = function(PR_nodes, RE_nodes, BA_nodes, SP_nodes, all_nodes, i, machines, tier, sw_pos, network_id)
|
||||
local pos = all_nodes[i]
|
||||
local positions = {
|
||||
{x=pos.x+1, y=pos.y, z=pos.z},
|
||||
|
@ -121,7 +128,7 @@ local traverse_network = function(PR_nodes, RE_nodes, BA_nodes, SP_nodes, all_no
|
|||
{x=pos.x, y=pos.y, z=pos.z-1}}
|
||||
--print("ON")
|
||||
for i, cur_pos in pairs(positions) do
|
||||
check_node_subp(PR_nodes, RE_nodes, BA_nodes, SP_nodes, all_nodes, cur_pos, machines, tier, sw_pos, i == 3)
|
||||
check_node_subp(PR_nodes, RE_nodes, BA_nodes, SP_nodes, all_nodes, cur_pos, machines, tier, sw_pos, i == 3, network_id)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -153,11 +160,11 @@ local get_network = function(sw_pos, pos1, tier)
|
|||
local all_nodes = {pos1}
|
||||
repeat
|
||||
traverse_network(PR_nodes, RE_nodes, BA_nodes, SP_nodes, all_nodes,
|
||||
i, technic.machines[tier], tier, sw_pos)
|
||||
i, technic.machines[tier], tier, sw_pos, minetest.hash_node_position(pos1))
|
||||
i = i + 1
|
||||
until all_nodes[i] == nil
|
||||
technic.networks[minetest.hash_node_position(pos1)] = {tier = tier, PR_nodes = PR_nodes,
|
||||
RE_nodes = RE_nodes, BA_nodes = BA_nodes, SP_nodes = SP_nodes}
|
||||
RE_nodes = RE_nodes, BA_nodes = BA_nodes, SP_nodes = SP_nodes, all_nodes = all_nodes}
|
||||
return PR_nodes, BA_nodes, RE_nodes
|
||||
end
|
||||
|
||||
|
@ -184,31 +191,34 @@ minetest.register_abm({
|
|||
local RE_nodes
|
||||
local machine_name = S("Switching Station")
|
||||
|
||||
if meta:get_int("active") ~= 1 then
|
||||
meta:set_int("active", 1)
|
||||
local active_pos = minetest.deserialize(meta:get_string("active_pos"))
|
||||
if active_pos then
|
||||
local meta1 = minetest.get_meta(active_pos)
|
||||
meta:set_string("infotext", S("%s (Slave)"):format(meta1:get_string("infotext")))
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
-- Which kind of network are we on:
|
||||
pos1 = {x=pos.x, y=pos.y-1, z=pos.z}
|
||||
|
||||
--Disable if necessary
|
||||
if meta:get_int("active") ~= 1 then
|
||||
minetest.forceload_free_block(pos)
|
||||
minetest.forceload_free_block(pos1)
|
||||
meta:set_string("infotext",S("%s Already Present"):format(machine_name))
|
||||
return
|
||||
end
|
||||
|
||||
local name = minetest.get_node(pos1).name
|
||||
local tier = technic.get_cable_tier(name)
|
||||
if tier then
|
||||
-- Forceload switching station
|
||||
minetest.forceload_block(pos)
|
||||
minetest.forceload_block(pos1)
|
||||
PR_nodes, BA_nodes, RE_nodes = get_network(pos, pos1, tier)
|
||||
else
|
||||
--dprint("Not connected to a network")
|
||||
meta:set_string("infotext", S("%s Has No Network"):format(machine_name))
|
||||
minetest.forceload_free_block(pos)
|
||||
minetest.forceload_free_block(pos1)
|
||||
return
|
||||
end
|
||||
|
||||
-- Run all the nodes
|
||||
local function run_nodes(list)
|
||||
local function run_nodes(list, run_stage)
|
||||
for _, pos2 in ipairs(list) do
|
||||
technic.get_or_load_node(pos2)
|
||||
local node2 = minetest.get_node(pos2)
|
||||
|
@ -217,14 +227,14 @@ minetest.register_abm({
|
|||
nodedef = minetest.registered_nodes[node2.name]
|
||||
end
|
||||
if nodedef and nodedef.technic_run then
|
||||
nodedef.technic_run(pos2, node2)
|
||||
nodedef.technic_run(pos2, node2, run_stage)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
run_nodes(PR_nodes)
|
||||
run_nodes(RE_nodes)
|
||||
run_nodes(BA_nodes)
|
||||
run_nodes(PR_nodes, technic.producer)
|
||||
run_nodes(RE_nodes, technic.receiver)
|
||||
run_nodes(BA_nodes, technic.battery)
|
||||
|
||||
-- Strings for the meta data
|
||||
local eu_demand_str = tier.."_EU_demand"
|
||||
|
@ -291,6 +301,10 @@ minetest.register_abm({
|
|||
S("@1. Supply: @2 Demand: @3",
|
||||
machine_name, technic.pretty_num(PR_eu_supply), technic.pretty_num(RE_eu_demand)))
|
||||
|
||||
-- Data that will be used by the power monitor
|
||||
meta:set_int("supply",PR_eu_supply)
|
||||
meta:set_int("demand",RE_eu_demand)
|
||||
|
||||
-- If the PR supply is enough for the RE demand supply them all
|
||||
if PR_eu_supply >= RE_eu_demand then
|
||||
--dprint("PR_eu_supply"..PR_eu_supply.." >= RE_eu_demand"..RE_eu_demand)
|
||||
|
@ -352,6 +366,7 @@ minetest.register_abm({
|
|||
meta1 = minetest.get_meta(pos1)
|
||||
meta1:set_int(eu_input_str, 0)
|
||||
end
|
||||
|
||||
end,
|
||||
})
|
||||
|
||||
|
@ -374,6 +389,7 @@ minetest.register_abm({
|
|||
interval = 1,
|
||||
chance = 1,
|
||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
||||
local meta = minetest.get_meta(pos)
|
||||
for tier, machines in pairs(technic.machines) do
|
||||
if machines[node.name] and switching_station_timeout_count(pos, tier) then
|
||||
local nodedef = minetest.registered_nodes[node.name]
|
||||
|
@ -392,6 +408,23 @@ minetest.register_abm({
|
|||
end,
|
||||
})
|
||||
|
||||
--Re-enable disabled switching station if necessary, similar to the timeout above
|
||||
minetest.register_abm({
|
||||
nodenames = {"technic:switching_station"},
|
||||
interval = 1,
|
||||
chance = 1,
|
||||
action = function(pos, node, active_object_count, active_object_count_wider)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local pos1 = {x=pos.x,y=pos.y-1,z=pos.z}
|
||||
local tier = technic.get_cable_tier(minetest.get_node(pos1).name)
|
||||
if not tier then return end
|
||||
if switching_station_timeout_count(pos, tier) then
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_int("active",1)
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
for tier, machines in pairs(technic.machines) do
|
||||
-- SPECIAL will not be traversed
|
||||
technic.register_machine(tier, "technic:switching_station", "SPECIAL")
|
||||
|
|
488
technic/radiation.lua
Normal file
|
@ -0,0 +1,488 @@
|
|||
--[[
|
||||
Radioactivity
|
||||
|
||||
Radiation resistance represents the extent to which a material
|
||||
attenuates radiation passing through it; i.e., how good a radiation
|
||||
shield it is. This is identified per node type. For materials that
|
||||
exist in real life, the radiation resistance value that this system
|
||||
uses for a node type consisting of a solid cube of that material is the
|
||||
(approximate) number of halvings of ionising radiation that is achieved
|
||||
by a meter of the material in real life. This is approximately
|
||||
proportional to density, which provides a good way to estimate it.
|
||||
Homogeneous mixtures of materials have radiation resistance computed
|
||||
by a simple weighted mean. Note that the amount of attenuation that
|
||||
a material achieves in-game is not required to be (and is not) the
|
||||
same as the attenuation achieved in real life.
|
||||
|
||||
Radiation resistance for a node type may be specified in the node
|
||||
definition, under the key "radiation_resistance". As an interim
|
||||
measure, until node definitions widely include this, this code
|
||||
knows a bunch of values for particular node types in several mods,
|
||||
and values for groups of node types. The node definition takes
|
||||
precedence if it specifies a value. Nodes for which no value at
|
||||
all is known are taken to provide no radiation resistance at all;
|
||||
this is appropriate for the majority of node types. Only node types
|
||||
consisting of a fairly homogeneous mass of material should report
|
||||
non-zero radiation resistance; anything with non-uniform geometry
|
||||
or complex internal structure should show no radiation resistance.
|
||||
Fractional resistance values are permitted.
|
||||
--]]
|
||||
|
||||
local S = technic.getter
|
||||
|
||||
local rad_resistance_node = {
|
||||
["default:brick"] = 13,
|
||||
["default:bronzeblock"] = 45,
|
||||
["default:clay"] = 15,
|
||||
["default:coalblock"] = 9.6,
|
||||
["default:cobble"] = 15,
|
||||
["default:copperblock"] = 46,
|
||||
["default:desert_cobble"] = 15,
|
||||
["default:desert_sand"] = 10,
|
||||
["default:desert_stone"] = 17,
|
||||
["default:desert_stonebrick"] = 17,
|
||||
["default:diamondblock"] = 24,
|
||||
["default:dirt"] = 8.2,
|
||||
["default:dirt_with_grass"] = 8.2,
|
||||
["default:dirt_with_grass_footsteps"] = 8.2,
|
||||
["default:dirt_with_snow"] = 8.2,
|
||||
["default:glass"] = 17,
|
||||
["default:goldblock"] = 170,
|
||||
["default:gravel"] = 10,
|
||||
["default:ice"] = 5.6,
|
||||
["default:lava_flowing"] = 8.5,
|
||||
["default:lava_source"] = 17,
|
||||
["default:mese"] = 21,
|
||||
["default:mossycobble"] = 15,
|
||||
["pbj_pup:pbj_pup"] = 10000,
|
||||
["pbj_pup:pbj_pup_candies"] = 10000,
|
||||
["gloopblocks:rainbow_block"] = 5000,
|
||||
["default:nyancat"] = 10000,
|
||||
["default:nyancat_rainbow"] = 10000,
|
||||
["nyancat:nyancat"] = 10000,
|
||||
["nyancat:nyancat_rainbow"] = 10000,
|
||||
["default:obsidian"] = 18,
|
||||
["default:obsidian_glass"] = 18,
|
||||
["default:sand"] = 10,
|
||||
["default:sandstone"] = 15,
|
||||
["default:sandstonebrick"] = 15,
|
||||
["default:snowblock"] = 1.7,
|
||||
["default:steelblock"] = 40,
|
||||
["default:stone"] = 17,
|
||||
["default:stone_with_coal"] = 16,
|
||||
["default:stone_with_copper"] = 20,
|
||||
["default:stone_with_diamond"] = 18,
|
||||
["default:stone_with_gold"] = 34,
|
||||
["default:stone_with_iron"] = 20,
|
||||
["default:stone_with_mese"] = 17,
|
||||
["default:stonebrick"] = 17,
|
||||
["default:water_flowing"] = 2.8,
|
||||
["default:water_source"] = 5.6,
|
||||
["farming:desert_sand_soil"] = 10,
|
||||
["farming:desert_sand_soil_wet"] = 10,
|
||||
["farming:soil"] = 8.2,
|
||||
["farming:soil_wet"] = 8.2,
|
||||
["glooptest:akalin_crystal_glass"] = 21,
|
||||
["glooptest:akalinblock"] = 40,
|
||||
["glooptest:alatro_crystal_glass"] = 21,
|
||||
["glooptest:alatroblock"] = 40,
|
||||
["glooptest:amethystblock"] = 18,
|
||||
["glooptest:arol_crystal_glass"] = 21,
|
||||
["glooptest:crystal_glass"] = 21,
|
||||
["glooptest:emeraldblock"] = 19,
|
||||
["glooptest:heavy_crystal_glass"] = 21,
|
||||
["glooptest:mineral_akalin"] = 20,
|
||||
["glooptest:mineral_alatro"] = 20,
|
||||
["glooptest:mineral_amethyst"] = 17,
|
||||
["glooptest:mineral_arol"] = 20,
|
||||
["glooptest:mineral_desert_coal"] = 16,
|
||||
["glooptest:mineral_desert_iron"] = 20,
|
||||
["glooptest:mineral_emerald"] = 17,
|
||||
["glooptest:mineral_kalite"] = 20,
|
||||
["glooptest:mineral_ruby"] = 18,
|
||||
["glooptest:mineral_sapphire"] = 18,
|
||||
["glooptest:mineral_talinite"] = 20,
|
||||
["glooptest:mineral_topaz"] = 18,
|
||||
["glooptest:reinforced_crystal_glass"] = 21,
|
||||
["glooptest:rubyblock"] = 27,
|
||||
["glooptest:sapphireblock"] = 27,
|
||||
["glooptest:talinite_crystal_glass"] = 21,
|
||||
["glooptest:taliniteblock"] = 40,
|
||||
["glooptest:topazblock"] = 24,
|
||||
["mesecons_extrawires:mese_powered"] = 21,
|
||||
["moreblocks:cactus_brick"] = 13,
|
||||
["moreblocks:cactus_checker"] = 8.5,
|
||||
["moreblocks:circle_stone_bricks"] = 17,
|
||||
["moreblocks:clean_glass"] = 17,
|
||||
["moreblocks:coal_checker"] = 9.0,
|
||||
["moreblocks:coal_glass"] = 17,
|
||||
["moreblocks:coal_stone"] = 17,
|
||||
["moreblocks:coal_stone_bricks"] = 17,
|
||||
["moreblocks:glow_glass"] = 17,
|
||||
["moreblocks:grey_bricks"] = 15,
|
||||
["moreblocks:iron_checker"] = 11,
|
||||
["moreblocks:iron_glass"] = 17,
|
||||
["moreblocks:iron_stone"] = 17,
|
||||
["moreblocks:iron_stone_bricks"] = 17,
|
||||
["moreblocks:plankstone"] = 9.3,
|
||||
["moreblocks:split_stone_tile"] = 15,
|
||||
["moreblocks:split_stone_tile_alt"] = 15,
|
||||
["moreblocks:stone_tile"] = 15,
|
||||
["moreblocks:super_glow_glass"] = 17,
|
||||
["moreblocks:tar"] = 7.0,
|
||||
["moreblocks:wood_tile"] = 1.7,
|
||||
["moreblocks:wood_tile_center"] = 1.7,
|
||||
["moreblocks:wood_tile_down"] = 1.7,
|
||||
["moreblocks:wood_tile_flipped"] = 1.7,
|
||||
["moreblocks:wood_tile_full"] = 1.7,
|
||||
["moreblocks:wood_tile_left"] = 1.7,
|
||||
["moreblocks:wood_tile_right"] = 1.7,
|
||||
["moreblocks:wood_tile_up"] = 1.7,
|
||||
["moreores:mineral_mithril"] = 18,
|
||||
["moreores:mineral_silver"] = 21,
|
||||
["moreores:mineral_tin"] = 19,
|
||||
["moreores:mithril_block"] = 26,
|
||||
["moreores:silver_block"] = 53,
|
||||
["moreores:tin_block"] = 37,
|
||||
["snow:snow_brick"] = 2.8,
|
||||
["technic:brass_block"] = 43,
|
||||
["technic:carbon_steel_block"] = 40,
|
||||
["technic:cast_iron_block"] = 40,
|
||||
["technic:chernobylite_block"] = 40,
|
||||
["technic:chromium_block"] = 37,
|
||||
["technic:corium_flowing"] = 40,
|
||||
["technic:corium_source"] = 80,
|
||||
["technic:granite"] = 18,
|
||||
["technic:lead_block"] = 80,
|
||||
["technic:marble"] = 18,
|
||||
["technic:marble_bricks"] = 18,
|
||||
["technic:mineral_chromium"] = 19,
|
||||
["technic:mineral_uranium"] = 71,
|
||||
["technic:mineral_zinc"] = 19,
|
||||
["technic:stainless_steel_block"] = 40,
|
||||
["technic:zinc_block"] = 36,
|
||||
["tnt:tnt"] = 11,
|
||||
["tnt:tnt_burning"] = 11,
|
||||
}
|
||||
local rad_resistance_group = {
|
||||
concrete = 16,
|
||||
tree = 3.4,
|
||||
uranium_block = 500,
|
||||
wood = 1.7,
|
||||
}
|
||||
local cache_radiation_resistance = {}
|
||||
local function node_radiation_resistance(node_name)
|
||||
local resistance = cache_radiation_resistance[node_name]
|
||||
if resistance then
|
||||
return resistance
|
||||
end
|
||||
local def = minetest.registered_nodes[node_name]
|
||||
if not def then
|
||||
cache_radiation_resistance[node_name] = 0
|
||||
return 0
|
||||
end
|
||||
resistance = def.radiation_resistance or
|
||||
rad_resistance_node[node_name]
|
||||
if not resistance then
|
||||
resistance = 0
|
||||
for g, v in pairs(def.groups) do
|
||||
if v > 0 and rad_resistance_group[g] then
|
||||
resistance = resistance + rad_resistance_group[g]
|
||||
end
|
||||
end
|
||||
end
|
||||
resistance = math.sqrt(resistance)
|
||||
cache_radiation_resistance[node_name] = resistance
|
||||
return resistance
|
||||
end
|
||||
|
||||
|
||||
--[[
|
||||
Radioactive nodes cause damage to nearby players. The damage
|
||||
effect depends on the intrinsic strength of the radiation source,
|
||||
the distance between the source and the player, and the shielding
|
||||
effect of the intervening material. These determine a rate of damage;
|
||||
total damage caused is the integral of this over time.
|
||||
|
||||
In the absence of effective shielding, for a specific source the
|
||||
damage rate varies realistically in inverse proportion to the square
|
||||
of the distance. (Distance is measured to the player's abdomen,
|
||||
not to the nominal player position which corresponds to the foot.)
|
||||
However, if the player is inside a non-walkable (liquid or gaseous)
|
||||
radioactive node, the nominal distance could go to zero, yielding
|
||||
infinite damage. In that case, the player's body is displacing the
|
||||
radioactive material, so the effective distance should remain non-zero.
|
||||
We therefore apply a lower distance bound of sqrt(0.75), which is
|
||||
the maximum distance one can get from the node center within the node.
|
||||
|
||||
A radioactive node is identified by being in the "radioactive" group,
|
||||
and the group value signifies the strength of the radiation source.
|
||||
The group value is the distance from a node at which an unshielded
|
||||
player will be damaged by 1 HP/s. Or, equivalently, it is the square
|
||||
root of the damage rate in HP/s that an unshielded player one node
|
||||
away will take.
|
||||
|
||||
Shielding is assessed by adding the shielding values of all nodes
|
||||
between the source node and the player, ignoring the source node itself.
|
||||
As in reality, shielding causes exponential attenuation of radiation.
|
||||
However, the effect is scaled down relative to real life. A node with
|
||||
radiation resistance value R yields attenuation of sqrt(R) * 0.1 nepers.
|
||||
(In real life it would be about R * 0.69 nepers, by the definition
|
||||
of the radiation resistance values.) The sqrt part of this formula
|
||||
scales down the differences between shielding types, reflecting the
|
||||
game's simplification of making expensive materials such as gold
|
||||
readily available in cubes. The multiplicative factor in the
|
||||
formula scales down the difference between shielded and unshielded
|
||||
safe distances, avoiding the latter becoming impractically large.
|
||||
|
||||
Damage is processed at rates down to 0.2 HP/s, which in the absence of
|
||||
shielding is attained at the distance specified by the "radioactive"
|
||||
group value. Computed damage rates below 0.2 HP/s result in no
|
||||
damage at all to the player. This gives the player an opportunity
|
||||
to be safe, and limits the range at which source/player interactions
|
||||
need to be considered.
|
||||
--]]
|
||||
local abdomen_offset = 1
|
||||
local cache_scaled_shielding = {}
|
||||
local rad_dmg_cutoff = 0.2
|
||||
local radiated_players = {}
|
||||
|
||||
local armor_enabled = technic.config:get_bool("enable_radiation_protection")
|
||||
local entity_damage = technic.config:get_bool("enable_entity_radiation_damage")
|
||||
local longterm_damage = technic.config:get_bool("enable_longterm_radiation_damage")
|
||||
|
||||
local function apply_fractional_damage(o, dmg)
|
||||
local dmg_int = math.floor(dmg)
|
||||
-- The closer you are to getting one more damage point,
|
||||
-- the more likely it will be added.
|
||||
if math.random() < dmg - dmg_int then
|
||||
dmg_int = dmg_int + 1
|
||||
end
|
||||
if dmg_int > 0 then
|
||||
local new_hp = math.max(o:get_hp() - dmg_int, 0)
|
||||
o:set_hp(new_hp)
|
||||
return new_hp == 0
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function calculate_base_damage(node_pos, object_pos, strength)
|
||||
local shielding = 0
|
||||
local dist = vector.distance(node_pos, object_pos)
|
||||
|
||||
for ray_pos in technic.trace_node_ray(node_pos,
|
||||
vector.direction(node_pos, object_pos), dist) do
|
||||
local shield_name = minetest.get_node(ray_pos).name
|
||||
shielding = shielding + node_radiation_resistance(shield_name) * 0.025
|
||||
end
|
||||
|
||||
local dmg = (strength * strength) /
|
||||
(math.max(0.75, dist * dist) * math.exp(shielding))
|
||||
|
||||
if dmg < rad_dmg_cutoff then return end
|
||||
return dmg
|
||||
end
|
||||
|
||||
local function calculate_damage_multiplier(object)
|
||||
local ag = object.get_armor_groups and object:get_armor_groups()
|
||||
if not ag then
|
||||
return 0
|
||||
end
|
||||
if ag.immortal then
|
||||
return 0
|
||||
end
|
||||
if ag.radiation then
|
||||
return 0.01 * ag.radiation
|
||||
end
|
||||
if ag.fleshy then
|
||||
return math.sqrt(0.01 * ag.fleshy)
|
||||
end
|
||||
return 0
|
||||
end
|
||||
|
||||
local function calculate_object_center(object)
|
||||
if object:is_player() then
|
||||
return {x=0, y=abdomen_offset, z=0}
|
||||
end
|
||||
return {x=0, y=0, z=0}
|
||||
end
|
||||
|
||||
local function dmg_object(pos, object, strength)
|
||||
local obj_pos = vector.add(object:getpos(), calculate_object_center(object))
|
||||
local mul
|
||||
if armor_enabled or entity_damage then
|
||||
-- we need to check may the object be damaged even if armor is disabled
|
||||
mul = calculate_damage_multiplier(object)
|
||||
if mul == 0 then
|
||||
return
|
||||
end
|
||||
end
|
||||
local dmg = calculate_base_damage(pos, obj_pos, strength)
|
||||
if not dmg then
|
||||
return
|
||||
end
|
||||
if armor_enabled then
|
||||
dmg = dmg * mul
|
||||
end
|
||||
apply_fractional_damage(object, dmg)
|
||||
if longterm_damage and object:is_player() then
|
||||
local pn = object:get_player_name()
|
||||
radiated_players[pn] = (radiated_players[pn] or 0) + dmg
|
||||
end
|
||||
end
|
||||
|
||||
local rad_dmg_mult_sqrt = math.sqrt(1 / rad_dmg_cutoff)
|
||||
local function dmg_abm(pos, node)
|
||||
local strength = minetest.get_item_group(node.name, "radioactive")
|
||||
local max_dist = strength * rad_dmg_mult_sqrt
|
||||
for _, o in pairs(minetest.get_objects_inside_radius(pos,
|
||||
max_dist + abdomen_offset)) do
|
||||
if entity_damage or o:is_player() then
|
||||
dmg_object(pos, o, strength)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if minetest.setting_getbool("enable_damage") then
|
||||
minetest.register_abm({
|
||||
nodenames = {"group:radioactive"},
|
||||
interval = 1,
|
||||
chance = 1,
|
||||
action = dmg_abm,
|
||||
})
|
||||
|
||||
if longterm_damage then
|
||||
minetest.register_globalstep(function(dtime)
|
||||
for pn, dmg in pairs(radiated_players) do
|
||||
dmg = dmg - (dtime / 8)
|
||||
local player = minetest.get_player_by_name(pn)
|
||||
local killed
|
||||
if player and dmg > rad_dmg_cutoff then
|
||||
killed = apply_fractional_damage(player, (dmg * dtime) / 8)
|
||||
else
|
||||
dmg = nil
|
||||
end
|
||||
-- on_dieplayer will have already set this if the player died
|
||||
if not killed then
|
||||
radiated_players[pn] = dmg
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
minetest.register_on_dieplayer(function(player)
|
||||
radiated_players[player:get_player_name()] = nil
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
-- Radioactive materials that can result from destroying a reactor
|
||||
local griefing = technic.config:get_bool("enable_corium_griefing")
|
||||
|
||||
for _, state in pairs({"flowing", "source"}) do
|
||||
minetest.register_node("technic:corium_"..state, {
|
||||
description = S(state == "source" and "Corium Source" or "Flowing Corium"),
|
||||
drawtype = (state == "source" and "liquid" or "flowingliquid"),
|
||||
[state == "source" and "tiles" or "special_tiles"] = {{
|
||||
name = "technic_corium_"..state.."_animated.png",
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 16,
|
||||
aspect_h = 16,
|
||||
length = 3.0,
|
||||
},
|
||||
}},
|
||||
paramtype = "light",
|
||||
paramtype2 = (state == "flowing" and "flowingliquid" or nil),
|
||||
light_source = (state == "source" and 8 or 5),
|
||||
walkable = false,
|
||||
pointable = false,
|
||||
diggable = false,
|
||||
buildable_to = true,
|
||||
drop = "",
|
||||
drowning = 1,
|
||||
liquidtype = state,
|
||||
liquid_alternative_flowing = "technic:corium_flowing",
|
||||
liquid_alternative_source = "technic:corium_source",
|
||||
liquid_viscosity = LAVA_VISC,
|
||||
liquid_renewable = false,
|
||||
damage_per_second = 6,
|
||||
post_effect_color = {a=192, r=80, g=160, b=80},
|
||||
groups = {
|
||||
liquid = 2,
|
||||
hot = 3,
|
||||
igniter = (griefing and 1 or 0),
|
||||
radioactive = (state == "source" and 12 or 6),
|
||||
not_in_creative_inventory = (state == "flowing" and 1 or nil),
|
||||
},
|
||||
})
|
||||
end
|
||||
|
||||
if rawget(_G, "bucket") and bucket.register_liquid then
|
||||
bucket.register_liquid(
|
||||
"technic:corium_source",
|
||||
"technic:corium_flowing",
|
||||
"technic:bucket_corium",
|
||||
"technic_bucket_corium.png",
|
||||
"Corium Bucket"
|
||||
)
|
||||
end
|
||||
|
||||
minetest.register_node("technic:chernobylite_block", {
|
||||
description = S("Chernobylite Block"),
|
||||
tiles = {"technic_chernobylite_block.png"},
|
||||
is_ground_content = true,
|
||||
groups = {cracky=1, radioactive=4, level=2},
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
light_source = 2,
|
||||
})
|
||||
|
||||
minetest.register_abm({
|
||||
nodenames = {"group:water"},
|
||||
neighbors = {"technic:corium_source"},
|
||||
interval = 1,
|
||||
chance = 1,
|
||||
action = function(pos, node)
|
||||
minetest.remove_node(pos)
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_abm({
|
||||
nodenames = {"technic:corium_flowing"},
|
||||
neighbors = {"group:water"},
|
||||
interval = 1,
|
||||
chance = 1,
|
||||
action = function(pos, node)
|
||||
minetest.set_node(pos, {name="technic:chernobylite_block"})
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_abm({
|
||||
nodenames = {"technic:corium_flowing"},
|
||||
interval = 5,
|
||||
chance = (griefing and 10 or 1),
|
||||
action = function(pos, node)
|
||||
minetest.set_node(pos, {name="technic:chernobylite_block"})
|
||||
end,
|
||||
})
|
||||
|
||||
if griefing then
|
||||
minetest.register_abm({
|
||||
nodenames = {"technic:corium_source", "technic:corium_flowing"},
|
||||
interval = 4,
|
||||
chance = 4,
|
||||
action = function(pos, node)
|
||||
for _, offset in ipairs({
|
||||
vector.new(1,0,0),
|
||||
vector.new(-1,0,0),
|
||||
vector.new(0,0,1),
|
||||
vector.new(0,0,-1),
|
||||
vector.new(0,-1,0),
|
||||
}) do
|
||||
if math.random(8) == 1 then
|
||||
minetest.dig_node(vector.add(pos, offset))
|
||||
end
|
||||
end
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
BIN
technic/textures/technic_chernobylite_dust.png
Normal file
After Width: | Height: | Size: 436 B |
BIN
technic/textures/technic_power_monitor_bottom_back.png
Normal file
After Width: | Height: | Size: 506 B |
BIN
technic/textures/technic_power_monitor_front.png
Normal file
After Width: | Height: | Size: 428 B |
BIN
technic/textures/technic_power_monitor_sides.png
Normal file
After Width: | Height: | Size: 456 B |
BIN
technic/textures/technic_stone_dust.png
Normal file
After Width: | Height: | Size: 417 B |
BIN
technic/textures/technicx32/technic_chernobylite_dust.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
technic/textures/technicx32/technic_stone_dust.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
|
@ -71,12 +71,6 @@ local function drill_dig_it1 (player)
|
|||
end
|
||||
|
||||
local function drill_dig_it2 (pos,player)
|
||||
drill_dig_it0 (pos,player)
|
||||
pos.z=pos.z+1
|
||||
drill_dig_it0 (pos,player)
|
||||
pos.z=pos.z-2
|
||||
drill_dig_it0 (pos,player)
|
||||
pos.z=pos.z+1
|
||||
pos.y=pos.y+1
|
||||
drill_dig_it0 (pos,player)
|
||||
pos.z=pos.z+1
|
||||
|
@ -84,7 +78,14 @@ local function drill_dig_it2 (pos,player)
|
|||
pos.z=pos.z-2
|
||||
drill_dig_it0 (pos,player)
|
||||
pos.z=pos.z+1
|
||||
pos.y=pos.y-2
|
||||
pos.y=pos.y-1
|
||||
drill_dig_it0 (pos,player)
|
||||
pos.z=pos.z+1
|
||||
drill_dig_it0 (pos,player)
|
||||
pos.z=pos.z-2
|
||||
drill_dig_it0 (pos,player)
|
||||
pos.z=pos.z+1
|
||||
pos.y=pos.y-1
|
||||
drill_dig_it0 (pos,player)
|
||||
pos.z=pos.z+1
|
||||
drill_dig_it0 (pos,player)
|
||||
|
@ -93,12 +94,6 @@ local function drill_dig_it2 (pos,player)
|
|||
end
|
||||
|
||||
local function drill_dig_it3 (pos,player)
|
||||
drill_dig_it0 (pos,player)
|
||||
pos.x=pos.x+1
|
||||
drill_dig_it0 (pos,player)
|
||||
pos.x=pos.x-2
|
||||
drill_dig_it0 (pos,player)
|
||||
pos.x=pos.x+1
|
||||
pos.y=pos.y+1
|
||||
drill_dig_it0 (pos,player)
|
||||
pos.x=pos.x+1
|
||||
|
@ -106,7 +101,14 @@ local function drill_dig_it3 (pos,player)
|
|||
pos.x=pos.x-2
|
||||
drill_dig_it0 (pos,player)
|
||||
pos.x=pos.x+1
|
||||
pos.y=pos.y-2
|
||||
pos.y=pos.y-1
|
||||
drill_dig_it0 (pos,player)
|
||||
pos.x=pos.x+1
|
||||
drill_dig_it0 (pos,player)
|
||||
pos.x=pos.x-2
|
||||
drill_dig_it0 (pos,player)
|
||||
pos.x=pos.x+1
|
||||
pos.y=pos.y-1
|
||||
drill_dig_it0 (pos,player)
|
||||
pos.x=pos.x+1
|
||||
drill_dig_it0 (pos,player)
|
||||
|
@ -252,10 +254,9 @@ local function mining_drill_mk2_setmode(user,itemstack)
|
|||
mode=mode+1
|
||||
if mode>=5 then mode=1 end
|
||||
minetest.chat_send_player(player_name, S("Mining Drill Mk%d Mode %d"):format(2, mode)..": "..mining_drill_mode_text[mode][1])
|
||||
item["name"]="technic:mining_drill_mk2_"..mode
|
||||
itemstack:set_name("technic:mining_drill_mk2_"..mode);
|
||||
meta["mode"]=mode
|
||||
item["metadata"]=minetest.serialize(meta)
|
||||
itemstack:replace(item)
|
||||
itemstack:set_metadata(minetest.serialize(meta))
|
||||
return itemstack
|
||||
end
|
||||
|
||||
|
@ -276,10 +277,9 @@ local function mining_drill_mk3_setmode(user,itemstack)
|
|||
mode=mode+1
|
||||
if mode>=6 then mode=1 end
|
||||
minetest.chat_send_player(player_name, S("Mining Drill Mk%d Mode %d"):format(3, mode)..": "..mining_drill_mode_text[mode][1])
|
||||
item["name"]="technic:mining_drill_mk3_"..mode
|
||||
itemstack:set_name("technic:mining_drill_mk3_"..mode);
|
||||
meta["mode"]=mode
|
||||
item["metadata"]=minetest.serialize(meta)
|
||||
itemstack:replace(item)
|
||||
itemstack:set_metadata(minetest.serialize(meta))
|
||||
return itemstack
|
||||
end
|
||||
|
||||
|
@ -296,7 +296,7 @@ local function mining_drill_mk2_handler(itemstack, user, pointed_thing)
|
|||
end
|
||||
local charge_to_take = cost_to_use(2, meta.mode)
|
||||
if meta.charge >= charge_to_take then
|
||||
local pos = minetest.get_pointed_thing_position(pointed_thing, above)
|
||||
local pos = minetest.get_pointed_thing_position(pointed_thing, false)
|
||||
drill_dig_it(pos, user, meta.mode)
|
||||
if not technic.creative_mode then
|
||||
meta.charge = meta.charge - charge_to_take
|
||||
|
@ -319,7 +319,7 @@ local function mining_drill_mk3_handler(itemstack, user, pointed_thing)
|
|||
end
|
||||
local charge_to_take = cost_to_use(3, meta.mode)
|
||||
if meta.charge >= charge_to_take then
|
||||
local pos = minetest.get_pointed_thing_position(pointed_thing, above)
|
||||
local pos = minetest.get_pointed_thing_position(pointed_thing, false)
|
||||
drill_dig_it(pos, user, meta.mode)
|
||||
if not technic.creative_mode then
|
||||
meta.charge = meta.charge - charge_to_take
|
||||
|
@ -348,7 +348,7 @@ minetest.register_tool("technic:mining_drill", {
|
|||
end
|
||||
local charge_to_take = cost_to_use(1, 1)
|
||||
if meta.charge >= charge_to_take then
|
||||
local pos = minetest.get_pointed_thing_position(pointed_thing, above)
|
||||
local pos = minetest.get_pointed_thing_position(pointed_thing, false)
|
||||
drill_dig_it(pos, user, 1)
|
||||
if not technic.creative_mode then
|
||||
meta.charge = meta.charge - charge_to_take
|
||||
|
|
|
@ -26,12 +26,7 @@ technic.chests.can_dig = function(pos, player)
|
|||
end
|
||||
|
||||
local function inv_change(pos, count, player)
|
||||
local meta = minetest.get_meta(pos)
|
||||
if not has_locked_chest_privilege(meta, player) then
|
||||
minetest.log("action", player:get_player_name()..
|
||||
" tried to access a locked chest belonging to "..
|
||||
meta:get_string("owner").." at "..
|
||||
minetest.pos_to_string(pos))
|
||||
if not default.can_interact_with_node(player, pos) then
|
||||
return 0
|
||||
end
|
||||
return count
|
||||
|
@ -54,18 +49,14 @@ function technic.chests.on_inv_move(pos, from_list, from_index, to_list, to_inde
|
|||
end
|
||||
|
||||
function technic.chests.on_inv_put(pos, listname, index, stack, player)
|
||||
minetest.log("action", player:get_player_name()..
|
||||
" puts stuff in to chest at "
|
||||
..minetest.pos_to_string(pos))
|
||||
minetest.log("action", player:get_player_name() ..
|
||||
" moves " .. stack:get_name() ..
|
||||
" to chest at " .. minetest.pos_to_string(pos))
|
||||
end
|
||||
|
||||
function technic.chests.on_inv_take(pos, listname, index, stack, player)
|
||||
minetest.log("action", player:get_player_name()..
|
||||
" takes stuff from chest at "
|
||||
..minetest.pos_to_string(pos))
|
||||
end
|
||||
|
||||
function has_locked_chest_privilege(meta, player)
|
||||
return player:get_player_name() == meta:get_string("owner")
|
||||
minetest.log("action", player:get_player_name() ..
|
||||
" takes " .. stack:get_name() ..
|
||||
" from chest at " .. minetest.pos_to_string(pos))
|
||||
end
|
||||
|
||||
|
|
|
@ -264,11 +264,44 @@ function technic.chests:definition(name, data)
|
|||
on_metadata_inventory_move = self.on_inv_move,
|
||||
on_metadata_inventory_put = self.on_inv_put,
|
||||
on_metadata_inventory_take = self.on_inv_take,
|
||||
on_blast = function(pos)
|
||||
local drops = {}
|
||||
default.get_inventory_drops(pos, "main", drops)
|
||||
drops[#drops+1] = "technic:"..name:lower()..(data.locked and "_locked" or "").."_chest"
|
||||
minetest.remove_node(pos)
|
||||
return drops
|
||||
end,
|
||||
}
|
||||
if data.locked then
|
||||
def.allow_metadata_inventory_move = self.inv_move
|
||||
def.allow_metadata_inventory_put = self.inv_put
|
||||
def.allow_metadata_inventory_take = self.inv_take
|
||||
def.on_blast = function() end
|
||||
def.can_dig = function(pos,player)
|
||||
local meta = minetest.get_meta(pos);
|
||||
local inv = meta:get_inventory()
|
||||
return inv:is_empty("main") and default.can_interact_with_node(player, pos)
|
||||
end
|
||||
def.on_skeleton_key_use = function(pos, player, newsecret)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local owner = meta:get_string("owner")
|
||||
local name = player:get_player_name()
|
||||
|
||||
-- verify placer is owner of lockable chest
|
||||
if owner ~= name then
|
||||
minetest.record_protection_violation(pos, name)
|
||||
minetest.chat_send_player(name, "You do not own this chest.")
|
||||
return nil
|
||||
end
|
||||
|
||||
local secret = meta:get_string("key_lock_secret")
|
||||
if secret == "" then
|
||||
secret = newsecret
|
||||
meta:set_string("key_lock_secret", secret)
|
||||
end
|
||||
|
||||
return secret, "a locked chest", owner
|
||||
end
|
||||
end
|
||||
return def
|
||||
end
|
||||
|
|
|
@ -5,7 +5,7 @@ minetest.register_node( ":technic:mineral_uranium", {
|
|||
description = S("Uranium Ore"),
|
||||
tiles = { "default_stone.png^technic_mineral_uranium.png" },
|
||||
is_ground_content = true,
|
||||
groups = {cracky=3, radioactive=1000},
|
||||
groups = {cracky=3, radioactive=1},
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
drop = "technic:uranium_lump",
|
||||
})
|
||||
|
@ -74,7 +74,7 @@ minetest.register_node(":technic:uranium_block", {
|
|||
description = S("Uranium Block"),
|
||||
tiles = { "technic_uranium_block.png" },
|
||||
is_ground_content = true,
|
||||
groups = {uranium_block=1, cracky=1, level=2, radioactive=3000},
|
||||
groups = {uranium_block=1, cracky=1, level=2, radioactive=2},
|
||||
sounds = default.node_sound_stone_defaults()
|
||||
})
|
||||
|
||||
|
|
|
@ -54,13 +54,13 @@ minetest.register_ore({
|
|||
ore_type = "scatter",
|
||||
ore = "technic:mineral_zinc",
|
||||
wherein = "default:stone",
|
||||
clust_scarcity = 8*8*8,
|
||||
clust_num_ores = 4,
|
||||
clust_size = 3,
|
||||
clust_scarcity = 9*9*9,
|
||||
clust_num_ores = 5,
|
||||
clust_size = 7,
|
||||
y_min = -32,
|
||||
y_max = 2,
|
||||
noise_params = zinc_params,
|
||||
noise_threshold = zinc_threshhold,
|
||||
noise_params = lead_params,
|
||||
noise_threshhold = lead_threshhold,
|
||||
})
|
||||
|
||||
minetest.register_ore({
|
||||
|
|