abm.lua 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. local S=physio_stress.intllib
  2. minetest.register_globalstep(function(dtime)
  3. physio_stress.dt=physio_stress.dt+dtime
  4. physio_stress.dt_heal=physio_stress.dt_heal+dtime
  5. -- print("dtime "..dtime)
  6. if physio_stress.dt > physio_stress.dtime then
  7. -- print("ping")
  8. local starttime=os.clock()
  9. physio_stress.dt=0
  10. physio_stress.dtime=tonumber(minetest.settings:get(physio_stress.intprefix..".dtime")) or 1
  11. physio_stress.dtime=math.max(0.1,physio_stress.dtime+(math.random(1,3)-2)/10) -- random time between global steps
  12. local players = minetest.get_connected_players()
  13. for i=1, #players do
  14. local player=players[i]
  15. local name = player:get_player_name()
  16. local ps=physio_stress.player[name]
  17. if ps["disabled"] == nil then --check if player is disabled (dies, left etc.)
  18. local act_pos=player:get_pos()
  19. local act_light=minetest.get_node_light(act_pos)
  20. local player_armor=0
  21. if armor ~= nil then -- fail back to check if 3d_armor is used
  22. local player_armor=armor.def[name].count
  23. end
  24. local act_node=minetest.get_node(act_pos)
  25. --sunburn/nyctophoby
  26. for i,attr in ipairs(physio_stress.phobies) do
  27. physio_stress.abm[attr](player)
  28. if xpfw.player_get_attribute(player,attr)>19 then
  29. minetest.chat_send_player(name,S("Beware of "..attr))
  30. player:set_hp( player:get_hp() - ps[attr.."_hp"] )
  31. xpfw.player_sub_attribute(player,attr,2)
  32. end
  33. if ps[attr.."_protect"] then
  34. ps[attr.."_delay"]=ps[attr.."_delay"]-dtime
  35. if ps[attr.."_delay"] < 0 then
  36. minetest.chat_send_player(name,S("no".." "..attr.." ".."protection"))
  37. ps[attr.."_protect"] = false
  38. end
  39. end
  40. end
  41. -- exhaustion
  42. if physio_stress.attributes.exhaustion then
  43. -- get max of speeds
  44. local no_speeds=0
  45. local exh=0
  46. for i,attr in ipairs(physio_stress.action_names) do --swam, walk etc.
  47. local aspeed=xpfw.player_get_attribute(player,"mean_"..attr.."_speed")
  48. if aspeed ~= nil then
  49. if aspeed > 0 then
  50. no_speeds=no_speeds+1
  51. exh=exh+aspeed*aspeed
  52. end
  53. end
  54. end
  55. if no_speeds>0 then
  56. exh=math.sqrt(exh)
  57. else
  58. exh = 0
  59. end
  60. -- if one speed excel actual exhaustion level than set to max.
  61. xpfw.player_add_attribute(player,"exhaustion",exh)
  62. if xpfw.player_get_attribute(player,"exhaustion") > 19 then
  63. local ret = playereffects.apply_effect_type("exhausted", 60, player)
  64. end
  65. physio_stress.hud_update(player,"exhaustion",xpfw.player_get_attribute(player,"exhaustion"))
  66. end
  67. -- saturation/thirst
  68. for j,st in ipairs(physio_stress.ingestion) do -- call for saturation/thirst similar calls
  69. if physio_stress.attributes[st] then
  70. local dsat=0
  71. -- for each coefficient (walked, swam, dug, build, base consumption) the sum of saturation/thirst consumption is added
  72. for i,attr in ipairs(physio_stress.st_coeff_names) do
  73. local dref=ps[st.."_"..attr]
  74. if dref==nil then
  75. dref=physio_stress.default_player[st.."_"..attr]
  76. end
  77. if dref==nil then dref=1 end
  78. -- print(st.." "..attr.." "..math.max(0,(xpfw.player_get_attribute(player,attr)-ps[attr])/(dref)).." dref "..dref)
  79. dsat=dsat+math.max(0,(xpfw.player_get_attribute(player,attr)-ps[attr])/(dref))
  80. end
  81. if physio_stress.attributes.exhaustion then
  82. local dref=ps[st.."_exhaustion"]
  83. if dref==nil then
  84. dref=physio_stress.default_player[st.."_exhaustion"]
  85. end
  86. if dref==nil then dref=1 end
  87. -- print(st.." exhaustion "..math.max(0,(xpfw.player_get_attribute(player,"exhaustion")/dtime)/(dref)).." dref "..dref)
  88. dsat=dsat+math.max(0,(xpfw.player_get_attribute(player,"exhaustion")/dtime)/(dref))
  89. end
  90. -- small corrections due to hardness of dug nodes (by group stage): harder stones need more energy
  91. local dref=ps[st.."_dug"]
  92. if dref==nil then
  93. dref=physio_stress.default_player[st.."_dug"]
  94. end
  95. for i,attr in ipairs(physio_stress.dig_groups) do
  96. local correction=physio_stress.dig_correction[attr] or 1
  97. dsat=dsat+math.max(0,(ps[attr]*correction)/(3*dref))
  98. end
  99. -- if player has enough saturation/thirst, this is reduced
  100. -- print(st.." "..dsat)
  101. xpfw.player_sub_attribute(player,st,math.min(dsat,xpfw.player_get_attribute(player,st)))
  102. end
  103. end
  104. -- actuall stats are copied
  105. for i,attr in ipairs(physio_stress.st_coeff_names) do
  106. local patt=xpfw.player_get_attribute(player,attr)
  107. if patt ~= nil then
  108. ps[attr]=patt
  109. end
  110. end
  111. -- dig groups are resetted
  112. for i,attr in ipairs(physio_stress.dig_groups) do
  113. ps[attr]=0
  114. end
  115. end
  116. end
  117. -- print("physio_stress_abm: "..1000*(os.clock()-starttime))
  118. end
  119. if physio_stress.dt_heal > physio_stress.dtime_heal then
  120. physio_stress.dt_heal = 0
  121. physio_stress.dtime_heal=tonumber(minetest.settings:get(physio_stress.intprefix..".dtime_heal")) or 1
  122. physio_stress.dtime_heal=math.max(0.1,physio_stress.dtime_heal+(math.random(1,3)-2)/10) -- random time between global steps
  123. local players = minetest.get_connected_players()
  124. for i=1, #players do
  125. local player=players[i]
  126. local name = player:get_player_name()
  127. local ps=physio_stress.player[name]
  128. if ps["disabled"] == nil then --check if player is disabled (dies, left etc.)
  129. local act_pos=player:get_pos()
  130. local act_node=minetest.get_node(act_pos)
  131. -- thirst recreation in water
  132. if physio_stress.attributes.thirst then
  133. if minetest.get_item_group(act_node.name,"water")>0 then
  134. if xpfw.player_get_attribute(player,"thirst")<physio_stress.thirstmax then
  135. if ps["drinking"] == nil then
  136. xpfw.player_add_attribute(player,"thirst",2)
  137. physio_stress.hud_update(player,"thirst",xpfw.player_get_attribute(player,"thirst"))
  138. ps["drinking"] = 1
  139. else
  140. ps["drinking"] = nil
  141. end
  142. end
  143. end
  144. end
  145. -- heal by saturation
  146. if physio_stress.attributes.saturation then
  147. local hp=player:get_hp()
  148. local sat=tonumber(xpfw.player_get_attribute(player,"saturation"))
  149. if hp<20 and sat>hp and sat >= physio_stress.saturation_minhealing then
  150. if ps["healing"] == nil then
  151. xpfw.player_sub_attribute(player,"saturation",2*physio_stress.saturation_recreation)
  152. physio_stress.hud_update(player,"saturation",xpfw.player_get_attribute(player,"saturation"))
  153. hp=hp+physio_stress.saturation_recreation
  154. player:set_hp(hp)
  155. ps["healing"] = 1
  156. else
  157. ps["healing"] = nil
  158. end
  159. end
  160. end
  161. -- saturation/thirst
  162. -- if saturation/thirst is zero, reduce health points
  163. for j,st in ipairs(physio_stress.ingestion) do -- call for saturation/thirst similar calls
  164. if physio_stress.attributes[st] then
  165. if xpfw.player_get_attribute(player,st)==0 then
  166. if ps["hp_"..st] == nil then
  167. player:set_hp(player:get_hp()-0.5)
  168. ps["hp_"..st] = 1
  169. else
  170. ps["hp_"..st] = nil
  171. end
  172. end
  173. end
  174. end
  175. end
  176. end
  177. end
  178. end)