Code refactoring, in-game docs, vanadium more common. Version 0.3

master
Alois Wohlschlager 2018-10-05 11:01:58 +02:00
parent a359d7e7e9
commit 9ad4b35bd9
11 changed files with 836 additions and 469 deletions

View File

@ -1,3 +1,8 @@
0.3:
* Extensive code refactoring to prepare for an API (which is already used internally, but unstable and not exposed at the moment)
* Added in-game documentation ("Old Alchemy Textbook")
* Made vanadium more common to better reflect the situation in real life
0.2:
* Water can now be crafted by burning hydrogen
* Updated README to reflect changes in the uses for some items

View File

@ -1,7 +1,7 @@
License for Code
----------------
Copyright (C) 2017 Alois Wohlschlager
Copyright (C) 2017, 2018 Alois Wohlschlager
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by

View File

@ -1,4 +1,4 @@
Adds ores, a lab, various lab equipment, chemicals and more tools, building materials and lights. The most comprehensive chemistry mod for Minetest.
Adds ores, a lab, various lab equipment, chemicals and more tools, building materials and lights. Very comprehensive chemistry mod for Minetest.
License: LGPLv2.1 or later for code, CC-BY-SA 3.0 for textures and sounds
@ -10,6 +10,7 @@ Other: copy the mod folder to minetest/mods/ in your installation folder
Dependencies: Nothing outside of the Minetest game, so everything needed should be already in place. We need only default, vessels, bucket and fire.
Mesecons will only add some support/compatibility features.
Minetest 0.4.17.1 is recommended.
Contact: alois1@gmx-topmail.de
@ -65,10 +66,11 @@ Misc
* Charcoal: Intermediate product to make coal from trees
* Compressed Coal: Make diamond renewable
* Refined lava: Make lava tools
* Old Alchemy Textbook: Contains all possible reactions (in-game documentation)
Tools
-----
* Lava pickaxe, shovel, axe and sword: Lava tools are like steel tools, but smelt dropped items, also the sword deals more damage
* Lava pickaxe, shovel, axe and sword: Lava tools are like steel tools, but smelt most dropped items (and turn wood into charcoal), also the sword deals more damage
* Stainless Steel pickaxe, shovel, axe and sword: More robust than steel tools
Blocks

111
book.lua Normal file
View File

@ -0,0 +1,111 @@
local pages = {}
local product_indexes = {}
local function representative(item_or_group_name)
if item_or_group_name:sub(1, 6) == "group:" then
local groupname = item_or_group_name:sub(7)
-- TODO this works well for the current purposes, but isn't robust at all
return "default:"..groupname
else
return item_or_group_name
end
end
local function reactant_name_count(page, index)
local reactants = reactions[page].reactants
if reactants[index] then
return representative(reactants[index]:get_name()).." "..reactants[index]:get_count()
else
return ""
end
end
local function catalyst_name(page)
local catalyst = reactions[page].catalyst
if catalyst then
return catalyst
else
return ""
end
end
local function tool_name(page)
local tool = reactions[page].tool
if tool then
return tool
else
return ""
end
end
local function product_name_count(page, product_index, index)
local output = reactions[page].possible_outputs[product_index]
if output then
if output.products[index] then
return representative(output.products[index]:get_name()).." "..output.products[index]:get_count()
else
return ""
end
else
return ""
end
end
local function book_formspec(page, product_index)
return
"size[8,4]"..
"label[1,0;Reactants "..page.."/"..#reactions.."]"..
"label[5,0;Products "..product_index.."/"..#reactions[page].possible_outputs..": p="..reactions[page].possible_outputs[product_index].probability.."]"..
"button[0,1;1,3;back;<]"..
"button[7,1;1,3;forward;>]"..
"item_image_button[1,1;1,1;"..reactant_name_count(page, 1)..";;]"..
"item_image_button[2,1;1,1;"..reactant_name_count(page, 2)..";;]"..
"item_image_button[1,2;1,1;"..reactant_name_count(page, 3)..";;]"..
"item_image_button[2,2;1,1;"..reactant_name_count(page, 4)..";;]"..
"item_image_button[1,3;1,1;"..reactant_name_count(page, 5)..";;]"..
"item_image_button[2,3;1,1;"..reactant_name_count(page, 6)..";;]"..
"item_image_button[3.5,1;1,1;"..catalyst_name()..";;]"..
"item_image_button[3.5,3;1,1;"..tool_name()..";;]"..
"item_image_button[5,1;1,1;"..product_name_count(page, product_index, 1)..";;]"..
"item_image_button[6,1;1,1;"..product_name_count(page, product_index, 2)..";;]"..
"item_image_button[5,2;1,1;"..product_name_count(page, product_index, 3)..";;]"..
"item_image_button[6,2;1,1;"..product_name_count(page, product_index, 4)..";;]"..
"item_image_button[5,3;1,1;"..product_name_count(page, product_index, 5)..";;]"..
"item_image_button[6,3;1,1;"..product_name_count(page, product_index, 6)..";;]"
end
function book_on_use(itemstack, user)
minetest.show_formspec(user:get_player_name(), "chemistry_book", book_formspec(1, 1))
end
minetest.register_on_player_receive_fields(function(player, formname, fields)
if formname ~= "chemistry_book" then
return
else
local page = pages[player:get_player_name()]
local product_index = product_indexes[player:get_player_name()]
if fields.back then
if product_index == 1 then
page = page - 1
product_index = #reactions[page].possible_outputs
else
product_index = product_index - 1
end
elseif fields.forward then
if product_index == #reactions[page].possible_outputs then
page = page + 1
product_index = 1
else
product_index = product_index + 1
end
end
if page == 0 then
page = #reactions
elseif page == #reactions + 1 then
page = 1
end
pages[player:get_player_name()] = page
product_indexes[player:get_player_name()] = product_index
minetest.show_formspec(player:get_player_name(), "chemistry_book", book_formspec(page, product_index))
end
end)

