nodes_register.lua 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653
  1. local S = farming.intllib
  2. -- fallback default definition, if no defaults given by configuration
  3. local farming_default_env={temperature_min=0,temperature_max=100,humidity_min=0,humidity_max=100,
  4. elevation_min=0,elevation_max=31000,light_min=10,light_max=default.LIGHT_MAX,rarety=10,
  5. grow_time_mean=120,spread_rate=1e-5,infect_rate_base=1e-5,infect_rate_monoculture=1e-3,
  6. harvest_max=2,place_param2 = 3,}
  7. -- function to check definition for a plant
  8. -- and set to defaults values
  9. local register_plant_check_def = function(def) -- time optimised
  10. -- local starttime=os.clock()
  11. local actmodname=minetest.get_current_modname()
  12. local base_name=actmodname..":"..def.name
  13. def.mod_name=actmodname
  14. def.plant_name=def.name
  15. def.base_name=base_name
  16. def.basepng=base_name:gsub(":","_")
  17. for dn,dv in pairs(farming_default_env) do
  18. if def[dn] == nil then
  19. def[dn] = dv
  20. end
  21. end
  22. if not def.description then
  23. def.description = def.name:gsub("^%l", string.upper)
  24. end
  25. if not def.fertility then
  26. def.fertility = {"grassland"}
  27. end
  28. if def.groups.seed_grindable ~= nil then
  29. if not def.grind then
  30. def.grind = base_name.."_grinded"
  31. end
  32. end
  33. if def.groups.seed_roastable ~= nil then
  34. if not def.roast then
  35. def.roast = base_name.."_roasted"
  36. end
  37. end
  38. if def.groups.for_coffee ~= nil then
  39. if def.roast ~= nil then
  40. if string.find(def.roast,"roasted")~=nil then
  41. def.coffeepowder=def.roast:gsub("roasted","powder")
  42. end
  43. end
  44. end
  45. -- check if seed_drop is set and check if it is a node name
  46. if def.seed_drop then
  47. if not string.match(def.seed_drop,":") then
  48. def.seed_drop=actmodname..":"..def.seed_drop
  49. end
  50. def.groups["has_harvest"] = 1
  51. end
  52. if def.groups.wiltable then
  53. if not def.wilt_time then
  54. def.wilt_time = farming.wilt_time
  55. end
  56. end
  57. if not def.place_param2 then
  58. def.place_param2 = 3
  59. end
  60. def.grow_time_min=math.floor(def.grow_time_mean*0.75)
  61. def.grow_time_max=math.floor(def.grow_time_mean*1.2)
  62. -- print("time check definition "..1000*(os.clock()-starttime))
  63. return def
  64. end
  65. -- Register plants
  66. farming.register_plant = function(def)
  67. -- Check def table
  68. if not def.steps then
  69. return nil
  70. end
  71. -- check definition
  72. def = register_plant_check_def(def)
  73. -- local definitions
  74. def.step_name=def.mod_name..":"..def.name
  75. def.seed_name=def.mod_name..":"..def.name.."_seed"
  76. def.plant_name = def.name
  77. local def_groups=def.groups
  78. -- if plant has harvest then registering
  79. if def_groups["has_harvest"] ~= nil then
  80. -- if plant drops seed of wild crop, set the wild seed as harvest
  81. if def.seed_drop ~= nil then
  82. def.harvest_name = def.seed_drop
  83. else
  84. def.harvest_name = def.step_name
  85. end
  86. print(def.harvest_name)
  87. farming.register_harvest(def)
  88. else
  89. def.harvest_name=def.seed_name
  90. end
  91. if def_groups["wiltable"] == 2 then
  92. def.wilt_name=def.mod_name..":wilt_"..def.name
  93. farming.register_wilt(def)
  94. end
  95. farming.register_seed(def)
  96. farming.register_steps(def)
  97. -- crops, which should be cultured, does not randomly appear on the field
  98. if (not def_groups["to_culture"]) then
  99. local edef=def
  100. local spread_def={name=def.step_name.."_1",
  101. temp_min=edef.temperature_min,temp_max=edef.temperature_max,
  102. hum_min=edef.humidity_min,hum_max=edef.humidity_max,
  103. y_min=edef.elevation_min,y_max=edef.elevation_max,base_rate = math.floor(math.log(def.spread_rate*1e10)),
  104. light_min=edef.light_min,light_max=edef.light_max}
  105. farming.min_light = math.min(farming.min_light,edef.light_min)
  106. table.insert(farming.spreading_crops,1,spread_def)
  107. end
  108. if def_groups["infectable"] then
  109. farming.register_infect(def)
  110. end
  111. -- if defined special roast, grind item or seed to drop,
  112. -- check if the item already exist. when not than register it.
  113. for _,it in ipairs({"roast","grind","seed_drop"}) do
  114. if def[it] ~= nil then
  115. if minetest.registered_craftitems[def[it]] == nil then
  116. farming.register_craftitem(def[it])
  117. end
  118. end
  119. end
  120. if def_groups["use_flail"] then
  121. if def.straw == nil then
  122. def.straw= "farming:straw"
  123. end
  124. farming.craft_seed(def)
  125. end
  126. if def_groups["use_trellis"] then
  127. farming.trellis_seed(def)
  128. -- print(dump(def))
  129. end
  130. if def_groups["seed_grindable"] then
  131. farming.register_grind(def)
  132. end
  133. if def_groups["seed_roastable"] then
  134. farming.register_roast(def)
  135. end
  136. if def_groups["for_coffee"] then
  137. farming.register_coffee(def)
  138. end
  139. if def.rarety_grass_drop ~= nil then
  140. if def.harvest_name ~= nil then
  141. table.insert(farming.grass_drop.items,1,{items={def.harvest_name},rarity=def.rarety_grass_drop})
  142. end
  143. end
  144. if def.rarety_junglegrass_drop ~= nil then
  145. if def.harvest_name ~= nil then
  146. table.insert(farming.junglegrass_drop.items,1,{items={def.harvest_name},rarity=def.rarety_junglegrass_drop})
  147. end
  148. end
  149. farming.registered_plants[def.name] = def
  150. end
  151. farming.register_harvest=function(hdef) --time optimised
  152. -- base definition of harvest
  153. local harvest_def={
  154. description = S(hdef.description),
  155. inventory_image = hdef.mod_name.."_"..hdef.plant_name..".png",
  156. groups = {flammable = 2,farming_harvest=1},
  157. plant_name=hdef.plant_name,
  158. }
  159. -- print(hdef.step_name)
  160. minetest.register_craftitem(":" .. hdef.step_name, harvest_def)
  161. end
  162. farming.register_craftitem = function(itemname)
  163. local desc = itemname:split(":")[2]
  164. local item_def={
  165. description = S(desc:gsub("^%l", string.upper)),
  166. inventory_image = itemname:gsub(":","_")..".png",
  167. groups = {flammable = 2},
  168. }
  169. minetest.register_craftitem(":"..itemname,item_def)
  170. end
  171. farming.register_infect=function(idef)
  172. -- local starttime=os.clock()
  173. local infectpng=idef.mod_name.."_"..idef.plant_name.."_ill.png"
  174. local infect_def={
  175. description = S(idef.description),
  176. tiles = {infectpng},
  177. drawtype = "plantlike",
  178. waving = 1,
  179. paramtype = "light",
  180. walkable = false,
  181. buildable_to = true,
  182. on_dig = farming.plant_cured , -- why digging fails?
  183. selection_box = {type = "fixed",
  184. fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5},},
  185. sounds = default.node_sound_leaves_defaults(),
  186. on_timer=farming.timer_infect,
  187. place_param2=idef.place_param2,
  188. groups = {snappy = 3, attached_node = 1, flammable = 2,farming_infect=2},
  189. }
  190. for _,coln in ipairs({"step_name","name","seed_name","plant_name",
  191. "infect_rate_base","infect_rate_monoculture"}) do
  192. infect_def[coln] = idef[coln]
  193. end
  194. infect_def.groups[idef.plant_name] = 0
  195. minetest.register_node(":" .. idef.name.."_infected", infect_def)
  196. -- print("time register infect "..1000*(os.clock()-starttime))
  197. end
  198. farming.register_wilt=function(idef)
  199. -- local starttime=os.clock()
  200. if not idef.wilt_name then
  201. return
  202. end
  203. local wilt_def={
  204. description = S(idef.description:gsub("^%l", string.upper).." wilted"),
  205. tiles = {idef.basepng.."_wilt.png"},
  206. drawtype = "plantlike",
  207. waving = 1,
  208. paramtype = "light",
  209. walkable = false,
  210. buildable_to = true,
  211. selection_box = {type = "fixed",
  212. fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5},},
  213. sounds = default.node_sound_leaves_defaults(),
  214. on_timer = farming.timer_wilt,
  215. place_param2=idef.place_param2,
  216. groups = {snappy = 3, attached_node = 1, flammable = 2,farming_wilt=1},
  217. }
  218. if idef.straw then
  219. wilt_def.drop={items={{items={idef.straw}}}}
  220. end
  221. for _,coln in ipairs({"name","seed_name","plant_name","fertility"}) do
  222. wilt_def[coln] = idef[coln]
  223. end
  224. if idef.groups.wiltable then
  225. wilt_def.groups["wiltable"]=idef.groups.wiltable
  226. end
  227. minetest.register_node(":" .. idef.wilt_name, wilt_def)
  228. -- print("time register wilt "..1000*(os.clock()-starttime))
  229. end
  230. farming.register_seed=function(sdef) --time optimised
  231. -- local starttime=os.clock()
  232. local seed_def = {
  233. description=S(sdef.name:gsub("^%l", string.upper).." Seed"),
  234. next_step = sdef.step_name .. "_1",
  235. drawtype = "signlike",
  236. paramtype = "light",
  237. paramtype2 = "wallmounted",
  238. walkable = false,
  239. sunlight_propagates = true,
  240. selection_box = {
  241. type = "fixed",
  242. fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5},
  243. },
  244. sounds = default.node_sound_dirt_defaults({
  245. dig = {name = "", gain = 0},
  246. dug = {name = "default_grass_footstep", gain = 0.2},
  247. place = {name = "default_place_node", gain = 0.25},
  248. }),
  249. on_place = farming.seed_on_place,
  250. on_timer = farming.timer_seed,
  251. place_param2=sdef.place_param2,
  252. groups = {farming_seed = 1, snappy = 3, attached_node = 1, flammable = 2},
  253. }
  254. for i,colu in ipairs({"fertility","plant_name","grow_time_min","grow_time_max","light_min"}) do
  255. seed_def[colu] = sdef[colu]
  256. end
  257. local invimage=sdef.seed_name:gsub(":","_")..".png"
  258. seed_def.inventory_image = invimage
  259. seed_def.tiles = {invimage}
  260. seed_def.wield_image = {invimage}
  261. seed_def.groups[sdef.mod_name] = 1
  262. for k, v in pairs(sdef.fertility) do
  263. seed_def.groups[v] = 1
  264. end
  265. for i,colu in ipairs({"on_soil","for_flour"}) do
  266. if sdef.groups[colu] then
  267. seed_def.groups[colu] = sdef.groups[colu]
  268. end
  269. end
  270. if sdef.eat_hp or sdef.drink then
  271. local eat_hp=0
  272. if sdef.eat_hp then
  273. eat_hp=sdef.eat_hp
  274. end
  275. seed_def.on_use=minetest.item_eat(eat_hp)
  276. if sdef.eat_hp then
  277. seed_def.groups["eatable"]=sdef.eat_hp
  278. end
  279. if sdef.drink then
  280. seed_def.groups["drinkable"]=sdef.drink
  281. end
  282. end
  283. minetest.register_node(":" .. sdef.seed_name, seed_def)
  284. -- print("time register seed "..1000*(os.clock()-starttime))
  285. end
  286. farming.register_steps = function(sdef)
  287. -- local starttime=os.clock()
  288. -- base configuration of all steps
  289. -- copy some plant definition into definition of this steps
  290. -- define drop item: normal drop the seed
  291. local dropitem=sdef.seed_name
  292. -- if plant has to be harvested, drop harvest instead
  293. if sdef.groups.has_harvest then
  294. if sdef.seed_drop then
  295. dropitem = sdef.seed_drop
  296. else
  297. dropitem = sdef.step_name
  298. end
  299. end
  300. local is_hurting=(sdef.groups.damage_per_second~=nil)
  301. local damage=0
  302. if is_hurting then
  303. damage=sdef.groups.damage_per_second
  304. end
  305. local is_viscos=(sdef.groups.liquid_viscosity and farming.config:get_int("viscosity") > 0)
  306. local viscosity=0
  307. if is_viscos then
  308. viscosity=sdef.groups.liquid_viscosity
  309. end
  310. local max_step=sdef.steps
  311. local stepname=sdef.step_name.."_"
  312. for i=1,max_step do
  313. local reli=i/max_step
  314. local ndef={description=stepname..i,
  315. drawtype = "plantlike",
  316. waving = 1,
  317. paramtype = "light",
  318. walkable = false,
  319. buildable_to = true,
  320. selection_box = {type = "fixed",
  321. fixed = {-0.5, -0.5, -0.5, 0.5, -5/16, 0.5},},
  322. sounds = default.node_sound_leaves_defaults(),
  323. drop_item=dropitem,
  324. drop={items={{items={dropitem}}}},
  325. tiles={sdef.basepng.."_"..i..".png"},
  326. place_param2=sdef.place_param2,
  327. groups = {snappy = 3, flammable = 2,flora=1, plant = 1,
  328. not_in_creative_inventory = 1, attached_node = 1,
  329. step=i,
  330. },
  331. }
  332. for _,colu in ipairs({"grow_time_min","grow_time_max","light_min","plant_name"}) do
  333. ndef[colu]=sdef[colu]
  334. end
  335. for _,colu in ipairs({"infectable","snappy","damage_per_second","liquid_viscosity","wiltable"}) do
  336. if sdef.groups[colu] then
  337. ndef.groups[colu] = sdef.groups[colu]
  338. end
  339. end
  340. ndef.groups[sdef.mod_name]=1
  341. ndef.groups[sdef.plant_name]=1
  342. if sdef.groups.use_trellis then
  343. table.insert(ndef.drop.items,1,{items={"farming:trellis"}})
  344. end
  345. if i < max_step then
  346. ndef.groups["farming_grows"]=1 -- plant is growing
  347. ndef.next_step=stepname.. (i + 1)
  348. ndef.on_timer = farming.timer_step
  349. ndef.grow_time_min=sdef.grow_time_min
  350. ndef.grow_time_max=sdef.grow_time_max
  351. end
  352. -- hurting and viscosity not for first step, which is used for random generation
  353. if i > 1 then
  354. -- check if plant hurts while going through
  355. if is_hurting then
  356. -- calculate damage as part of growing: Full damage only for full grown plant
  357. local step_damage=math.ceil(damage*reli)
  358. if step_damage > 0 then
  359. ndef.damage_per_second = step_damage
  360. end
  361. end
  362. -- for some crops you should walk slowly through like a wheat field
  363. if is_viscos then
  364. local step_viscosity=math.ceil(viscosity*reli)
  365. if step_viscosity > 0 then
  366. ndef.liquid_viscosity= step_viscosity
  367. ndef.liquidtype="source"
  368. ndef.liquid_alternative_source=ndef.description
  369. ndef.liquid_alternative_flowing=ndef.description
  370. ndef.liquid_renewable=false
  371. ndef.liquid_range=0
  372. end
  373. end
  374. end
  375. -- with higher grow levels you harvest more
  376. local step_harvest = math.floor(reli*sdef.harvest_max + 0.05)
  377. if step_harvest > 1 then
  378. for h = 2,step_harvest do
  379. table.insert(ndef.drop.items,1,{items={dropitem},rarity=(max_step - i + 1)*h})
  380. end
  381. end
  382. if i == max_step then
  383. ndef.groups["farming_fullgrown"]=1
  384. for _,colu in ipairs({"punchable","seed_extractable"}) do
  385. if sdef.groups[colu] then
  386. ndef.groups[colu] = sdef.groups[colu]
  387. end
  388. end
  389. ndef.on_dig = farming.dig_harvest
  390. if sdef.groups.wiltable then
  391. local nowilt=sdef.groups.wiltable
  392. if nowilt == 2 then
  393. ndef.next_step=sdef.wilt_name
  394. elseif nowilt == 1 then
  395. ndef.next_step = stepname .. (i - 1)
  396. elseif nowilt == 3 then
  397. ndef.pre_step = stepname .. (i - 1)
  398. ndef.seed_name=sdef.seed_name
  399. end
  400. ndef.on_timer = farming.timer_step
  401. ndef.grow_time_min=sdef.wilt_time or 10
  402. ndef.grow_time_max=math.ceil(ndef.grow_time_min*1.1)
  403. end
  404. -- at the end stage you can harvest by change a cultured seed (if defined)
  405. if sdef.next_plant then
  406. local next_plant_rarity = (max_step - i + 1)*2
  407. --table.insert(ndef.drop.items,1,{items={sdef.next_plant},rarity=next_plant_rarity})
  408. end
  409. if sdef.groups.punchable and i > 1 then
  410. ndef.pre_step = stepname.. (i - 1)
  411. ndef.on_punch = farming.punch_step
  412. end
  413. if sdef.groups.seed_extractable then
  414. ndef.seed_name = sdef.seed_name
  415. end
  416. end
  417. -- print(dump(ndef))
  418. minetest.register_node(":" .. ndef.description, ndef)
  419. end
  420. -- print("time register step "..1000*(os.clock()-starttime))
  421. end
  422. -- define seed crafting out of harvest, releasing kind of straw
  423. function farming.craft_seed(gdef)
  424. if gdef.seed_name == nil then
  425. return
  426. end
  427. if gdef.harvest_name == nil then
  428. return
  429. end
  430. local straw_name = "farming:straw"
  431. if gdef.straw ~= nil then
  432. straw_name = gdef.straw
  433. end
  434. minetest.register_craft({
  435. type = "shapeless",
  436. output = gdef.seed_name.." 1",
  437. recipe = {
  438. farming.modname..":flail",gdef.harvest_name
  439. },
  440. replacements = {{"group:farming_flail", farming.modname..":flail"},
  441. {gdef.harvest_name,straw_name}},
  442. })
  443. end
  444. function farming.register_coffee(cdef)
  445. local starttime=os.clock()
  446. if not cdef.coffeepowder then
  447. return
  448. end
  449. if not cdef.roast then
  450. return
  451. end
  452. local powder_png = cdef.coffeepowder:gsub(":","_")..".png"
  453. local powder_def={
  454. description = S(cdef.description:gsub("^%l", string.upper).." powder"),
  455. inventory_image = powder_png,
  456. groups = {flammable = 2,food_grain_powder=1},
  457. plant_name=cdef.plant_name,
  458. }
  459. if cdef.eat_hp then
  460. powder_def.on_use=minetest.item_eat(cdef.eat_hp)
  461. powder_def.groups["eatable"]=cdef.eat_hp
  462. end
  463. minetest.register_craftitem(":" .. cdef.coffeepowder, powder_def)
  464. minetest.register_craft({
  465. type = "shapeless",
  466. output = cdef.coffeepowder,
  467. recipe = {cdef.roast,
  468. farming.modname..":coffee_grinder"},
  469. replacements = {{"group:food_coffee_grinder", farming.modname..":coffee_grinder"}},
  470. })
  471. -- print("time register coffee "..1000*(os.clock()-starttime))
  472. end
  473. -- registering roast items if needed for plant
  474. function farming.register_roast(rdef)
  475. local starttime=os.clock()
  476. if not rdef.seed_name then
  477. return
  478. end
  479. if not rdef.roast then
  480. return
  481. end
  482. local roastitem=rdef.roast
  483. -- if no roast defined in config, register an own roast item
  484. if minetest.registered_craftitems[roastitem] == nil then
  485. local roast_png = roastitem:gsub(":","_")..".png"
  486. local rn = roastitem:split(":")[2]
  487. rn=rn:gsub("_"," ")
  488. local roast_def={
  489. description = S(rdef.description:gsub("^%l", string.upper)),
  490. inventory_image = roast_png,
  491. groups = {flammable = 2},
  492. plant_name=rdef.plant_name,
  493. }
  494. if rdef.groups.seed_roastable then
  495. roast_def.groups["seed_roastable"] = rdef.groups.seed_roastable
  496. end
  497. if rdef.eat_hp then
  498. roast_def.on_use=minetest.item_eat(rdef.eat_hp*2)
  499. roast_def.groups["eatable"]=rdef.eat_hp*2
  500. end
  501. minetest.register_craftitem(":" .. roastitem, roast_def)
  502. end
  503. local cooktime = 3
  504. if rdef.groups.seed_roastable then
  505. cooktime = rdef.groups.seed_roastable
  506. end
  507. local seedname=rdef.seed_name
  508. if rdef.seed_drop ~= nil then
  509. seedname=rdef.seed_drop
  510. end
  511. minetest.register_craft({
  512. type = "cooking",
  513. cooktime = cooktime or 3,
  514. output = roastitem,
  515. recipe = seedname
  516. })
  517. -- print("time register roast "..1000*(os.clock()-starttime))
  518. end
  519. -- registering grind items
  520. function farming.register_grind(rdef)
  521. local starttime=os.clock()
  522. if rdef.seed_name == nil then
  523. return
  524. end
  525. if rdef.step_name == nil then
  526. return
  527. end
  528. local grinditem = rdef.step_name.."_flour"
  529. if rdef.grind then
  530. grinditem = rdef.grind
  531. end
  532. local desc = grinditem:split(":")[2]
  533. desc = desc:gsub("_"," ")
  534. local grind_png = grinditem:gsub(":","_")..".png"
  535. local grind_def={
  536. description = S(desc:gsub("^%l", string.upper).." roasted"),
  537. inventory_image = grind_png,
  538. groups = {flammable = 2},
  539. plant_name=rdef.plant_name,
  540. }
  541. if rdef.eat_hp then
  542. grind_def.on_use=minetest.item_eat(rdef.eat_hp)
  543. grind_def.groups["eatable"]=rdef.eat_hp
  544. end
  545. minetest.register_craftitem(":" .. grinditem, grind_def)
  546. minetest.register_craft({
  547. type = "shapeless",
  548. output = grinditem,
  549. recipe = {rdef.seed_name.." "..rdef.groups["seed_grindable"],
  550. farming.modname..":mortar_pestle"},
  551. replacements = {{"group:food_mortar_pestle", farming.modname..":mortar_pestle"}},
  552. })
  553. -- print("time register grind "..1000*(os.clock()-starttime))
  554. end
  555. farming.trellis_seed = function(gdef)
  556. if gdef.seed_name == nil then
  557. return
  558. end
  559. if gdef.harvest_name == nil then
  560. return
  561. end
  562. minetest.register_craft({
  563. type = "shapeless",
  564. output = gdef.seed_name.." 1",
  565. recipe = {
  566. farming.modname..":trellis",gdef.harvest_name
  567. },
  568. })
  569. end
  570. -- local starttime=os.clock()
  571. -- print("time define infect "..1000*(os.clock()-starttime))