Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Radiation API #651

Open
wants to merge 19 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions technic/doc/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,14 @@ Unsorted functions:
* Some configuration function
* `technic.tube_inject_item(pos, start_pos, velocity, item)`
* Same as `pipeworks.tube_inject_item`
* `technic.register_rad_resistance(node_name, resistance)`
* Sets the radiation resistance of the given node.
* `node_name`: name of the node
* `resistance`: number, radiation resistance of the node
* `technic.register_group_resistance(group_name, resistance)`
* Sets the radiation resistance of the given group of nodes.
* `group_name`: name of the group
* `resistance`: number, radiation resistance of the group

### Energy modifiers
* `technic.set_RE_wear(itemstack, item_load, max_charge)`
Expand Down Expand Up @@ -193,6 +201,12 @@ Groups:
* UNRELIABLE. Indicates whether the item or node belongs to technic
* `connect_sides = {"top", "left", ...}`
* Extends the Minetest API. Indicates where the machine can be connected.
* `radioactive = <radiation>`
* Makes the node radioactive.
* `<radiation>`: Strength of the node's radiation (ex. `2`).
* `rad_resistance = <resistance>`
* Makes the node resistant to radiation.
* `<resistance>`: Strength of the node's resistance (ex. `80`).

Additional definition fields:

Expand Down
83 changes: 43 additions & 40 deletions technic/radiation.lua
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,20 @@ or complex internal structure should show no radiation resistance.
Fractional resistance values are permitted.
--]]

-- Function to register node-specific resistance
function technic.register_rad_resistance(node_name, resistance)
SmallJoker marked this conversation as resolved.
Show resolved Hide resolved
local node = minetest.registered_nodes[node_name]
if node then
if not node.groups then
node.groups = {}
end
node.groups.rad_resistance = resistance
end
end
DustyDave961 marked this conversation as resolved.
Show resolved Hide resolved

local S = technic.getter

local rad_resistance_node = {
local node_resistances = {
["default:brick"] = 13,
["default:bronzeblock"] = 45,
["default:clay"] = 15,
Expand Down Expand Up @@ -147,57 +158,49 @@ local rad_resistance_node = {
["moreores:silver_block"] = 53,
["snow:snow_brick"] = 2.8,
["basic_materials: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

-- Register all node resistances at once
for node_name, resistance in pairs(node_resistances) do
technic.register_rad_resistance(node_name, resistance)
end

-- Function to register group-specific resistance
function technic.register_group_resistance(group_name, resistance)
for node_name, node_def in pairs(minetest.registered_nodes) do
if node_def.groups[group_name] then
if not node_def.groups.rad_resistance then
node_def.groups.rad_resistance = resistance
end
end
end
end

technic.register_group_resistance("concrete", 16)
technic.register_group_resistance("tree", 3.4)
technic.register_group_resistance("uranium_block", 500)
technic.register_group_resistance("wood", 1.7)
Comment on lines +183 to +186
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately this only works on nodes that are already registered when technic is loaded.
A few ideas to fix that:

  1. re-add the previous cache_radiation_resistance to lazily calculate the node value when needed
  2. calculate all values either in core.register_on_mods_loaded or in a core.after(0, function() ??? end) callback (first server step)

Copy link
Author

@DustyDave961 DustyDave961 Oct 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found such functions in the Minetest lua api, but I'm unsure how to use the minetest.register_on_mods_loaded(function()) function. Do I just replace "function" with node_radiation_resistance, or is there more to it? I'm still quite new to all this.

Edit: @DustyBagel has informed me that function is not backwards compatible with certain versions of Minetest. I don't think it's a big deal, but should we consider the minetest.after function instead?

Copy link
Member

@SmallJoker SmallJoker Oct 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

core.register_on_mods_loaded (core == minetest) is run after all mods are loaded. You can still use core.override_item if needed.

Here's what I would do: loop through core.registered_nodes and cache the resistance values (where it is present). Afterwards, node_radiation_resistance() could always retrieve the value (or 0) from the cache without any additional computations. That's computationally more expensive on startup, but has the lowest memory footprint in the long-run and more predictable code execution time.


Changelog 0.4.16 → 5.0.0 mentions this callback. Minetest 5.0.0 is already the minimal requirement for technic, thus this is not of a concern.

If functions are not mentioned in the changelog, you might as well have a look at the git blame of the lua_api.md line, which reveals when it was added.


-- Function to calculate radiation resistance
local function node_radiation_resistance(node_name)
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

local resistance = 0
-- Add rad_resistance group value if it exists
if def.groups.rad_resistance then
resistance = resistance + def.groups.rad_resistance
end
resistance = math.sqrt(resistance)
cache_radiation_resistance[node_name] = resistance
return resistance

return math.sqrt(resistance)
end


--[[
Radioactive nodes cause damage to nearby players. The damage
effect depends on the intrinsic strength of the radiation source,
Expand Down Expand Up @@ -456,7 +459,7 @@ 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},
groups = {cracky=1, radioactive=4, level=2, rad_resistance=40},
sounds = default.node_sound_stone_defaults(),
light_source = 2,
})
Expand Down
26 changes: 13 additions & 13 deletions technic_worldgen/nodes.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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=1},
groups = {cracky=3, radioactive=1, rad_resistance=71},
sounds = default.node_sound_stone_defaults(),
drop = "technic:uranium_lump",
})
Expand All @@ -14,7 +14,7 @@ minetest.register_node( ":technic:mineral_chromium", {
description = S("Chromium Ore"),
tiles = { "default_stone.png^technic_mineral_chromium.png" },
is_ground_content = true,
groups = {cracky=3},
groups = {cracky=3, rad_resistance=19},
sounds = default.node_sound_stone_defaults(),
drop = "technic:chromium_lump",
})
Expand All @@ -23,7 +23,7 @@ minetest.register_node( ":technic:mineral_zinc", {
description = S("Zinc Ore"),
tiles = { "default_stone.png^technic_mineral_zinc.png" },
is_ground_content = true,
groups = {cracky=3},
groups = {cracky=3, rad_resistance=19},
sounds = default.node_sound_stone_defaults(),
drop = "technic:zinc_lump",
})
Expand All @@ -50,31 +50,31 @@ minetest.register_node( ":technic:granite", {
description = S("Granite"),
tiles = { "technic_granite.png" },
is_ground_content = true,
groups = {cracky=1},
groups = {cracky=1, rad_resistance=18},
sounds = default.node_sound_stone_defaults(),
})

