trigger.lua 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. local trigger = {}
  2. function trigger.get_global_environment()
  3. local env = {}
  4. for influence, func in pairs(climate_mod.global_influences) do
  5. env[influence] = func()
  6. end
  7. return env
  8. end
  9. function trigger.get_position_environment(pos)
  10. local env = table.copy(climate_mod.global_environment)
  11. for influence, func in pairs(climate_mod.influences) do
  12. env[influence] = func(pos)
  13. end
  14. return env
  15. end
  16. function trigger.get_player_environment(player)
  17. local ppos = player:get_pos()
  18. local env = trigger.get_position_environment(ppos)
  19. env.player = player
  20. return env
  21. end
  22. function trigger.test_condition(condition, env, goal)
  23. local value = env[condition:sub(5)]
  24. if condition:sub(1, 4) == "min_" then
  25. return type(value) ~= "nil" and goal <= value
  26. elseif condition:sub(1, 4) == "max_" then
  27. return type(value) ~= "nil" and goal > value
  28. elseif condition:sub(1, 4) == "has_" then
  29. if type(value) == "nil" then return false end
  30. for _, g in ipairs(goal) do
  31. if value == g then return true end
  32. end
  33. return false
  34. else
  35. value = env[condition]
  36. return type(value) == "nil" or goal == value
  37. end
  38. end
  39. local function is_weather_active(player, weather, env)
  40. if climate_mod.forced_weather[weather] ~= nil then
  41. return climate_mod.forced_weather[weather]
  42. end
  43. local config = climate_mod.weathers[weather]
  44. if type(config.conditions) == "function" then
  45. return config.conditions(env)
  46. end
  47. for condition, goal in pairs(config.conditions) do
  48. if not trigger.test_condition(condition, env, goal) then
  49. return false
  50. end
  51. end
  52. return true
  53. end
  54. local function get_weather_effects(player, weather_config, env)
  55. local config = {}
  56. local effects = {}
  57. if type(weather_config.effects) == "function" then
  58. config = weather_config.effects(env)
  59. else
  60. config = weather_config.effects
  61. end
  62. for effect, value in pairs(config) do
  63. if type(climate_mod.effects[effect]) ~= "nil" then
  64. effects[effect] = value
  65. end
  66. end
  67. return effects
  68. end
  69. function trigger.get_active_effects()
  70. local environments = {}
  71. for _, player in ipairs(minetest.get_connected_players()) do
  72. local playername = player:get_player_name()
  73. local hp = player:get_hp()
  74. -- skip weather presets for dead players
  75. if hp ~= nil and hp > 0 then
  76. environments[playername] = trigger.get_player_environment(player)
  77. end
  78. end
  79. local effects = {}
  80. climate_mod.current_weather = {}
  81. for wname, wconfig in pairs(climate_mod.weathers) do
  82. for _, player in ipairs(minetest.get_connected_players()) do
  83. local pname = player:get_player_name()
  84. local env = environments[pname]
  85. if env ~= nil then
  86. if is_weather_active(player, wname, env) then
  87. if type(climate_mod.current_weather[pname]) == "nil" then
  88. climate_mod.current_weather[pname] = {}
  89. end
  90. table.insert(climate_mod.current_weather[pname], wname)
  91. local player_effects = get_weather_effects(player, wconfig, env)
  92. for effect, value in pairs(player_effects) do
  93. if type(effects[effect]) == "nil" then
  94. effects[effect] = {}
  95. end
  96. if type(effects[effect][pname]) == "nil" then
  97. effects[effect][pname] = {}
  98. end
  99. effects[effect][pname][wname] = value
  100. end
  101. end
  102. end
  103. end
  104. end
  105. return effects
  106. end
  107. function trigger.call_handlers(name, effect, prev_effect)
  108. if effect == nil then effect = {} end
  109. if prev_effect == nil then prev_effect = {} end
  110. local starts = {}
  111. local has_starts = false
  112. local ticks = {current = {}, prev = {}}
  113. local has_ticks = false
  114. local stops = {}
  115. local has_stops = false
  116. for player, sources in pairs(effect) do
  117. if type(prev_effect[player]) ~= "nil" then
  118. has_ticks = true
  119. ticks.current[player] = sources
  120. ticks.prev[player] = prev_effect[player]
  121. else
  122. has_starts = true
  123. starts[player] = sources
  124. end
  125. end
  126. for player, sources in pairs(prev_effect) do
  127. if type(effect[player]) == "nil" then
  128. stops[player] = sources
  129. has_stops = true
  130. end
  131. end
  132. if has_starts then
  133. for _, handler in ipairs(climate_mod.effects[name]["start"]) do
  134. handler(starts)
  135. end
  136. end
  137. if has_ticks then
  138. for _, handler in ipairs(climate_mod.effects[name]["tick"]) do
  139. handler(ticks.current, ticks.prev)
  140. end
  141. end
  142. -- remaining table lists ending effects
  143. if has_stops then
  144. for _, handler in ipairs(climate_mod.effects[name]["stop"]) do
  145. handler(stops)
  146. end
  147. end
  148. end
  149. return trigger