--function forestry_bees.Bee(bee_type,active_type_gene,inactive_type_gene,active_fertility_gene,inactive_fertility_gene) --local itemstack = ItemStack({name = forestry_bees.bee_name(bee_type,active_type_gene)}) --itemstack:get_meta():set_string("active_type_gene",active_type_gene) --itemstack:get_meta():set_string("inactive_type_gene",inactive_type_gene) --itemstack:get_meta():set_string("active_fertility_gene",active_fertility_gene) --itemstack:get_meta():set_string("inactive_fertility_gene",inactive_fertility_gene) --return itemstack --end function forestry_bees.Bee(bee_type,genes) local itemstack = ItemStack({name = forestry_bees.bee_name(bee_type,genes["type_gene"][1])}) --the "1" is cuz the table genes["type_gene"] has 2 entries: active and inactive itemstack:get_meta():set_string("genes", minetest.serialize(genes)) --for gene_type,gene in pairs(genes) do -- itemstack:get_meta():set_string(gene_type,gene) --end return itemstack end function forestry_bees.can_queen_work(queen, pos) local genes = minetest.deserialize(queen:get_meta():get_string("genes")) local biome_data = minetest.get_biome_data(pos) local biome_name = minetest.get_biome_name(biome_data["biome"]) local humidity = biome_data["humidity"] local heat = biome_data["heat"] --now get the environmental data local is_right_heat = true --futureproofing local is_right_humidity = true --futureproofing local is_right_biome = true --futureproofing local is_sky_access = (genes["cave"][1] or (minetest.get_natural_light(vector.offset(pos, 0, 1, 0), 0.5) == 15)) local is_not_raining = (genes["flyer"][1] or true) --would require additional mods local is_day = (genes["nocturnal"][1] or ((0.25 < minetest.get_timeofday()) and (minetest.get_timeofday() < 0.75))) return is_sky_access and is_not_raining and is_day end function forestry_bees.calculate_drop(bee) local genes = minetest.deserialize(bee:get_meta():get_string("genes")) local possible_drops = forestry_bees.bee_drops[genes["type_gene"][1]] --this gets us a table local out_table = {} for drop,chance in pairs(possible_drops) do if math.random() < chance * genes["production"][1] then --the prob of getting something is P = (base chance from bee_drops) * (item modifier (frames and stuff)) * (bee production gene) table.insert(out_table,ItemStack(drop)) end end return out_table end function forestry_bees.bee_name(bee_type,active_type_gene) return "forestry_bees:"..active_type_gene.."_"..bee_type end function forestry_bees.stacks_in_inv(inv,listname) local stack_list = inv:get_list(listname) local result = 0 for i = 1,#stack_list do if not stack_list[i]:is_empty() then result = result + 1 end end return result end function forestry_bees.format_bee(bee) local name = bee:get_name() local meta = bee:get_meta() local genes = forestry_bees.return_all_genes_double(string.sub(string.match(string.match(name,":.*"),".*_"),2,-2)) return forestry_bees.Bee(string.sub(string.match(string.sub(string.match(name,"_.*"),2),"_.*"),2),genes) end function forestry_bees.breed_princess_drone(princess,drone) local princess_genes = minetest.deserialize(princess:get_meta():get_string("genes")) --princess_meta["genes"] local drone_genes = minetest.deserialize(drone:get_meta():get_string("genes")) --fix for missing genes in bees, if we have bees with missing genes we just give them the default ones if princess_genes == nil then local princess_type = string.sub(string.match(string.match(princess:get_name(),":.*"),".*_"),2,-2) princess_genes = forestry_bees.return_all_genes_double(princess_type) end if drone_genes == nil then local drone_type = string.sub(string.match(string.match(drone:get_name(),":.*"),".*_"),2,-2) drone_genes = forestry_bees.return_all_genes_double(drone_type) end local queen = forestry_bees.Bee("queen",princess_genes) local queen_meta = queen:get_meta() queen_meta:set_string("drone_genes",minetest.serialize(drone_genes)) return queen end local function final_gene(gene1,gene2) local output = {} --randomly choose if the genes are 1,2 or 2,1 if math.random(2)==2 then output[1] = gene1 output[2] = gene2 else output[1] = gene2 output[2] = gene1 end return output end local function mutation(type1,type2,pos) local out_table1 = {} local out_table2 = {} local mutation = {false, false} --check every possible mutation to see if we may obtain it if ( (not (forestry_bees.bee_mutations[type1] == nil)) and (not (forestry_bees.bee_mutations[type1][type2] == nil)) ) then for out_type, t in pairs(forestry_bees.bee_mutations[type1][type2]) do local prob1 = math.random() local prob2 = math.random() local flag = t["check_fun"](pos) if (t["chance"] > prob1) and flag then table.insert(out_table1, out_type) end if (t["chance"] > prob2) and flag then table.insert(out_table2, out_type) end end end local output = final_gene(type1,type2) if next(out_table1) then --if a mutation accurred in gene 1 mutation[1] = true output[1] = out_table1[math.random(#out_table1)] end if next(out_table2) then --if a mutation accurred in gene 2 mutation[2] = true output[2] = out_table2[math.random(#out_table2)] end --out_table is always non-empty, now we uniformally --sample from out_table to get the output gene return output, mutation end local function choose_genes(genes) --from the table "genes" we for each entry randomly choose 1,2 and keep that gene --returning a table local output = {} for key,gene_pair in pairs(genes) do output[key] = gene_pair[math.random(2)] end return output end local function output_genes(mother_genes,father_genes,pos) local mother_chosen_genes = choose_genes(mother_genes) local father_chosen_genes = choose_genes(father_genes) local genes = {} genes["type_gene"], is_mutated = mutation(mother_chosen_genes["type_gene"], father_chosen_genes["type_gene"],pos) for key,_ in pairs(mother_chosen_genes) do --if key == "type_gene" then -- genes[key] = mutation(mother_chosen_genes[key], father_chosen_genes[key]) if not (key == "type_gene") then genes[key] = final_gene(mother_chosen_genes[key], father_chosen_genes[key]) end end --if a mutation occurred we change the corresponding genes to the base_genes of the mutated bee if is_mutated[1] then for key,value in pairs(forestry_bees.return_genes(genes["type_gene"][1])) do genes[key][1] = value end end if is_mutated[2] then for key,value in pairs(forestry_bees.return_genes(genes["type_gene"][2])) do genes[key][2] = value end end return genes end function forestry_bees.apiary_result(queen, pos) --given a queen calculates the correct princess + drone output local meta = queen:get_meta() local mother_genes = minetest.deserialize(meta:get_string("genes")) local father_genes = minetest.deserialize(meta:get_string("drone_genes")) local genes = output_genes(mother_genes,father_genes,pos) --local genes = final_gene(mother_chosen_gene, father_chosen_gene) local princess = forestry_bees.Bee("princess", genes) local dronelist = {} local fertility = mother_genes["fertility"][1] for i=1,fertility do local genes = output_genes(mother_genes,father_genes,pos) local drone = forestry_bees.Bee("drone", genes) table.insert(dronelist, drone) end return princess, dronelist end