minetest.register_node( ":technic:granite_bricks", {
description = S("Granite Bricks"),
tiles = { "technic_granite_bricks.png" },
is_ground_content = false,
groups = {cracky=1},
groups = {cracky=1, rad_resistance=18},
sounds = default.node_sound_stone_defaults(),
})

minetest.register_node( ":technic:marble", {
description = S("Marble"),
tiles = { "technic_marble.png" },
is_ground_content = true,
groups = {cracky=3, marble=1},
groups = {cracky=3, marble=1, rad_resistance=18},
sounds = default.node_sound_stone_defaults(),
})

minetest.register_node( ":technic:marble_bricks", {
description = S("Marble Bricks"),
tiles = { "technic_marble_bricks.png" },
is_ground_content = false,
groups = {cracky=3},
groups = {cracky=3, rad_resistance=18},
sounds = default.node_sound_stone_defaults(),
})

Expand All @@ -90,23 +90,23 @@ minetest.register_node(":technic:chromium_block", {
description = S("Chromium Block"),
tiles = { "technic_chromium_block.png" },
is_ground_content = true,
groups = {cracky=1, level=2},
groups = {cracky=1, level=2, rad_resistance=37},
sounds = default.node_sound_stone_defaults()
})

minetest.register_node(":technic:zinc_block", {
description = S("Zinc Block"),
tiles = { "technic_zinc_block.png" },
is_ground_content = true,
groups = {cracky=1, level=2},
groups = {cracky=1, level=2, rad_resistance=36},
sounds = default.node_sound_stone_defaults()
})

minetest.register_node(":technic:lead_block", {
description = S("Lead Block"),
tiles = { "technic_lead_block.png" },
is_ground_content = true,
groups = {cracky=1, level=2},
groups = {cracky=1, level=2, rad_resistance=80},
DustyDave961 marked this conversation as resolved.
Show resolved Hide resolved
sounds = default.node_sound_stone_defaults()
})

Expand All @@ -121,23 +121,23 @@ minetest.register_node(":technic:cast_iron_block", {
description = S("Cast Iron Block"),
tiles = { "technic_cast_iron_block.png" },
is_ground_content = true,
groups = {cracky=1, level=2},
groups = {cracky=1, level=2, rad_resistance=40},
sounds = default.node_sound_stone_defaults()
})

minetest.register_node(":technic:carbon_steel_block", {
description = S("Carbon Steel Block"),
tiles = { "technic_carbon_steel_block.png" },
is_ground_content = true,
groups = {cracky=1, level=2},
groups = {cracky=1, level=2, rad_resistance=40},
sounds = default.node_sound_stone_defaults()
})

minetest.register_node(":technic:stainless_steel_block", {
description = S("Stainless Steel Block"),
tiles = { "technic_stainless_steel_block.png" },
is_ground_content = true,
groups = {cracky=1, level=2},
groups = {cracky=1, level=2, rad_resistance=40},
sounds = default.node_sound_stone_defaults()
})

Expand Down