@@ -66,30 +66,63 @@ minetest.register_on_placenode(mesecon.on_placenode)
6666minetest .register_on_dignode (mesecon .on_dignode )
6767
6868-- Overheating service for fast circuits
69+ local OVERHEAT_MAX = mesecon .setting (" overheat_max" , 20 )
70+ local COOLDOWN_TIME = mesecon .setting (" cooldown_time" , 2.0 )
71+ local COOLDOWN_STEP = mesecon .setting (" cooldown_granularity" , 0.5 )
72+ local COOLDOWN_MULTIPLIER = OVERHEAT_MAX / COOLDOWN_TIME
73+ local cooldown_timer = 0.0
74+ local object_heat = {}
6975
7076-- returns true if heat is too high
71- mesecon .do_overheat = function (pos )
72- local meta = minetest .get_meta (pos )
73- local heat = meta :get_int (" heat" ) or 0
74-
75- heat = heat + 1
76- meta :set_int (" heat" , heat )
77-
78- if heat < mesecon .setting (" overheat_max" , 20 ) then
79- mesecon .queue :add_action (pos , " cooldown" , {}, 1 , nil , 0 )
80- else
77+ function mesecon .do_overheat (pos )
78+ local id = minetest .hash_node_position (pos )
79+ local heat = (object_heat [id ] or 0 ) + 1
80+ object_heat [id ] = heat
81+ if heat >= OVERHEAT_MAX then
82+ minetest .log (" action" , " Node overheats at " .. minetest .pos_to_string (pos ))
83+ object_heat [id ] = nil
8184 return true
8285 end
83-
8486 return false
8587end
8688
89+ function mesecon .do_cooldown (pos )
90+ local id = minetest .hash_node_position (pos )
91+ object_heat [id ] = nil
92+ end
8793
88- mesecon .queue :add_function (" cooldown" , function (pos )
89- local meta = minetest .get_meta (pos )
90- local heat = meta :get_int (" heat" )
94+ function mesecon .get_heat (pos )
95+ local id = minetest .hash_node_position (pos )
96+ return object_heat [id ] or 0
97+ end
9198
92- if (heat > 0 ) then
93- meta :set_int (" heat" , heat - 1 )
99+ function mesecon .move_hot_nodes (moved_nodes )
100+ local new_heat = {}
101+ for _ , n in ipairs (moved_nodes ) do
102+ local old_id = minetest .hash_node_position (n .oldpos )
103+ local new_id = minetest .hash_node_position (n .pos )
104+ new_heat [new_id ] = object_heat [old_id ]
105+ object_heat [old_id ] = nil
106+ end
107+ for id , heat in pairs (new_heat ) do
108+ object_heat [id ] = heat
94109 end
95- end )
110+ end
111+
112+ local function global_cooldown (dtime )
113+ cooldown_timer = cooldown_timer + dtime
114+ if cooldown_timer < COOLDOWN_STEP then
115+ return -- don't overload the CPU
116+ end
117+ local cooldown = COOLDOWN_MULTIPLIER * cooldown_timer
118+ cooldown_timer = 0
119+ for id , heat in pairs (object_heat ) do
120+ heat = heat - cooldown
121+ if heat <= 0 then
122+ object_heat [id ] = nil -- free some RAM
123+ else
124+ object_heat [id ] = heat
125+ end
126+ end
127+ end
128+ minetest .register_globalstep (global_cooldown )
0 commit comments