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 18 commits into
base: master
Choose a base branch
from
103 changes: 72 additions & 31 deletions technic/radiation.lua
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,26 @@ or complex internal structure should show no radiation resistance.
Fractional resistance values are permitted.
--]]

local rad_resistance_node = {}
local rad_resistance_group = {}
local cache_radiation_resistance = {}

-- Function to register node-specific resistance
function technic.register_rad_resistance(node_name, resistance)
SmallJoker marked this conversation as resolved.
Show resolved Hide resolved
rad_resistance_node[node_name] = resistance
cache_radiation_resistance[node_name] = nil -- Invalidate cache
end

-- Function to register multiple node resistances at once
function technic.register_multiple_resistances(resistances)
for node_name, resistance in pairs(resistances) do
technic.register_rad_resistance(node_name, 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 @@ -165,38 +182,62 @@ local rad_resistance_node = {
["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

-- Register all node resistances at once
technic.register_multiple_resistances(node_resistances)

-- Function to register group-specific resistance
function technic.register_group_resistance(group_name, resistance)
rad_resistance_group[group_name] = resistance
-- Invalidate cache for all nodes in this group
for node_name, def in pairs(minetest.registered_nodes) do
if def.groups[group_name] then
cache_radiation_resistance[node_name] = nil
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
function node_radiation_resistance(node_name)
DustyDave961 marked this conversation as resolved.
Show resolved Hide resolved
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

-- Check for rad_resistance group in node definition
resistance = 0
for g, v in pairs(def.groups) do
if g == "rad_resistance" then
resistance = resistance + v
end
end
DustyDave961 marked this conversation as resolved.
Show resolved Hide resolved

-- If no rad_resistance group, use registered node-specific resistance
if resistance == 0 then
DustyDave961 marked this conversation as resolved.
Show resolved Hide resolved
resistance = rad_resistance_node[node_name] or 0
end

-- Add group-specific resistance if applicable
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

resistance = math.sqrt(resistance)
cache_radiation_resistance[node_name] = resistance
return resistance
end

--[[
Radioactive nodes cause damage to nearby players. The damage
Expand Down