services.lua 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. -- Dig and place services
  2. mesecon.on_placenode = function(pos, node)
  3. mesecon.execute_autoconnect_hooks_now(pos, node)
  4. -- Receptors: Send on signal when active
  5. if mesecon.is_receptor_on(node.name) then
  6. mesecon.receptor_on(pos, mesecon.receptor_get_rules(node))
  7. end
  8. -- Conductors: Send turnon signal when powered or replace by respective offstate conductor
  9. -- if placed conductor is an onstate one
  10. if mesecon.is_conductor(node.name) then
  11. local sources = mesecon.is_powered(pos)
  12. if sources then
  13. -- also call receptor_on if itself is powered already, so that neighboring
  14. -- conductors will be activated (when pushing an on-conductor with a piston)
  15. for _, s in ipairs(sources) do
  16. local rule = vector.subtract(pos, s)
  17. mesecon.turnon(pos, rule)
  18. end
  19. --mesecon.receptor_on (pos, mesecon.conductor_get_rules(node))
  20. elseif mesecon.is_conductor_on(node) then
  21. node.name = mesecon.get_conductor_off(node)
  22. minetest.swap_node(pos, node)
  23. end
  24. end
  25. -- Effectors: Send changesignal and activate or deactivate
  26. if mesecon.is_effector(node.name) then
  27. local powered_rules = {}
  28. local unpowered_rules = {}
  29. -- for each input rule, check if powered
  30. for _, r in ipairs(mesecon.effector_get_rules(node)) do
  31. local powered = mesecon.is_powered(pos, r)
  32. if powered then table.insert(powered_rules, r)
  33. else table.insert(unpowered_rules, r) end
  34. local state = powered and mesecon.state.on or mesecon.state.off
  35. mesecon.changesignal(pos, node, r, state, 1)
  36. end
  37. if (#powered_rules > 0) then
  38. for _, r in ipairs(powered_rules) do
  39. mesecon.activate(pos, node, r, 1)
  40. end
  41. else
  42. for _, r in ipairs(unpowered_rules) do
  43. mesecon.deactivate(pos, node, r, 1)
  44. end
  45. end
  46. end
  47. end
  48. mesecon.on_dignode = function(pos, node)
  49. if mesecon.is_conductor_on(node) then
  50. mesecon.receptor_off(pos, mesecon.conductor_get_rules(node))
  51. elseif mesecon.is_receptor_on(node.name) then
  52. mesecon.receptor_off(pos, mesecon.receptor_get_rules(node))
  53. end
  54. mesecon.execute_autoconnect_hooks_queue(pos, node)
  55. end
  56. function mesecon.on_blastnode(pos, intensity)
  57. local node = minetest.get_node(pos)
  58. minetest.remove_node(pos)
  59. mesecon.on_dignode(pos, node)
  60. return minetest.get_node_drops(node.name, "")
  61. end
  62. minetest.register_on_placenode(mesecon.on_placenode)
  63. minetest.register_on_dignode(mesecon.on_dignode)
  64. -- Overheating service for fast circuits
  65. local OVERHEAT_MAX = mesecon.setting("overheat_max", 20)
  66. local COOLDOWN_TIME = mesecon.setting("cooldown_time", 2.0)
  67. local COOLDOWN_STEP = mesecon.setting("cooldown_granularity", 0.5)
  68. local COOLDOWN_MULTIPLIER = OVERHEAT_MAX / COOLDOWN_TIME
  69. local cooldown_timer = 0.0
  70. local object_heat = {}
  71. -- returns true if heat is too high
  72. function mesecon.do_overheat(pos)
  73. local id = minetest.hash_node_position(pos)
  74. local heat = (object_heat[id] or 0) + 1
  75. object_heat[id] = heat
  76. if heat >= OVERHEAT_MAX then
  77. minetest.log("action", "Node overheats at " .. minetest.pos_to_string(pos))
  78. object_heat[id] = nil
  79. return true
  80. end
  81. return false
  82. end
  83. function mesecon.do_cooldown(pos)
  84. local id = minetest.hash_node_position(pos)
  85. object_heat[id] = nil
  86. end
  87. function mesecon.get_heat(pos)
  88. local id = minetest.hash_node_position(pos)
  89. return object_heat[id] or 0
  90. end
  91. function mesecon.move_hot_nodes(moved_nodes)
  92. local new_heat = {}
  93. for _, n in ipairs(moved_nodes) do
  94. local old_id = minetest.hash_node_position(n.oldpos)
  95. local new_id = minetest.hash_node_position(n.pos)
  96. new_heat[new_id] = object_heat[old_id]
  97. object_heat[old_id] = nil
  98. end
  99. for id, heat in pairs(new_heat) do
  100. object_heat[id] = heat
  101. end
  102. end
  103. local function global_cooldown(dtime)
  104. cooldown_timer = cooldown_timer + dtime
  105. if cooldown_timer < COOLDOWN_STEP then
  106. return -- don't overload the CPU
  107. end
  108. local cooldown = COOLDOWN_MULTIPLIER * cooldown_timer
  109. cooldown_timer = 0
  110. for id, heat in pairs(object_heat) do
  111. heat = heat - cooldown
  112. if heat <= 0 then
  113. object_heat[id] = nil -- free some RAM
  114. else
  115. object_heat[id] = heat
  116. end
  117. end
  118. end
  119. minetest.register_globalstep(global_cooldown)