~fgaz/minetest-falling_nodes

a6cb5cb55db067554faf3578efa6cf9ac5a6ada9 — Francesco Gazzetta a month ago ea498cd
Add static heat/temperature
3 files changed, 66 insertions(+), 0 deletions(-)

A mods/falling_nodes/heat.lua
M mods/falling_nodes/init.lua
M mods/falling_nodes/materials.lua
A mods/falling_nodes/heat.lua => mods/falling_nodes/heat.lua +50 -0
@@ 0,0 1,50 @@
-- TODO implement heat simulation / dynamic temperatures
minetest.register_on_mods_loaded(function()
  for name,def in pairs(falling_nodes.registered_materials) do
    if def.temperature_high then
      local hotter = {}
      -- FIXME quadratic on the number of registered materials
      for name_,def_ in pairs(falling_nodes.registered_materials) do
        if def_.temperature_base >= def.temperature_high.temperature then
          table.insert(hotter, name_)
        end
      end
      if #hotter ~= 0 then
        minetest.register_abm {
          label = "High temperature: " .. name,
          nodenames = {name},
          neighbors = hotter,
	  -- TODO make heat conductivity and/or temperature difference
	  -- affect either interval or chance.
          interval = minetest.settings:get("abm_interval") * 1,
	  -- 26 is the number of neighbors. chance 1 would be disproportionately fast.
          chance = 26,
          catch_up = false,
          -- MAYBE based on heat capacity, trigger this action and/or the action of the hot node
          action = falling_nodes.registered_materials[name].temperature_high.action,
        }
      end
    end
    if def.temperature_low then
      local colder = {}
      for name_,def_ in pairs(falling_nodes.registered_materials) do
        if def_.temperature_base <= def.temperature_low.temperature then
          print(name_ .. " is colder than " .. name)
          table.insert(colder, name_)
        end
      end
      if #colder ~= 0 then
        print(name .. " has colder materials")
        minetest.register_abm {
          label = "Low temperature: " .. name,
          nodenames = {name},
          neighbors = colder,
          interval = minetest.settings:get("abm_interval") * 1,
          chance = 26,
          catch_up = false,
          action = falling_nodes.registered_materials[name].temperature_low.action,
        }
      end
    end
  end
end)

M mods/falling_nodes/init.lua => mods/falling_nodes/init.lua +1 -0
@@ 8,5 8,6 @@ dofile(minetest.get_modpath(modname) .. "/temporary_settings.lua")
dofile(minetest.get_modpath(modname) .. "/states_of_matter.lua")
dofile(minetest.get_modpath(modname) .. "/explosions.lua")
dofile(minetest.get_modpath(modname) .. "/materials.lua")
dofile(minetest.get_modpath(modname) .. "/heat.lua")
dofile(minetest.get_modpath(modname) .. "/walls.lua")
dofile(minetest.get_modpath(modname) .. "/tools.lua")

M mods/falling_nodes/materials.lua => mods/falling_nodes/materials.lua +15 -0
@@ 4,12 4,25 @@ local utils = dofile(minetest.get_modpath(modname) .. "/utils.lua")

falling_nodes.registered_materials = {}

--- Celsius to Kelvin
local function C2K(C) return C * 273.15 end

function falling_nodes.register_material(name, original_def)
  local def = table.copy(original_def)
  def.temperature_base = def.temperature_base or C2K(22)
  falling_nodes.registered_materials[name] = {}
  -- TODO validation
  for _,field in ipairs {
    "electricity_action",
    -- DefaultProperties.temp in TPT
    "temperature_base",
    -- HighTemperature in TPT.
    -- {temperature : number, action : function(pos)}
    -- MAYBE action can be a node name to be swapped
    "temperature_high",
    -- LowTemperature in TPT
    -- {temperature : number, action : function(pos)}
    "temperature_low",
  } do
    falling_nodes.registered_materials[name][field] = def[field]
    def[field] = nil


@@ 60,6 73,7 @@ falling_nodes.register_material("falling_nodes:fire", {
  drawtype = "firelike",
  paramtype = "light",
  walkable = false,
  temperature_base = C2K(422)
})

-- TODO a timer would be better, but it has to be transferred when nodes are moved


@@ 79,6 93,7 @@ falling_nodes.register_material("falling_nodes:lava", {
    ["falling_nodes:liquid"] = 1,
    ["falling_nodes:igniter"] = 1,
  },
  temperature_base = C2K(1500),
})

falling_nodes.register_material("falling_nodes:gunpowder", {