InsaneProtestor/mods/ip_terumet/init.lua
2022-11-22 00:44:34 -05:00

328 lines
11 KiB
Lua

--[[ Terumet v3.0
Mod for open-source voxel game Minetest (https://www.minetest.net/)
Written for Minetest version 5.0.0
Now also supports Minetest 0.4.17
Creates a new ore in the world which can be used to make useful alloys
and heat-powered machines.
By Terumoc [https://github.com/Terumoc]
and with contributions from:
> obl3pplifp (https://github.com/obl3pplifp) for bug reports, information, ideas, and other considerable contributions
> RSL-Redstonier [https://github.com/RSL-Redstonier]
> Chem871 [https://github.com/Chemguy99] for many ideas and requests
BIG Thanks to all contributors for their input!
]]--
--[[ Copyright (C) 2017-2019 Terumoc (Scott Horvath)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. ]]
terumet = {}
terumet.version = {major=3, minor=0, patch=0}
local ver = terumet.version
terumet.version_text = ver.major .. '.' .. ver.minor .. '.' .. ver.patch
terumet.mod_name = "terumet"
-- this isn't the suggested way to check for game version but... it works for my purposes
terumet.legacy = minetest.get_version().string:find('0.4')
if terumet.legacy then
minetest.log('[terumet] MTv0.4.* detected - in legacy mode!')
end
terumet.RAND = PcgRandom(os.time())
local FMT = string.format
minetest.register_chatcommand( 'item_info', {
params = '',
description = 'Get a complete description of the ItemStack in your hand',
privs = {debug=true},
func = function(name)
local player = minetest.get_player_by_name(name)
if player then
local witem = player:get_wielded_item()
if witem:is_empty() then
return true, "You're not holding anything."
else
local def = witem:get_definition()
local wear = witem:get_wear()
local wear_pct = FMT('%.1f%%', wear / 65535 * 100.0)
if def then
return true, FMT('%s "%s" #%s/%s w:%s (%s)',
minetest.colorize('#ff0', witem:get_name()),
def.description,
witem:get_count(),
minetest.colorize('#0ff', def.stack_max),
minetest.colorize('#f0f', wear),
minetest.colorize('#f0f', wear_pct)
)
else
return true, FMT('*NO DEF* %s #%s w:%s (%s)',
minetest.colorize('#ff0', witem:get_name()),
witem:get_count(),
minetest.colorize('#f0f', wear),
minetest.colorize('#f0f', wear_pct)
)
end
end
else
return false, "You aren't a player somehow, sorry?!"
end
end
})
function terumet.chance(pct)
if pct <= 0 then return false end
if pct >= 100 then return true end
return terumet.RAND:next(1,100) <= pct
end
-- function for a node's on_blast callback to be removed with a pct% chance
function terumet.blast_chance(pct, id)
return function(pos)
if terumet.chance(pct) then
minetest.remove_node(pos)
return {id}
else
return nil
end
end
end
-- empty function useful for where a callback is necessary but using nil would cause undesired default behavior
terumet.NO_FUNCTION = function() end
terumet.EMPTY = {}
terumet.ZERO_XYZ = {x=0,y=0,z=0}
function terumet.recipe_3x3(i)
return {
{i, i, i}, {i, i, i}, {i, i, i}
}
end
function terumet.recipe_box(outer, inner)
return {
{outer, outer, outer}, {outer, inner, outer}, {outer, outer, outer}
}
end
function terumet.recipe_plus(i)
return {
{'', i, ''}, {i, i, i}, {'', i, ''}
}
end
function terumet.random_velocity(max_tenths)
return {
x = terumet.RAND:next(-max_tenths,max_tenths) / 10,
y = terumet.RAND:next(-max_tenths,max_tenths) / 10,
z = terumet.RAND:next(-max_tenths,max_tenths) / 10
}
end
function terumet.particle_stream(pointA, pointB, density, particle_data, player)
local dist_vector = {x=(pointB.x-pointA.x), y=(pointB.y-pointA.y), z=(pointB.z-pointA.z)}
local dist = vector.length(dist_vector)
local pcount = dist * density
if pcount < 1 then return end -- guard against div/0
local step = {x=(dist_vector.x/pcount), y=(dist_vector.y/pcount), z=(dist_vector.z/pcount)}
local ppos = vector.new(pointA)
for _ = 1,pcount do
ppos = util3d.pos_plus(ppos, step)
minetest.add_particle{
pos = vector.new(ppos),
velocity=terumet.random_velocity(5),
expirationtime=(particle_data.expiration or 1),
size=(particle_data.size or 1),
glow=(particle_data.glow or 1),
playername=player,
texture=particle_data.texture,
animation=particle_data.animation
}
end
end
function terumet.format_time(t)
return string.format('%.1f s', t or 0)
end
function terumet.do_lua_file(name)
dofile(minetest.get_modpath(terumet.mod_name) .. '/' .. name .. '.lua')
end
-- create a copy of node groups from an unlit machine for lit version of machine
function terumet.create_lit_node_groups(unlit_groups)
local new_groups = {not_in_creative_inventory=1}
for k,v in pairs(unlit_groups) do new_groups[k] = v end
return new_groups
end
function terumet.itemstack_desc(stack)
local stack_desc = stack:get_definition().description
-- use only what is before a newline if one is in the description
if stack_desc:find('\n') then stack_desc = stack_desc:match('(.*)\n') end
if stack:get_count() > 1 then
return string.format('%s (x%d)', stack_desc, stack:get_count())
else
return stack_desc
end
end
-- given a table with 'group:XXX' keys and a node/item definition with groups, return the
-- (first) value in the table where node/item has a group key of XXX, otherwise nil
function terumet.match_group_key(table, def)
if not def then return nil end
for group_name,_ in pairs(def.groups) do
local grp_key = 'group:'..group_name
if table[grp_key] then
return table[grp_key]
end
end
return nil
end
function terumet.id(id, number)
if number then
return string.format('%s:%s %d', terumet.mod_name, id, number)
else
return string.format('%s:%s', terumet.mod_name, id)
end
end
function terumet.give_player_item(pos, player, stack)
local inv = player:get_inventory()
local leftover = inv:add_item("main", stack)
if leftover and not leftover:is_empty() then
minetest.item_drop(leftover, player, player:get_pos())
end
end
function terumet.tex(id)
-- accepts both base ids (assuming this mod) and full mod ids
-- ex: terumet.tex('ingot_raw') -> 'terumet_ingot_raw.png'
-- terumet.tex('default:cobble') -> 'default_cobble.png'
if id:match(':') then
return string.format('%s.png', id:gsub(':', '_'))
else
return string.format('%s_%s.png', terumet.mod_name, id)
end
end
function terumet.item_desc(name, xinfo)
if xinfo then
return string.format("%s\n%s", name, minetest.colorize(terumet.options.misc.TIP_COLOR, xinfo))
else
return name
end
end
function terumet.crystal_tex(color)
return string.format('%s^[multiply:%s', terumet.tex('item_cryst'), color)
end
function terumet.tex_comp(base_tex, overlay_id)
return base_tex .. '^' .. terumet.tex(overlay_id)
end
function terumet.tex_trans(id, rot)
return terumet.tex(id) .. '^[transform' .. rot
end
local HEAR_DIST = 12
terumet.squishy_node_sounds = {
footstep = {name='terumet_squish_step', max_hear_distance=HEAR_DIST},
dig = {name='terumet_squish_dig', max_hear_distance=HEAR_DIST},
dug = {name='terumet_squish_dug', max_hear_distance=HEAR_DIST},
place = {name='terumet_squish_place', max_hear_distance=HEAR_DIST},
}
terumet.do_lua_file('util3d')
terumet.do_lua_file('interop/terumet_api')
terumet.do_lua_file('options')
terumet.do_lua_file('material/reg_alloy')
-- reg_alloy(name, id, block hardness level, repair material value)
terumet.reg_alloy('Terucopper', 'tcop', 1, 20)
terumet.reg_alloy('Terutin', 'ttin', 1, 15)
terumet.reg_alloy('Terusteel', 'tste', 2, 40)
terumet.reg_alloy('Terugold', 'tgol', 3, 80)
terumet.reg_alloy('Coreglass', 'cgls', 4, 120)
terumet.reg_alloy('Teruchalcum', 'tcha', 2, 60)
terumet.do_lua_file('material/ceramic')
--terumet.do_lua_file('material/thermese')
terumet.do_lua_file('material/coil')
--terumet.do_lua_file('material/crushed')
--terumet.do_lua_file('material/pwood')
--terumet.do_lua_file('material/tglass')
terumet.do_lua_file('material/rebar')
terumet.do_lua_file('material/misc')
terumet.do_lua_file('material/crystallized')
--terumet.do_lua_file('material/battery')
local id = terumet.id
-- register raw terumetal ingot as weak repair-material
terumet.register_repair_material(id('ingot_raw'), 10)
--terumet.do_lua_file('tool/reg_tools')
local sword_opts = terumet.options.tools.sword_damage
--terumet.do_lua_file('tool/ore_saw')
-- register repairable default tools and materials
-- {value of 1 item, item id}:
local dmv_values = {
steel={10, 'default:steel_ingot'},
bronze={30, 'default:bronze_ingot'},
mese={90, 'default:mese_crystal'},
diamond={100, 'default:diamond'}
}
for dmat, v in pairs(dmv_values) do
terumet.register_repairable_item("default:pick_"..dmat, v[1]*3)
terumet.register_repairable_item("default:axe_"..dmat, v[1]*3)
terumet.register_repairable_item("default:shovel_"..dmat, v[1])
terumet.register_repairable_item("default:sword_"..dmat, v[1]*2)
terumet.register_repair_material(v[2], v[1])
end
terumet.do_lua_file('material/concrete')
terumet.do_lua_file('material/coalproc')
--experimental stuff
--terumet.do_lua_file('material/meson')
local INTEROPS = {'3d_armor', 'doors', 'unified_inventory', 'tubelib', 'dungeon_loot', 'moreores', 'farming', 'extra'}
for _,mod in ipairs(INTEROPS) do
if minetest.get_modpath(mod) then terumet.do_lua_file('interop/'..mod) end
end
local vacfood_options = terumet.options.vac_oven.VAC_FOOD
if vacfood_options and vacfood_options.ACTIVE then terumet.do_lua_file('material/vacfood') end
terumet.do_lua_file('interop/crusher_misc')