View File

@ -270,6 +270,12 @@ minetest.register_craft({
recipe = {"default:lava_source", "default:steel_ingot"}
})
minetest.register_craft({
type = "shapeless",
output = "chemistry:book",
recipe = {"default:book", "chemistry:sulfur_lump"}
})
-- Mesecon compatibility/support
if minetest.get_modpath("mesecons") ~= nil then
minetest.register_craft({

View File

@ -147,3 +147,13 @@ minetest.register_craftitem("chemistry:refined_lava", {
description = "Refined Lava",
inventory_image = "chemistry_refined_lava.png",
})
minetest.register_craftitem("chemistry:book", {
description = "Old Alchemy Textbook",
inventory_image = "chemistry_book.png",
stack_max = 1,
groups = {book = 1},
on_use = function(itemstack, user)
book_on_use(itemstack, user)
end,
})

View File

@ -1,11 +1,20 @@
-- No API is exported yet, as it's unstable
chemistry = {}
local chemistry_path=minetest.get_modpath("chemistry")
--[[
Dependencies:
reactions > lab
book > lab
craftitems > book
]]--
dofile(chemistry_path.."/nodes.lua")
dofile(chemistry_path.."/craftitems.lua")
dofile(chemistry_path.."/ores.lua")
dofile(chemistry_path.."/tools.lua")
dofile(chemistry_path.."/lab.lua")
dofile(chemistry_path.."/reactions.lua")
dofile(chemistry_path.."/crafting.lua")
dofile(chemistry_path.."/abm.lua")
dofile(chemistry_path.."/book.lua")
dofile(chemistry_path.."/craftitems.lua")

672
lab.lua
View File

@ -1,5 +1,5 @@
local formspec =
"size[8,8.5]"..
"size[8,8.5]"..
default.gui_bg..
default.gui_bg_img..
default.gui_slots..
@ -19,6 +19,77 @@ local formspec =
"listring[current_player;main]"..
default.get_hotbar_bg(0, 4.25)
EPSILON = 1e-7
reactions = {}
--[[
This is how a formula looks like:
{
tool: (itemstring of tool needed for the reaction, or nil)
catalyst: (--"--)
reactants: {
(ItemStack's of up to six reactants, indexes more than six are silently ignored; no duplicate itemstrings please)
}
possible_outputs: {
{
probability: (...)
products: {
(ItemStack's of up to six products)
}
}
}
sound: (description of a sound to be played, or nil)
}
--]]
function register_reaction(formula)
local err = false
-- Basic checks of formula
if formula.reactants == nil then
minetest.log("error", "No reactants supplied to register_reaction() (nil)")
err = true
end
if #formula.reactants == 0 then
minetest.log("error", "No reactants supplied to register_reaction() (empty)")
err = true
end
local reactant_count = 0
for i=1, 6 do
if not (formula.reactants[i] == nil) then
reactant_count = reactant_count + 1
end
end
if not (#formula.reactants == reactant_count) then
minetest.log("error", "Extra reactants supplied to register_reaction() ")
err = true
end
if formula.possible_outputs == nil then
minetest.log("error", "No possible outputs supplied to register_reaction() (nil)")
err = true
end
if #formula.possible_outputs == 0 then
minetest.log("error", "No possible outputs supplied to register_reaction() (empty)")
err = true
end
local total_probability = 0.0
for i=1, #formula.possible_outputs do
local output = formula.possible_outputs[i]
if output.probability <= 0 or output.probability > 1 then
minetest.log("error", "Invalid probability for output supplied to register_reaction()")
err = true
end
total_probability = total_probability + output.probability
end
if math.abs(total_probability - 1.0) > EPSILON then
minetest.log("error", "Probabilities which do not sum to one supplied to register_reaction()")
err = true
end
if not err then
reactions[#reactions + 1] = formula
end
end
local function can_dig(pos, player)
local meta = minetest.get_meta(pos);
local inv = meta:get_inventory()
@ -56,12 +127,20 @@ local function allow_metadata_inventory_take(pos, listname, index, stack, player
return stack:get_count()
end
local function reaction_possible(pos)
local function reaction_possible(pos, products)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local p5 = inv:get_stack("product", 5)
local p6 = inv:get_stack("product", 6)
return p5:is_empty() and p6:is_empty()
-- Actually not quite, this checks whether the reaction would be possible if we needed an empty stack for every product
-- TODO do this properly
local needed_stacks = #products
local free_stacks = 0
for i=1, 6 do
local prod = inv:get_stack("product", i)
if prod:is_empty() then
free_stacks = free_stacks + 1
end
end
return free_stacks >= needed_stacks
end
local function get_node_group(name, group)
@ -74,13 +153,15 @@ end
local function bunsen_sound(pos)
minetest.sound_play("chemistry_bunsen", {
pos = pos,
max_hear_distance = 32,
max_hear_distance = 16,
gain = 1.0,
})
end
local function explosion_sound(pos)
minetest.sound_play("chemistry_explosion", {
pos = pos,
max_hear_distance = 64,
gain = 1.0,
})
end
@ -88,7 +169,7 @@ end
local function mortar_sound(pos)
minetest.sound_play("chemistry_mortar", {
pos = pos,
max_hear_distance = 32,
max_hear_distance = 8,
gain = 1.0,
})
end
@ -96,7 +177,7 @@ end
local function pouring_sound(pos)
minetest.sound_play("chemistry_pouring", {
pos = pos,
max_hear_distance = 32,
max_hear_distance = 8,
gain = 1.0,
})
end
@ -104,470 +185,138 @@ end
local function stirring_sound(pos)
minetest.sound_play("chemistry_stirring", {
pos = pos,
max_hear_distance = 32,
max_hear_distance = 8,
gain = 1.0,
})
end
local function check_item_match(item, stack)
if item == nil then
return stack:is_empty()
else
return stack:get_name() == item
end
end
local function check_name_match(actual, needed)
if needed:sub(1, 6) == "group:" then
return get_node_group(actual, needed:sub(7)) ~= 0
else
return actual == needed
end
end
local function lab_node_timer(pos, elapsed)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local result = false
local catalyst = inv:get_stack("catalyst", 1)
local tool = inv:get_stack("tool", 1)
local r1 = inv:get_stack("reactant", 1)
local r2 = inv:get_stack("reactant", 2)
local r3 = inv:get_stack("reactant", 3)
local r4 = inv:get_stack("reactant", 4)
local r5 = inv:get_stack("reactant", 5)
local r6 = inv:get_stack("reactant", 6)
if r6:is_empty() then
if r5:is_empty() then
if r4:is_empty() then
if r3:is_empty() then
if r2:is_empty() then
if r1:is_empty() then
else
if r1:get_name() == "chemistry:vanadium_ingot" and r1:get_count() >= 2 and tool:get_name() == "chemistry:bunsen" then
local item = ItemStack("chemistry:vanadium_v_oxide", 1)
if reaction_possible(pos) then
bunsen_sound(pos)
inv:add_item("product", item)
r1:set_count(r1:get_count() - 2)
inv:set_stack("reactant", 1, r1)
result = true
end
end
if r1:get_name() == "chemistry:sulfur_lump" and tool:get_name() == "chemistry:bunsen" then
local item = ItemStack("chemistry:sulfur_dioxide", 1)
if reaction_possible(pos) then
bunsen_sound(pos)
inv:add_item("product", item)
r1:set_count(r1:get_count() - 1)
inv:set_stack("reactant", 1, r1)
result = true
end
end
if r1:get_name() == "chemistry:sulfur_dioxide" and r1:get_count() >= 2 and tool:get_name() == "chemistry:bunsen" and catalyst:get_name() == "chemistry:vanadium_v_oxide" then
local item = ItemStack("chemistry:sulfur_trioxide", 1) -- just using two here doesn't work for some reason
if reaction_possible(pos) then
bunsen_sound(pos)
inv:add_item("product", item)
inv:add_item("product", item)
r1:set_count(r1:get_count() - 2)
inv:set_stack("reactant", 1, r1)
result = true
end
end
if r1:get_name() == "bucket:bucket_water" and tool:get_name() == "chemistry:bucket_emptying_system" then
local item = ItemStack("default:water_source", 1)
local bucket = ItemStack("bucket:bucket_empty", 1)
if reaction_possible(pos) then
pouring_sound(pos)
inv:add_item("product", item)
inv:set_stack("reactant", 1, bucket)
result = true
end
end
if r1:get_name() == "bucket:bucket_lava" and tool:get_name() == "chemistry:bucket_emptying_system" then
local item = ItemStack("default:lava_source", 1)
local bucket = ItemStack("bucket:bucket_empty", 1)
if reaction_possible(pos) then
pouring_sound(pos)
inv:add_item("product", item)
inv:set_stack("reactant", 1, bucket)
result = true
end
end
if r1:get_name() == "default:water_source" and r1:get_count() >= 2 and tool:get_name() == "chemistry:electrolytic_unit" then
local item = ItemStack("chemistry:hydrogen", 1)
local oxygen = ItemStack("chemistry:oxygen", 1)
if reaction_possible(pos) then
inv:add_item("product", item)
inv:add_item("product", item)
inv:add_item("product", oxygen)
r1:set_count(r1:get_count() - 2)
inv:set_stack("reactant", 1, r1)
result = true
end
end
if r1:get_name() == "chemistry:salt" and r1:get_count() >= 2 and tool:get_name() == "chemistry:electrolytic_unit" then
local sodium = ItemStack("chemistry:sodium", 1)
local chlorine = ItemStack("chemistry:chlorine", 1)
if reaction_possible(pos) then
inv:add_item("product", sodium)
inv:add_item("product", sodium)
inv:add_item("product", chlorine)
r1:set_count(r1:get_count() - 2)
inv:set_stack("reactant", 1, r1)
result = true
end
end
if r1:get_name() == "chemistry:hydrogen" and r1:get_count() >= 4 and tool:get_name() == "chemistry:star" then
local helium = ItemStack("chemistry:helium", 1)
if reaction_possible(pos) then
inv:add_item("product", helium)
r1:set_count(r1:get_count() - 4)
inv:set_stack("reactant", 1, r1)
result = true
end
end
if r1:get_name() == "chemistry:helium" and r1:get_count() >= 3 and tool:get_name() == "chemistry:star" then
local carbon = ItemStack("default:coal_lump", 1)
if reaction_possible(pos) then
inv:add_item("product", carbon)
r1:set_count(r1:get_count() - 3)
inv:set_stack("reactant", 1, r1)
result = true
end
end
if r1:get_name() == "default:coal_lump" and r1:get_count() >= 2 and tool:get_name() == "chemistry:star" then
local neon = ItemStack("chemistry:neon", 1)
local helium = ItemStack("chemistry:helium", 1)
if reaction_possible(pos) then
inv:add_item("product", neon)
inv:add_item("product", helium)
r1:set_count(r1:get_count() - 2)
inv:set_stack("reactant", 1, r1)
result = true
end
end
if r1:get_name() == "chemistry:oxygen" and r1:get_count() >= 2 and tool:get_name() == "chemistry:star" then
if math.random() < 0.5 then
local sulfur = ItemStack("chemistry:sulfur_lump", 1)
if reaction_possible(pos) then
inv:add_item("product", sulfur)
r1:set_count(r1:get_count() - 2)
inv:set_stack("reactant", 1, r1)
result = true
end
else
local silicon = ItemStack("chemistry:silicon", 1)
local helium = ItemStack("chemistry:helium", 1)
if reaction_possible(pos) then
inv:add_item("product", silicon)
inv:add_item("product", helium)
r1:set_count(r1:get_count() - 2)
inv:set_stack("reactant", 1, r1)
result = true
end
end
end
if r1:get_name() == "chemistry:silicon" and r1:get_count() >= 2 and tool:get_name() == "chemistry:star" then
local iron = ItemStack("default:iron_lump", 1)
if reaction_possible(pos) then
inv:add_item("product", iron)
r1:set_count(r1:get_count() - 2)
inv:set_stack("reactant", 1, r1)
result = true
end
end
if r1:get_name() == "chemistry:silicon" and tool:get_name() == "chemistry:bunsen" then
local item = ItemStack("default:sand", 1)
if reaction_possible(pos) then
bunsen_sound(pos)
inv:add_item("product", item)
r1:set_count(r1:get_count() - 1)
inv:set_stack("reactant", 1, r1)
result = true
end
end
if r1:get_name() == "default:cobble" and tool:get_name() == "chemistry:mortar" then
local item = ItemStack("default:gravel", 1)
if reaction_possible(pos) then
mortar_sound(pos)
inv:add_item("product", item)
r1:set_count(r1:get_count() - 1)
inv:set_stack("reactant", 1, r1)
result = true
end
end
if r1:get_name() == "default:sand" and tool:get_name() == "chemistry:mortar" then
local item = ItemStack("default:clay", 1)
if reaction_possible(pos) then
mortar_sound(pos)
inv:add_item("product", item)
r1:set_count(r1:get_count() - 1)
inv:set_stack("reactant", 1, r1)
result = true
end
end
if get_node_group(r1:get_name(), "tree") ~= 0 and tool:get_name() == "chemistry:mortar" then
local item = ItemStack("default:dirt", 1)
if reaction_possible(pos) then
mortar_sound(pos)
inv:add_item("product", item)
inv:add_item("product", item)
inv:add_item("product", item)
inv:add_item("product", item)
inv:add_item("product", item)
inv:add_item("product", item)
inv:add_item("product", item)
inv:add_item("product", item)
r1:set_count(r1:get_count() - 1)
inv:set_stack("reactant", 1, r1)
result = true
end
end
if get_node_group(r1:get_name(), "wood") ~= 0 and tool:get_name() == "chemistry:mortar" then
local item = ItemStack("default:dirt", 1)
if reaction_possible(pos) then
mortar_sound(pos)
inv:add_item("product", item)
inv:add_item("product", item)
r1:set_count(r1:get_count() - 1)
inv:set_stack("reactant", 1, r1)
result = true
end
end
if get_node_group(r1:get_name(), "tree") ~= 0 and tool:get_name() == "chemistry:bunsen" then
local item = ItemStack("chemistry:charcoal", 1)
if reaction_possible(pos) then
bunsen_sound(pos)
inv:add_item("product", item)
inv:add_item("product", item)
inv:add_item("product", item)
inv:add_item("product", item)
r1:set_count(r1:get_count() - 1)
inv:set_stack("reactant", 1, r1)
result = true
end
end
if get_node_group(r1:get_name(), "wood") ~= 0 and tool:get_name() == "chemistry:bunsen" then
local item = ItemStack("chemistry:charcoal", 1)
if reaction_possible(pos) then
bunsen_sound(pos)
inv:add_item("product", item)
r1:set_count(r1:get_count() - 1)
inv:set_stack("reactant", 1, r1)
result = true
end
end
-- The Completely Realistic Supernova™
-- Masses don't work out, and the star continues to exist, but it's just to make the last few things renewable
if r1:get_name() == "default:diamond" and tool:get_name() == "chemistry:star" then
local value = math.random()
if (value < 0.4) then
if reaction_possible(pos) then
explosion_sound(pos)
local copper = ItemStack("default:copper_lump", 1)
inv:add_item("product", copper)
r1:set_count(r1:get_count() - 1)
inv:set_stack("reactant", 1, r1)
result = true
end
elseif (value < 0.8) then
if reaction_possible(pos) then
explosion_sound(pos)
local vanadium = ItemStack("chemistry:vanadium_lump", 1)
inv:add_item("product", vanadium)
r1:set_count(r1:get_count() - 1)
inv:set_stack("reactant", 1, r1)
result = true
end
elseif (value < 0.93) then
if reaction_possible(pos) then
explosion_sound(pos)
local gold = ItemStack("default:gold_lump", 1)
inv:add_item("product", gold)
r1:set_count(r1:get_count() - 1)
inv:set_stack("reactant", 1, r1)
result = true
end
else
if reaction_possible(pos) then
explosion_sound(pos)
local mese = ItemStack("default:mese_crystal", 1)
inv:add_item("product", mese)
r1:set_count(r1:get_count() - 1)
inv:set_stack("reactant", 1, r1)
result = true
end
end
end
if r1:get_name() == "chemistry:copper_sulfate_wet" and tool:get_name() == "chemistry:bunsen" then
local item = ItemStack("default:copper_sulfate_dry", 1)
if reaction_possible(pos) then
bunsen_sound(pos)
inv:add_item("product", item)
r1:set_count(r1:get_count() - 1)
inv:set_stack("reactant", 1, r1)
result = true
end
end
if r1:get_name() == "default:water_source" and r1:get_count() >= 10 and tool:get_name() == "chemistry:bunsen" then
local item = ItemStack("chemistry:salt", 1)
if reaction_possible(pos) then
bunsen_sound(pos)
inv:add_item("product", item)
r1:set_count(r1:get_count() - 10)
inv:set_stack("reactant", 1, r1)
result = true
end
end
if r1:get_name() == "chemistry:hydrogen" and tool:get_name() == "chemistry:bunsen" then
local item = ItemStack("default:water_source", 1)
if reaction_possible(pos) then
explosion_sound(pos)
inv:add_item("product", item)
r1:set_count(r1:get_count() - 1)
inv:set_stack("reactant", 1, r1)
result = true
end
end
end -- r1 switch
else
if r1:get_name() == "chemistry:sulfur_trioxide" and r2:get_name() == "default:water_source" and tool:get_name() == "chemistry:stir_stick" then
local item = ItemStack("chemistry:sulfur_trioxide_water", 1)
if reaction_possible(pos) then
inv:add_item("product", item)
r1:set_count(r1:get_count() - 1)
r2:set_count(r2:get_count() - 1)
inv:set_stack("reactant", 1, r1)
inv:set_stack("reactant", 2, r2)
result = true
end
local r = {}
r[1] = inv:get_stack("reactant", 1)
r[2] = inv:get_stack("reactant", 2)
r[3] = inv:get_stack("reactant", 3)
r[4] = inv:get_stack("reactant", 4)
r[5] = inv:get_stack("reactant", 5)
r[6] = inv:get_stack("reactant", 6)
local reaction = nil
for i=1, #reactions do
local formula = reactions[i]
local needed_tool = formula.tool
local needed_catalyst = formula.catalyst
local needed_reactants = formula.reactants
local reaction_works = true
for j=1, 6 do
local needed_reactant = needed_reactants[j]
local ok = false
if needed_reactant == nil then
ok = true
else
for k=1, 6 do
local supplied_reactant = r[k]
if check_name_match(supplied_reactant:get_name(), needed_reactant:get_name()) and supplied_reactant:get_count() >= needed_reactant:get_count() then
ok = true
end
end
end
if not ok then
reaction_works = false
end
end
local reactant_count = 0
for k = 1, 6 do
local supplied_reactant = r[k]
if not r[k]:is_empty() then
reactant_count = reactant_count + 1
end
end
if reactant_count ~= #needed_reactants then
reaction_works = false
end
if not check_item_match(needed_tool, tool) then
reaction_works = false
end
if not check_item_match(needed_catalyst, catalyst) then
reaction_works = false
end
if reaction_works then
reaction = formula
end
end
if not (reaction == nil) then
local rand = math.random()
local total_probability = 0.0
local selected_output = nil
while selected_output == nil do
for i=1, #reaction.possible_outputs do
local output = reaction.possible_outputs[i]
total_probability = total_probability + output.probability
if total_probability > rand then
selected_output = output
break
end
end
if selected_output == nil then
minetest.log("info", "Hit epsilon, retry")
end
end
local products = selected_output.products
if reaction_possible(pos, products) then
local reactants = reaction.reactants
for j=1, 6 do
local reactant = reactants[j]
if not (reactant == nil) then
for k=1, 6 do
if check_name_match(r[k]:get_name(), reactant:get_name()) then
r[k]:set_count(r[k]:get_count() - reactant:get_count())
inv:set_stack("reactant", k, r[k])
end
if r1:get_name() == "chemistry:sulfur_trioxide" and r2:get_name() == "chemistry:sulfuric_acid" and tool:get_name() == "chemistry:stir_stick" then
local item = ItemStack("chemistry:disulfuric_acid", 1)
if reaction_possible(pos) then
inv:add_item("product", item)
r1:set_count(r1:get_count() - 1)
r2:set_count(r2:get_count() - 1)
inv:set_stack("reactant", 1, r1)
inv:set_stack("reactant", 2, r2)
result = true
end
end
if r1:get_name() == "chemistry:disulfuric_acid" and r2:get_name() == "default:water_source" and tool:get_name() == "chemistry:stir_stick" then
local item = ItemStack("chemistry:sulfuric_acid", 1)
if reaction_possible(pos) then
inv:add_item("product", item)
inv:add_item("product", item)
r1:set_count(r1:get_count() - 1)
r2:set_count(r2:get_count() - 1)
inv:set_stack("reactant", 1, r1)
inv:set_stack("reactant", 2, r2)
result = true
end
end
if r1:get_name() == "chemistry:hydrogen" and r2:get_name() == "chemistry:chlorine" and tool:get_name() == "chemistry:bunsen" then
local item = ItemStack("chemistry:hydrogen_chloride", 1)
if reaction_possible(pos) then
explosion_sound(pos)
inv:add_item("product", item)
inv:add_item("product", item)
r1:set_count(r1:get_count() - 1)
r2:set_count(r2:get_count() - 1)
inv:set_stack("reactant", 1, r1)
inv:set_stack("reactant", 2, r2)
result = true
end
end
if r1:get_name() == "chemistry:hydrogen_chloride" and r2:get_name() == "default:water_source" and tool:get_name() == "chemistry:stir_stick" then
local item = ItemStack("chemistry:hydrochloric_acid", 1)
if reaction_possible(pos) then
stirring_sound(pos)
inv:add_item("product", item)
r1:set_count(r1:get_count() - 1)
r2:set_count(r2:get_count() - 1)
inv:set_stack("reactant", 1, r1)
inv:set_stack("reactant", 2, r2)
result = true
end
end
if r1:get_name() == "chemistry:sodium" and r1:get_count() >= 2 and r2:get_name() == "default:water_source" and r2:get_count() >= 2 and tool:get_name() == "chemistry:stir_stick" then
local item = ItemStack("chemistry:sodium_hydroxide", 1)
local hydrogen = ItemStack("chemistry:hydrogen", 1)
if reaction_possible(pos) then
stirring_sound(pos)
inv:add_item("product", item)
inv:add_item("product", item)
inv:add_item("product", hydrogen)
r1:set_count(r1:get_count() - 2)
r2:set_count(r2:get_count() - 2)
inv:set_stack("reactant", 1, r1)
inv:set_stack("reactant", 2, r2)
result = true
end
end
if r1:get_name() == "chemistry:sodium_hydroxide" and r2:get_name() == "default:water_source" and tool:get_name() == "chemistry:stir_stick" then
local item = ItemStack("chemistry:caustic_soda", 1)
if reaction_possible(pos) then
stirring_sound(pos)
inv:add_item("product", item)
r1:set_count(r1:get_count() - 1)
r2:set_count(r2:get_count() - 1)
inv:set_stack("reactant", 1, r1)
inv:set_stack("reactant", 2, r2)
result = true
end
end
if r1:get_name() == "default:coal_lump" and r2:get_name() == "chemistry:helium" and tool:get_name() == "chemistry:star" then
local oxygen = ItemStack("chemistry:oxygen", 1)
if reaction_possible(pos) then
inv:add_item("product", oxygen)
r1:set_count(r1:get_count() - 1)
r2:set_count(r2:get_count() - 1)
inv:set_stack("reactant", 1, r1)
inv:set_stack("reactant", 2, r2)
result = true
end
end
if r1:get_name() == "chemistry:neon" and r2:get_name() == "chemistry:helium" and tool:get_name() == "chemistry:star" then
local magnesium = ItemStack("chemistry:magnesium", 1)
if reaction_possible(pos) then
inv:add_item("product", magnesium)
r1:set_count(r1:get_count() - 1)
r2:set_count(r2:get_count() - 1)
inv:set_stack("reactant", 1, r1)
inv:set_stack("reactant", 2, r2)
result = true
end
end
if r1:get_name() == "chemistry:oxygen" and r2:get_name() == "chemistry:helium" and tool:get_name() == "chemistry:star" then
local neon = ItemStack("chemistry:neon", 1)
if reaction_possible(pos) then
inv:add_item("product", neon)
r1:set_count(r1:get_count() - 1)
r2:set_count(r2:get_count() - 1)
inv:set_stack("reactant", 1, r1)
inv:set_stack("reactant", 2, r2)
result = true
end
end
if (r1:get_name() == "default:copper_lump" or r1:get_name() == "default:copper_ingot") and r2:get_name() == "chemistry:sulfuric_acid" and tool:get_name() == "chemistry:stir_stick" and catalyst:get_name() == "chemistry:bunsen" then
local cuso4 = ItemStack("chemistry:copper_ii_sulfate_dry", 1)
local hydrogen = ItemStack("chemistry:hydrogen", 1)
if reaction_possible(pos) then
stirring_sound(pos)
inv:add_item("product", cuso4)
inv:add_item("product", hydrogen)
r1:set_count(r1:get_count() - 1)
r2:set_count(r2:get_count() - 1)
inv:set_stack("reactant", 1, r1)
inv:set_stack("reactant", 2, r2)
result = true
end
end
if (get_node_group(r1:get_name(), "stone") ~= 0 or r1:get_name() == "default:gravel") and r2:get_name() == "chemistry:sulfuric_acid" and tool:get_name() == "chemistry:stir_stick" then
local gypsum = ItemStack("chemistry:gypsum", 1)
if reaction_possible(pos) then
stirring_sound(pos)
inv:add_item("product", gypsum)
r1:set_count(r1:get_count() - 1)
r2:set_count(r2:get_count() - 1)
inv:set_stack("reactant", 1, r1)
inv:set_stack("reactant", 2, r2)
result = true
end
end
end -- r2 switch
end -- r3 switch
end -- r4 switch
end -- r5 switch
end -- r6 switch
end
end
end
for k=1, #products do
inv:add_item("product", products[k])
end
if reaction.sound then
local sound = reaction.sound
if sound == "bunsen" then
bunsen_sound()
elseif sound == "explosion" then
explosion_sound()
elseif sound == "mortar" then
mortar_sound()
elseif sound == "pouring" then
pouring_sound()
elseif sound == "stirring" then
stirring_sound()
end
end
result = true
end
end
return result
end
@ -611,4 +360,3 @@ minetest.register_node("chemistry:lab", {
allow_metadata_inventory_move = allow_metadata_inventory_move,
allow_metadata_inventory_take = allow_metadata_inventory_take,
})

View File

@ -55,7 +55,7 @@ function chemistry.register_ores()
ore_type = "scatter",
ore = "chemistry:stone_with_vanadium",
wherein = "default:stone",
clust_scarcity = 9 * 9 * 9,
clust_scarcity = 7 * 7 * 7,
clust_num_ores = 5,
clust_size = 3,
y_min = 1025,
@ -66,7 +66,7 @@ function chemistry.register_ores()
ore_type = "scatter",
ore = "chemistry:stone_with_vanadium",
wherein = "default:stone",
clust_scarcity = 12 * 12 * 12,
clust_scarcity = 9 * 9 * 9,
clust_num_ores = 4,
clust_size = 3,
y_min = -63,
@ -77,7 +77,7 @@ function chemistry.register_ores()
ore_type = "scatter",
ore = "chemistry:stone_with_vanadium",
wherein = "default:stone",
clust_scarcity = 9 * 9 * 9,
clust_scarcity = 7 * 7 * 7,
clust_num_ores = 5,
clust_size = 3,
y_min = -31000,

476
reactions.lua Normal file
View File

@ -0,0 +1,476 @@
register_reaction({
tool = "chemistry:bunsen",
reactants = {ItemStack("chemistry:vanadium_ingot 2")},
possible_outputs = {
{
probability = 1.0,
products = {ItemStack("chemistry:vanadium_v_oxide 1")}
}
},
sound = "bunsen"
})
register_reaction({
tool = "chemistry:bunsen",
reactants = {ItemStack("chemistry:sulfur_lump 1")},
possible_outputs = {
{
probability = 1.0,
products = {ItemStack("chemistry:sulfur_dioxide 1")}
}
},
sound = "bunsen"
})
register_reaction({
tool = "chemistry:bunsen",
catalyst = "chemistry:vanadium_v_oxide",
reactants = {ItemStack("chemistry:sulfur_dioxide 2")},
possible_outputs = {
{
probability = 1.0,
products = {ItemStack("chemistry:sulfur_trioxide 2")}
}
},
sound = "bunsen"
})
register_reaction({
tool = "chemistry:bucket_emptying_system",
reactants = {ItemStack("bucket:bucket_water 1")},
possible_outputs = {
{
probability = 1.0,
products = {ItemStack("default:water_source 1"), ItemStack("bucket:bucket_empty 1")}
}
},
sound = "pouring"
})
register_reaction({
tool = "chemistry:bucket_emptying_system",
reactants = {ItemStack("bucket:bucket_lava 1")},
possible_outputs = {
{
probability = 1.0,
products = {ItemStack("default:lava_source 1"), ItemStack("bucket:bucket_empty 1")}
}
},
sound = "pouring"
})
register_reaction({
tool = "chemistry:electrolytic_unit",
reactants = {ItemStack("default:water_source 2")},
possible_outputs = {
{
probability = 1.0,
products = {ItemStack("chemistry:hydrogen 2"), ItemStack("chemistry:oxygen 1")}
}
}
})
register_reaction({
tool = "chemistry:electrolytic_unit",
reactants = {ItemStack("chemistry:salt 2")},
possible_outputs = {
{
probability = 1.0,
products = {ItemStack("chemistry:sodium 2"), ItemStack("chemistry:chlorine 1")}
}
}
})
register_reaction({
tool = "chemistry:star",
reactants = {ItemStack("chemistry:hydrogen 4")},
possible_outputs = {
{
probability = 1.0,
products = {ItemStack("chemistry:helium 1")}
}
}
})
register_reaction({
tool = "chemistry:star",
reactants = {ItemStack("chemistry:helium 3")},
possible_outputs = {
{
probability = 1.0,
products = {ItemStack("default:coal_lump 1")}
}
}
})
register_reaction({
tool = "chemistry:star",
reactants = {ItemStack("default:coal_lump 2")},
possible_outputs = {
{
probability = 1.0,
products = {ItemStack("chemistry:neon 1"), ItemStack("chemistry:helium 1")}
}
}
})
register_reaction({
tool = "chemistry:star",
reactants = {ItemStack("chemistry:oxygen 2")},
possible_outputs = {
{
probability = 0.5,
products = {ItemStack("chemistry:sulfur_lump 1")}
},
{
probability = 0.5,
products = {ItemStack("chemistry:silicon 1"), ItemStack("chemistry:helium 1")}
}
}
})
register_reaction({
tool = "chemistry:star",
reactants = {ItemStack("chemistry:silicon 2")},
possible_outputs = {
{
probability = 1.0,
products = {ItemStack("default:iron_lump 1")}
}
}
})
register_reaction({
tool = "chemistry:bunsen",
reactants = {ItemStack("chemistry:silicon 1")},
possible_outputs = {
{
probability = 1.0,
products = {ItemStack("default:sand 1")}
}
},
sound = "bunsen"
})
register_reaction({
tool = "chemistry:mortar",
reactants = {ItemStack("default:cobble 1")},
possible_outputs = {
{
probability = 1.0,
products = {ItemStack("default:gravel 1")}
}
},
sound = "mortar"
})
register_reaction({
tool = "chemistry:mortar",
reactants = {ItemStack("default:gravel 1")},
possible_outputs = {
{
probability = 1.0,
products = {ItemStack("default:sand 1")}
}
},
sound = "mortar"
})
register_reaction({
tool = "chemistry:mortar",
reactants = {ItemStack("default:sand 1")},
possible_outputs = {
{
probability = 1.0,
products = {ItemStack("default:clay 1")}
}
},
sound = "mortar"
})
register_reaction({
tool = "chemistry:mortar",
reactants = {ItemStack("group:tree 1")},
possible_outputs = {
{
probability = 1.0,
products = {ItemStack("default:dirt 8")}
}
},
sound = "mortar"
})
register_reaction({
tool = "chemistry:mortar",
reactants = {ItemStack("group:wood 1")},
possible_outputs = {
{
probability = 1.0,
products = {ItemStack("default:dirt 2")}
}
},
sound = "mortar"
})
register_reaction({
tool = "chemistry:bunsen",
reactants = {ItemStack("group:tree 1")},
possible_outputs = {
{
probability = 1.0,
products = {ItemStack("chemistry:charcoal 4")}
}
},
sound = "bunsen"
})
register_reaction({
tool = "chemistry:bunsen",
reactants = {ItemStack("group:wood 1")},
possible_outputs = {
{
probability = 1.0,
products = {ItemStack("chemistry:charcoal 1")}
}
},
sound = "bunsen"
})
register_reaction({
tool = "chemistry:star",
reactants = {ItemStack("default:iron_lump 1")},
possible_outputs = { -- The probabilities are approximately proportional to the occurence at very low y
{
probability = 0.351,
products = {ItemStack("default:iron_lump 1")}
},
{
probability = 0.309,
products = {ItemStack("chemistry:vanadium_lump 1")}
},
{
probability = 0.146,
products = {ItemStack("default:copper_lump 1")}
},
{
probability = 0.106,
products = {ItemStack("default:tin_lump 1")}
},
{
probability = 0.048,
products = {ItemStack("default:gold_lump 1")}
},
{
probability = 0.039,
products = {ItemStack("default:mese_crystal 1")}
},
{
probability = 0.001,
products = {ItemStack("default:mese 1")}
}
}
})
register_reaction({
tool = "chemistry:bunsen",
reactants = {ItemStack("chemistry:copper_ii_sulfate_wet 1")},
possible_outputs = {
{
probability = 1.0,
products = {ItemStack("chemistry:copper_ii_sulfate_dry 1")}
}
},
sound = "bunsen"
})
register_reaction({
tool = "chemistry:bunsen",
reactants = {ItemStack("default:water_source 10")},
possible_outputs = {
{
probability = 1.0,
products = {ItemStack("chemistry:salt 1")}
}
},
sound = "bunsen"
})
register_reaction({
tool = "chemistry:bunsen",
reactants = {ItemStack("chemistry:hydrogen 1")},
possible_outputs = {
{
probability = 1.0,
products = {ItemStack("default:water_source 1")}
}
},
sound = "explosion"
})
register_reaction({
tool = "chemistry:stir_stick",
reactants = {ItemStack("chemistry:sulfur_trioxide 1"), ItemStack("default:water_source 1")},
possible_outputs = {
{
probability = 1.0,
products = {ItemStack("chemistry:sulfur_trioxide_water 1")}
}
},
sound = "stirring"
})
register_reaction({
tool = "chemistry:stir_stick",
reactants = {ItemStack("chemistry:sulfur_trioxide 1"), ItemStack("chemistry:sulfuric_acid 1")},
possible_outputs = {
{
probability = 1.0,
products = {ItemStack("chemistry:disulfuric_acid 1")}
}
},
sound = "stirring"
})
register_reaction({
tool = "chemistry:stir_stick",
reactants = {ItemStack("chemistry:disulfuric_acid 1"), ItemStack("default:water_source 1")},
possible_outputs = {
{
probability = 1.0,
products = {ItemStack("chemistry:sulfuric_acid 2")}
}
},
sound = "stirring"
})
register_reaction({
tool = "chemistry:bunsen",
reactants = {ItemStack("chemistry:hydrogen 1"), ItemStack("chemistry:chlorine 1")},
possible_outputs = {
{
probability = 1.0,
products = {ItemStack("chemistry:hydrogen_chloride 2")}
}
},
sound = "explosion"
})
register_reaction({
tool = "chemistry:stir_stick",
reactants = {ItemStack("chemistry:hydrogen_chloride 1"), ItemStack("default:water_source 1")},
possible_outputs = {
{
probability = 1.0,
products = {ItemStack("chemistry:hydrochloric_acid 1")}
}
},
sound = "stirring"
})
register_reaction({
tool = "chemistry:stir_stick",
reactants = {ItemStack("chemistry:sodium 2"), ItemStack("default:water_source 2")},
possible_outputs = {
{
probability = 1.0,
products = {ItemStack("chemistry:sodium_hydroxide 2"), ItemStack("chemistry:hydrogen 1")}
}
},
sound = "stirring"
})
register_reaction({
tool = "chemistry:stir_stick",
reactants = {ItemStack("chemistry:sodium_hydroxide 1"), ItemStack("default:water_source 1")},
possible_outputs = {
{
probability = 1.0,
products = {ItemStack("chemistry:caustic_soda 1")}
}
},
sound = "stirring"
})
register_reaction({
tool = "chemistry:star",
reactants = {ItemStack("default:coal_lump 1"), ItemStack("chemistry:helium 1")},
possible_outputs = {
{
probability = 1.0,
products = {ItemStack("chemistry:oxygen 1")}
}
}
})
register_reaction({
tool = "chemistry:star",
reactants = {ItemStack("chemistry:neon 1"), ItemStack("chemistry:helium 1")},
possible_outputs = {
{
probability = 1.0,
products = {ItemStack("chemistry:magnesium 1")}
}
}
})
register_reaction({
tool = "chemistry:star",
reactants = {ItemStack("chemistry:oxygen 1"), ItemStack("chemistry:helium 1")},
possible_outputs = {
{
probability = 1.0,
products = {ItemStack("chemistry:neon 1")}
}
}
})
register_reaction({
tool = "chemistry:stir_stick",
catalyst = "chemistry:bunsen",
reactants = {ItemStack("default:copper_lump 1"), ItemStack("chemistry:sulfuric_acid 1")},
possible_outputs = {
{
probability = 1.0,
products = {ItemStack("chemistry:copper_ii_sulfate_dry 1"), ItemStack("chemistry:hydrogen 1")}
}
},
sound = "bunsen"
})
register_reaction({
tool = "chemistry:stir_stick",
catalyst = "chemistry:bunsen",
reactants = {ItemStack("default:copper_ingot 1"), ItemStack("chemistry:sulfuric_acid 1")},
possible_outputs = {
{
probability = 1.0,
products = {ItemStack("chemistry:copper_ii_sulfate_dry 1"), ItemStack("chemistry:hydrogen 1")}
}
},
sound = "bunsen"
})
register_reaction({
tool = "chemistry:stir_stick",
reactants = {ItemStack("group:stone 1"), ItemStack("chemistry:sulfuric_acid 1")},
possible_outputs = {
{
probability = 1.0,
products = {ItemStack("chemistry:gypsum 1")}
}
},
sound = "stirring"
})
register_reaction({
tool = "chemistry:stir_stick",
reactants = {ItemStack("default:gravel 1"), ItemStack("chemistry:sulfuric_acid 1")},
possible_outputs = {
{
probability = 1.0,
products = {ItemStack("chemistry:gypsum 1")}
}
},
sound = "stirring"
})

BIN
textures/chemistry_book.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 437 B