#4 implement infection based on local condition of crop

master
A. Demant 2018-10-24 06:51:12 +02:00
parent 1a3ce76ed4
commit b5e8d7d2b2
5 changed files with 126 additions and 156 deletions

View File

@ -20,8 +20,8 @@ end
-- rarety of crops on map, default is 0.001 (higher number = more crops)
farming.rarety = farming.config:get_float("rarety") or 0.002
-- random waiting time for growing
farming.wait_min = farming.config:get_int("wati_min") or 40
farming.wait_max = farming.config:get_int("wati_max") or 80
farming.wait_min = farming.config:get_int("wati_min") or 20
farming.wait_max = farming.config:get_int("wati_max") or 40
farming.wilt_removal_time = wilt_removal_time or 60
farming.wilt_time = 5
farming.min_light = 14

View File

@ -28,6 +28,7 @@ Actual columns:
infectable void
any value the plant can be infected, where the crop does not give any seed or harvest
and may infect other crops nearby
Higher values means more infectable
wiltable void
1 Wilt is going one step back, like Berries: They loose the fruits, but grow again
2 Plant wilt and remove itself after time. During wilt you can harvest straw if defined.

View File

@ -1,5 +1,5 @@
name,enabled,next_plant,rarety,steps,harvest_max,eat_hp,to_culture,to_dig,has_harvest,on_soil,punchable,wiltable,infectable,infection_defence,seed_extractable,no_seed,use_flail,use_trellis,for_coffee,seed_roastable,seed_grindable,for_flour,snappy,damage_per_second,liquid_viscosity,temperature_min,temperature_max,humidity_min,humidity_max,elevation_min,elevation_max,light_min,light_max,infect_rate_base,infect_rate_monoculture,spread_rate,grow_time_mean,wilt_time,straw,culture_rate,seed_drop,grind,roast
default,1,,10,8,2,1,,,,,,,,,,,,,,,,,3,,,15,80,10,80,0,200,11,14,1E-05,0.001,0.0001,12,,,,,,
default,1,,10,8,2,1,,,,,,,,,,,,,,,,,3,,,15,80,10,80,0,200,11,14,10,5,0.0001,12,,,,,,
barley,1,,10,7,2,,,,1,1,,2,1,,,,1,,1,3,,1,3,,2,25,,30,,,,,,,,,,,farming:straw,,,farming:flour,
beetroot,1,,10,5,2,2,,1,,1,,,,,,,,,,,,,3,,,35,,30,,,,9,,,,,,,,,,,
blackberry,1,,10,4,2,1,,,,,1,1,,,,,,,,,,,3,1,5,,90,20,,,,9,,,,,,,,,,,
@ -9,12 +9,12 @@ chili,1,,20,8,2,1,,,,,1,,,,,,,,,,,,3,,,45,90,,,,1000,,,,,,,,,,,,
coffee,1,,20,5,2,1,,,,,1,,,,,,,,1,4,,,3,,,50,120,50,150,,1000,12,,,,,,,,,,,
corn,1,,10,8,2,2,,,,1,,2,1,,,,,,,4,1,,3,,2,35,90,30,,,,,,,,,,,,,,,farming:corn_cob
cotton,1,,10,8,2,,,,1,1,,,1,,,,1,,,,,,3,,2,45,90,20,,,,12,,,,,,,,,,,
culturewheat,1,,100,4,3,,1,,1,1,,2,1,,,,1,,1,3,,1,3,,2,25,,40,,,,10,,,,,100,5,farming:straw,,,farming:flour,
culturewheat,1,,100,4,3,,1,,1,1,,2,2,,,,1,,1,3,,1,3,,2,25,,40,,,,10,,,,,100,5,farming:straw,,,farming:flour,
flax,,,10,7,2,,,,1,1,,,1,,,,1,,,,,,3,,,25,,30,,,,,,,,,,,farming:flaw,,,,
garlic,,,10,5,2,1,,1,,1,,,,,,,,,,3,,,3,,,,,,,,,,,,,,,,,,,,
grapes,1,,10,8,3,2,1,,,1,1,,1,,,,,1,,,,,3,,3,,,,,,,,,,,,,,,,farming:seed_wildgrapes,,
hemp,1,,10,8,2,,,,1,,,,,,,,1,,,,,,3,,2,,120,,,,,8,,,,1E-05,9,,farming:hemp_fibre,,,,
hop,1,,10,7,3,1,1,,,1,1,2,1,,,,,1,,4,,,3,,,,,,,,,,,,,,,,,,farming:seed_wildhop,,
hop,1,,10,7,3,1,1,,,1,1,2,2,,,,,1,,4,,,3,,,,,,,,,,,,,,,,,,farming:seed_wildhop,,
mustard,1,,10,5,2,,,,,,,,1,,,,,,,,2,,3,,,,,,,,,,,,,,,,,,,,
potato,1,,10,4,2,2,,,,1,,2,1,,,,,,,4,1,,3,,,,,,,,,,,,,,,,,,,,farming:potato_baked
raspberry,1,,10,4,2,1,,,,,1,1,,,,,,,,,,,3,1,5,,,,,,,9,,,,,,,,,,,

