2024-10-08 22:14:20 +02:00
--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
2024-10-07 14:31:20 +02:00
return itemstack
end
2024-10-09 22:06:52 +02:00
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
2024-10-08 16:37:23 +02:00
local out_table = { }
for drop , chance in pairs ( possible_drops ) do
2024-10-09 22:06:52 +02:00
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)
2024-10-08 16:37:23 +02:00
table.insert ( out_table , ItemStack ( drop ) )
end
end
return out_table
end
2024-10-08 22:14:20 +02:00
function forestry_bees . bee_name ( bee_type , active_type_gene )
return " forestry_bees: " .. active_type_gene .. " _ " .. bee_type
2024-10-07 14:31:20 +02:00
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
2024-10-07 19:52:09 +02:00
end
2024-10-11 19:39:04 +02:00
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
2024-10-07 19:52:09 +02:00
function forestry_bees . breed_princess_drone ( princess , drone )
2024-10-08 22:14:20 +02:00
--local princess_meta = princess:get_meta()
local princess_genes = minetest.deserialize ( princess : get_meta ( ) : get_string ( " genes " ) ) --princess_meta["genes"]
--local drone_meta = drone:get_meta()
local drone_genes = minetest.deserialize ( drone : get_meta ( ) : get_string ( " genes " ) )
local queen = forestry_bees.Bee ( " queen " , princess_genes )
2024-10-07 19:52:09 +02:00
local queen_meta = queen : get_meta ( )
2024-10-08 22:14:20 +02:00
queen_meta : set_string ( " drone_genes " , minetest.serialize ( drone_genes ) )
2024-10-07 19:52:09 +02:00
return queen
end
2024-10-08 22:14:20 +02:00
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
2024-10-11 19:39:04 +02:00
local function mutation ( type1 , type2 , pos )
2024-10-07 19:52:09 +02:00
local out_table1 = { }
local out_table2 = { }
2024-10-09 21:28:02 +02:00
local mutation = { false , false }
2024-10-07 19:52:09 +02:00
--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
2024-10-11 19:39:04 +02:00
for out_type , t in pairs ( forestry_bees.bee_mutations [ type1 ] [ type2 ] ) do
2024-10-07 19:52:09 +02:00
local prob1 = math.random ( )
local prob2 = math.random ( )
2024-10-11 19:39:04 +02:00
local flag = t [ " check_fun " ] ( pos )
if ( t [ " chance " ] > prob1 ) and flag then
2024-10-07 19:52:09 +02:00
table.insert ( out_table1 , out_type )
end
2024-10-11 19:39:04 +02:00
if ( t [ " chance " ] > prob2 ) and flag then
2024-10-07 19:52:09 +02:00
table.insert ( out_table2 , out_type )
end
end
end
2024-10-08 22:14:20 +02:00
local output = final_gene ( type1 , type2 )
2024-10-07 19:52:09 +02:00
if next ( out_table1 ) then --if a mutation accurred in gene 1
2024-10-09 21:28:02 +02:00
mutation [ 1 ] = true
2024-10-07 19:52:09 +02:00
output [ 1 ] = out_table1 [ math.random ( # out_table1 ) ]
end
if next ( out_table2 ) then --if a mutation accurred in gene 2
2024-10-09 21:28:02 +02:00
mutation [ 2 ] = true
2024-10-07 19:52:09 +02:00
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
2024-10-09 21:28:02 +02:00
return output , mutation
2024-10-07 19:52:09 +02:00
end
2024-10-08 22:14:20 +02:00
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
2024-10-11 19:39:04 +02:00
local function output_genes ( mother_genes , father_genes , pos )
2024-10-08 22:14:20 +02:00
local mother_chosen_genes = choose_genes ( mother_genes )
local father_chosen_genes = choose_genes ( father_genes )
local genes = { }
2024-10-09 21:28:02 +02:00
2024-10-11 19:39:04 +02:00
genes [ " type_gene " ] , is_mutated = mutation ( mother_chosen_genes [ " type_gene " ] , father_chosen_genes [ " type_gene " ] , pos )
2024-10-09 21:28:02 +02:00
2024-10-08 22:14:20 +02:00
for key , _ in pairs ( mother_chosen_genes ) do
2024-10-09 21:28:02 +02:00
--if key == "type_gene" then
-- genes[key] = mutation(mother_chosen_genes[key], father_chosen_genes[key])
if not ( key == " type_gene " ) then
2024-10-08 22:14:20 +02:00
genes [ key ] = final_gene ( mother_chosen_genes [ key ] , father_chosen_genes [ key ] )
end
end
2024-10-09 21:28:02 +02:00
--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
2024-10-08 22:14:20 +02:00
return genes
end
2024-10-11 19:39:04 +02:00
function forestry_bees . apiary_result ( queen , pos )
2024-10-07 19:52:09 +02:00
--given a queen calculates the correct princess + drone output
local meta = queen : get_meta ( )
2024-10-08 22:14:20 +02:00
local mother_genes = minetest.deserialize ( meta : get_string ( " genes " ) )
local father_genes = minetest.deserialize ( meta : get_string ( " drone_genes " ) )
2024-10-11 19:39:04 +02:00
local genes = output_genes ( mother_genes , father_genes , pos )
2024-10-08 22:14:20 +02:00
--local genes = final_gene(mother_chosen_gene, father_chosen_gene)
local princess = forestry_bees.Bee ( " princess " , genes )
2024-10-07 19:52:09 +02:00
local dronelist = { }
2024-10-08 22:14:20 +02:00
local fertility = mother_genes [ " fertility " ] [ 1 ]
for i = 1 , fertility do
2024-10-11 19:39:04 +02:00
local genes = output_genes ( mother_genes , father_genes , pos )
2024-10-08 22:14:20 +02:00
local drone = forestry_bees.Bee ( " drone " , genes )
2024-10-07 19:52:09 +02:00
table.insert ( dronelist , drone )
end
return princess , dronelist
end