View File

@ -48,10 +48,39 @@ minetest.register_lbm({
})
minetest.register_abm({
label="crops getting ill",
nodenames="group:infectable",
intervall = 5,
change=1,
action = function(pos)
local node=minetest.get_node(pos)
print(dump(node))
if node.name == "air" or node.name == "ignore" then
return
end
local ndef = minetest.registered_nodes[node.name]
if ndef.groups.infectable == nil then
return
end
local meta = minetest.get_meta(pos)
local ill_rate=meta:get_int("farming:weakness")
if ill_rate == nil then
return
end
print(ill_rate)
-- if math.random(1,ill_rate)==1 then
farming.plant_infect(pos)
print("infect at "..dump(pos))
-- end
end
})
minetest.register_abm({
label="Planting crops",
nodenames = farming.change_soil,
neighbors = {"air"},
interval = 15+math.random(-1,1), -- little noise
chance = 2,
chance = 200,
action = function(pos)
local ptabove={x=pos.x,y=pos.y+1,z=pos.z}
local above = minetest.get_node(ptabove)
@ -77,7 +106,7 @@ minetest.register_abm({
return
end
end
if math.random(0,100) < 1 then
-- if math.random(0,100) < 1 then
local node_temp=minetest.get_heat(pos)
local node_hum=minetest.get_humidity(pos)
local sc={}
@ -96,23 +125,11 @@ minetest.register_abm({
end
if #sc > 0 then
local rand_plant = math.random(1,#sc)
-- print(sc[rand_plant])
--[[
local pdef = minetest.registered_nodes[ sc[rand_plant] ]
local day_start=99999
local light_amount=0
for i=50,120 do
if minetest.get_node_light(ptabove,(i)/240)>pdef.light_min then
light_amount=light_amount+minetest.get_node_light(ptabove,i/240)
day_start=math.min(day_start,i)
end
end
print(pdef.light_min,day_start,light_amount)
]]
minetest.add_node(ptabove, {name=sc[rand_plant],param2=1})
minetest.get_node_timer(ptabove):start(math.random(10, 15))
farming.set_node_metadata(ptabove)
end
end
-- end
end,
})
--print(dump(farming.spreading_crops))

View File

@ -82,7 +82,6 @@ farming.register_plant = function(def)
if def.groups["wiltable"] == 2 then
def.wilt_name=def.mod_name..":wilt_"..def.name
print(def.wilt_name)
farming.register_wilt(def)
end
farming.registered_plants[def.name] = def
@ -114,8 +113,6 @@ farming.register_plant = function(def)
farming.seed_craft(def)
end
if def.groups["use_trellis"] then
print(dump(def))
-- print(dump(def))
farming.trellis_seed(def)
end
if def.groups["seed_grindable"] then
@ -213,6 +210,7 @@ farming.register_infect=function(idef)
infect_def.groups = {snappy = 3, attached_node = 1, flammable = 2,infect=2}
infect_def.groups["step"] = -1
infect_def.groups[idef.plant_name] = 0
minetest.register_node(":" .. idef.name.."_infected", infect_def)
end
farming.register_wilt=function(idef)
@ -247,7 +245,6 @@ end
farming.register_seed=function(sdef)
-- print(sdef.name:gsub("^%l", string.upper))
local seed_def = {
description=S(sdef.name:gsub("^%l", string.upper).." Seed"),
drawtype = "signlike",
@ -268,7 +265,6 @@ farming.register_seed=function(sdef)
on_place = farming.seed_on_place,
on_timer = farming.seed_on_timer,
}
-- print(seed_def.description)
for i,colu in ipairs({"place_param2","fertility","plant_name","seed_name","grow_time_min","grow_time_max","light_min"}) do
seed_def[colu] = sdef[colu]
end
@ -290,7 +286,6 @@ farming.register_seed=function(sdef)
if sdef.eat_hp then
seed_def.on_use=minetest.item_eat(sdef.eat_hp)
end
-- print(dump(seed_def))
minetest.register_node(":" .. sdef.seed_name, seed_def)
end
@ -357,6 +352,7 @@ farming.register_steps = function(sdef)
end
ndef.groups["step"] = i
ndef.groups[sdef.mod_name]=1
ndef.groups[sdef.plant_name]=1
ndef.tiles={sdef.mod_name.."_"..sdef.plant_name.."_"..i..".png"}
if i < sdef.steps then
ndef.groups["farming_grows"]=1 -- plant is growing
@ -416,7 +412,6 @@ farming.register_steps = function(sdef)
ndef.groups["farming_fullgrown"]=1
ndef.on_dig = farming.harvest_on_dig
if sdef.groups.wiltable ~= nil then
print(sdef.wilt_name)
if sdef.groups.wiltable == 2 then
ndef.next_step=sdef.wilt_name
end
@ -426,7 +421,6 @@ farming.register_steps = function(sdef)
if sdef.groups.wiltable == 3 then
ndef.pre_step = sdef.step_name .. "_" .. (i - 1)
end
print(sdef.wilt_name)
ndef.on_timer = farming.step_on_timer
if sdef.groups.wiltable == 3 then
ndef.on_timer = farming.wilt_on_timer
@ -443,130 +437,12 @@ farming.register_steps = function(sdef)
end
if i == sdef.steps and is_punchable and i > 1 then
ndef.pre_step = sdef.step_name .. "_" .. (i - 1)
-- print(ndef.pre_step)
ndef.on_punch = farming.step_on_punch
end
-- print(dump(ndef))
minetest.register_node(":" .. ndef.description, ndef)
end
-- farming.register_lbm(lbm_nodes,sdef)
end
farming.register_lbm = function(lbm_nodes,def)
-- replacement LBM for pre-nodetimer plants
minetest.register_lbm({
name = ":" .. def.mod_name .. ":start_nodetimer_" .. def.plant_name,
nodenames = lbm_nodes,
action = function(pos, node)
minetest.get_node_timer(pos):start(math.random(farming.wait_min,farming.wait_max))
end,
})
end
farming.register_abm = function(mdef)
local rand_change = 50
if mdef.spread then
if mdef.spread.base_rate then
rand_change = mdef.spread.base_rate
end
end
if mdef.spread then
-- random spread of plant on surface.
minetest.register_abm({
nodenames = mdef.spread.spreadon,
neighbors = {"air"},
interval = mdef.spread.intervall+math.random(-1,1), -- little noise
chance = rand_change,
action = function(pos)
local ptabove={x=pos.x,y=pos.y+1,z=pos.z}
local above = minetest.get_node(ptabove)
if above.name ~= "air" then
return
end
if minetest.get_node_light(ptabove) < mdef.minlight then
return
end
local ymin=0
local ymax=31000
if mdef.spawnon then
ymin=mdef.spawnon.spawn_min or 0
ymax=mdef.spawnon.spawn_max or 31000
end
if (ptabove.y < ymin or ptabove.y > ymax ) then
return
end
local pos0 = vector.subtract(pos,4)
local pos1 = vector.add(pos,4)
-- only for positions, where not too many plants are nearby
if #minetest.find_nodes_in_area(pos0,pos1,"group:"..mdef.plant_name) > 2 then
return
end
if math.random(0,mdef.spread.inv_change) < 1 then
minetest.add_node(ptabove, {name=mdef.harvest_name.."_1"})
minetest.get_node_timer(pos):start(math.random(mdef.min_grow_time or 100, mdef.max_grow_time or 200))
end
end,
})
-- spread for full-grown plant
minetest.register_abm({
nodenames =mdef.spread.spreadon ,
neighbours=mdef.harvest_name.."_"..mdef.steps,
interval = mdef.spread.intervall + math.random(-1,1), --little noise
chance = mdef.spread.spread,
action = function(pos)
local ptabove={x=pos.x,y=pos.y+1,z=pos.z}
local above = minetest.get_node(ptabove)
if above.name ~= "air" then
return
end
if minetest.get_node_light(ptabove) < mdef.minlight then
return
end
local ymin=0
local ymax=31000
if mdef.spawnon then
ymin=mdef.spawnon.spawn_min or 0
ymax=mdef.spawnon.spawn_max or 31000
end
if (ptabove.y < ymin or ptabove.y > ymax ) then
return
end
if math.random(0,mdef.spread.inv_change) < 1 then
minetest.add_node(ptabove, {name=mdef.harvest_name.."_1"})
minetest.get_node_timer(pos):start(math.random(mdef.min_grow_time or 100, mdef.max_grow_time or 200))
end
end,
})
end
end
farming.register_mapgen = function(mdef)
-- register mapgen
if mdef.groups.to_culture == nil then
local deco_def={
deco_type = "simple",
place_on = mdef.spawnon,
sidelen = 16,
noise_params = {
offset = 0.012,
scale = 0.006,
spread = {x = 200, y = 200, z = 200},
seed = 329,
octaves = 3,
persist = 0.6
},
y_min = mdef.elevation_min,
y_max = mdef.elevation_max,
decoration = mdef.wildname or mdef.step_name.."_"..mdef.steps,
-- spawn_by = mdef.spawnon.spawnby,
-- num_spawn_by = mdef.spawnon.spawn_num,
-- biomes = farming.get_biomes(def)
}
minetest.register_decoration(deco_def)
-- end
end
end
farming.register_billhook = function(name,def)
if not def.groups["billhook"] then
def.groups["billhook"]=1
@ -642,12 +518,13 @@ farming.plant_infect = function(pos)
local node = minetest.get_node(pos)
local name = node.name
local def = minetest.registered_nodes[name]
local infect_name=def.plant.."_infected"
-- print(dump(def))
local infect_name=def.plant_name.."_infected"
if not minetest.registered_nodes[infect_name] then
return
end
local meta = minetest.get_meta(pos)
meta:set_int("farming:step",def.groups["step"])
-- meta:set_int("farming:step",def.groups["step"])
local placenode = {name = infect_name}
if def.place_param2 then
placenode.param2 = def.place_param2
@ -662,9 +539,7 @@ farming.plant_cured = function(pos)
local def = minetest.registered_nodes[name]
local meta = minetest.get_meta(pos)
local cured_step=meta:get_int("farming:step")
-- print(cured_step)
local cured_name=def.step_name.."_"..cured_step
-- print(cured_name)
if not minetest.registered_nodes[cured_name] then
return
end
@ -720,6 +595,49 @@ farming.harvest_on_dig = function(pos, node, digger)
minetest.node_dig(pos,node,digger)
end
farming.infect_on_timer = function(pos,elapsed)
local node = minetest.get_node(pos)
local def = minetest.registered_nodes[node.name]
local meta = minetest.get_meta(pos)
local actual_step=meta:get_int("farming:step")
if actual_step == nil then
minetest.swap_node(pos, {name="air"})
return
end
if actual_step == 0 then
print("plant dies")
minetest.swap_node(pos, {name="air"})
return
end
local infected = 0
if def.infect_rate_monoculture ~= nil then
local monoculture=minetest.find_nodes_in_area(vector.subtract(pos,2),vector.add(pos,2),"group:"..def.plant_name)
if monoculture ~= nil then
for i = 1,#monoculture do
if math.random(1,max(2,def.infect_rate_monoculture))==1 then
farming.plant_infect(monoculture[i])
print("infection spread")
infected=infected+1
end
end
end
end
if infected == 0 then
local culture=minetest.find_nodes_in_area(vector.subtract(pos,3),vector.add(pos,3),"group:infectable")
if culture ~= nil then
for i = 1,#culture do
if math.random(1,max(2,def.infect_rate_base))==1 then
farming.plant_infect(culture[i])
print("infection spread")
infected=infected+1
end
end
end
end
meta:set_int("farming:step",actual_step-1)
minetest.get_node_timer(pos):start(math.random(farming.wait_min,farming.wait_max))
end
farming.step_on_timer = function(pos, elapsed)
local node = minetest.get_node(pos)
local name = node.name
@ -839,6 +757,7 @@ farming.place_seed = function(itemstack, placer, pointed_thing, plantname)
minetest.get_node_timer(pt.above):start(math.random(wait_min, wait_max))
local meta = minetest.get_meta(pt.above)
meta:set_int("farming:step",0)
farming.set_node_metadata(pt.above)
if not (creative and creative.is_enabled_for
and creative.is_enabled_for(player_name)) then
itemstack:take_item()
@ -1074,8 +993,6 @@ function farming.register_roast(rdef)
if rdef.eat_hp then
roast_def.on_use=minetest.item_eat(rdef.eat_hp*2)
end
-- print(roastitem)
-- print(dump(roast_def))
minetest.register_craftitem(":" .. roastitem, roast_def)
@ -1102,7 +1019,6 @@ function farming.register_grind(rdef)
if rdef.grind then
grinditem = rdef.grind
end
-- print(grinditem)
local desc = grinditem:split(":")[2]
desc = desc:gsub("_"," ")
local mname = minetest.get_current_modname()
@ -1192,9 +1108,45 @@ farming.billhook_on_use = function(itemstack, user, pointed_thing, uses)
end
farming.set_node_metadata=function(pos)
local base_rate = 5
local node = minetest.get_node(pos)
local def = minetest.registered_nodes[node.name]
local pdef = farming.registered_plants[def.plant_name]
local ill_rate=(pdef.light_max-minetest.get_node_light(pos,0.5))/(pdef.light_max-pdef.light_min)
local ill_rate=base_rate * (pdef.light_max-minetest.get_node_light(pos,0.5))/(pdef.light_max-pdef.light_min)
-- calc coeff for temperature
local ill_temp=(base_rate * math.sqrt(math.min(minetest.get_heat(pos)-pdef.temperature_min,pdef.temperature_max-minetest.get_heat(pos))/(pdef.temperature_max-pdef.temperature_min)))
-- negative coeff means, it is out of range
if ill_temp < 0 then
ill_temp = (ill_temp * (-0.75))
end
-- calc coeff for humidity
local ill_hum=(base_rate * math.sqrt(math.min(minetest.get_humidity(pos)-pdef.humidity_min,pdef.humidity_max-minetest.get_humidity(pos))/(pdef.humidity_max-pdef.humidity_min)))
-- negative coeff means, it is out of range
if ill_hum < 0 then
ill_hum = (ill_hum * (-0.75))
end
local infect_rate = 1
if pdef.groups.infectable then
infect_rate = pdef.groups.infectable
end
ill_rate = math.ceil((ill_rate + ill_temp + ill_hum)/infect_rate)
local meta = minetest.get_meta(pos)
meta:set_int("farming:weakness",ill_rate)
-- calculating
local day_start=99999
local light_amount=0
for i=50,120 do
if minetest.get_node_light(pos,(i)/240)>pdef.light_min then
light_amount=light_amount+minetest.get_node_light(pos,i/240)
day_start=math.min(day_start,i)
end
end
if day_start > 240 then
day_start=120
end
-- daytime, when light reach light_min
meta:set_float("farming:daystart",day_start/240)
-- amount of light the crop gets till midday
meta:set_int("farming:lightamount",light_amount)
end