-- IndustrialTest
-- Copyright (C) 2023 mrkubax10

-- 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/>.

local S=minetest.get_translator("industrialtest")

local definition={
	description=S("Machine Block"),
	tiles={"industrialtest_machine_block.png"},
}
if industrialtest.mtgAvailable then
	definition.sounds=default.node_sound_metal_defaults()
	definition.groups={cracky=1,level=2}
elseif industrialtest.mclAvailable then
	definition.sounds=mcl_sounds.node_sound_metal_defaults()
	definition._mcl_blast_resistance=6
	definition._mcl_hardness=5
end
minetest.register_node("industrialtest:machine_block",definition)
minetest.register_craft({
	type="shaped",
	output="industrialtest:machine_block",
	recipe={
		{"industrialtest:refined_iron_ingot","industrialtest:refined_iron_ingot","industrialtest:refined_iron_ingot"},
		{"industrialtest:refined_iron_ingot","","industrialtest:refined_iron_ingot"},
		{"industrialtest:refined_iron_ingot","industrialtest:refined_iron_ingot","industrialtest:refined_iron_ingot"}
	}
})

definition={
	description=S("Advanced Machine Block"),
	tiles={"industrialtest_advanced_machine_block.png"},
	groups={
		_industrialtest_wrenchUnmountable=1
	}
}
if industrialtest.mtgAvailable then
	definition.sounds=default.node_sound_metal_defaults()
	definition.groups.cracky=2
	definition.groups.level=2
elseif industrialtest.mclAvailable then
	definition.sounds=mcl_sounds.node_sound_metal_defaults()
	definition._mcl_blast_resistance=7
	definition._mcl_hardness=5
end
minetest.register_node("industrialtest:advanced_machine_block",definition)
minetest.register_craft({
	type="shaped",
	output="industrialtest:advanced_machine_block",
	recipe={
		{"","industrialtest:advanced_alloy",""},
		{"industrialtest:carbon_plate","industrialtest:machine_block","industrialtest:carbon_plate"},
		{"","industrialtest:advanced_alloy",""}
	}
})

definition={
	description=S("Rubber Wood"),
	tiles={
		"industrialtest_rubber_wood_top.png",
		"industrialtest_rubber_wood_top.png",
		"industrialtest_rubber_wood_side.png"
	},
	paramtype2="4dir"
}
if industrialtest.mtgAvailable then
	definition.sounds=default.node_sound_wood_defaults()
	definition.groups={
		tree=1,
		choppy=2,
		oddly_breakable_by_hand=1,
		flammable=2
	}
elseif industrialtest.mclAvailable then
	definition.sounds=mcl_sounds.node_sound_wood_defaults()
	definition.groups={
		handy=1,
		axey=1,
		tree=1,
		flammable=2,
		building_block=1,
		material_wood=1,
		fire_encouragement=5,
		fire_flammability=5
	}
	definition.after_destruct=mcl_core.update_leaves
	definition._mcl_blast_resistance=1.8
	definition._mcl_hardness=1.8
end
definition.groups._industrialtest_rubberWood=1
minetest.register_node("industrialtest:rubber_wood",definition)
definition=table.copy(definition)
definition.description=nil
definition.tiles={
	"industrialtest_rubber_wood_top.png",
	"industrialtest_rubber_wood_top.png",
	"industrialtest_rubber_wood_side.png",
	"industrialtest_rubber_wood_side.png",
	"industrialtest_rubber_wood_side_with_rubber.png",
	"industrialtest_rubber_wood_side.png"
}
definition.drop="industrialtest:rubber_wood"
if industrialtest.mclAvailable then
	definition.groups.not_in_creative_inventory=1
	definition._doc_items_create_entry=false
end
minetest.register_node("industrialtest:rubber_wood_with_rubber",definition)
minetest.register_abm({
	label="Rubber forming",
	nodenames={"industrialtest:rubber_wood"},
	interval=120,
	chance=2,
	action=function(pos)
		local neighbourPositions={
			vector.offset(pos,-1,0,0),
			vector.offset(pos,1,0,0),
			vector.offset(pos,0,-1,0),
			vector.offset(pos,0,1,0),
			vector.offset(pos,0,0,-1),
			vector.offset(pos,0,0,1)
		}
		for _,value in ipairs(neighbourPositions) do
			if minetest.get_node(value).name=="industrialtest:rubber_wood_with_rubber" then
				return
			end
		end
		minetest.set_node(pos,{
			name="industrialtest:rubber_wood_with_rubber",
			param2=industrialtest.random:next(0,3)
		})
	end
})
minetest.register_craft({
	type="shapeless",
	output=industrialtest.elementKeys.junglePlanks.." 3",
	recipe={"group:_industrialtest_rubberWood"}
})
definition={
	description=S("Rubber Leaves"),
	drawtype="allfaces_optional",
	tiles={"industrialtest_rubber_leaves.png"},
	special_tiles={"industrialtest_rubber_leaves_simple.png"},
	paramtype="light",
	sunlight_propagates=true,
	waving=1
}
if industrialtest.mtgAvailable then
	definition.sounds=default.node_sound_leaves_defaults()
	definition.groups={
		snappy=3,
		leafdecay=3,
		flammable=2,
		leaves=1
	}
	definition.drop={
		max_items=1,
		items={
			{
				items={"industrialtest:rubber_sapling"},
				rarity=20
			},
			{items={"industrialtest:rubber_leaves"}}
		}
	}
	definition.after_place_node=default.after_place_leaves
elseif industrialtest.mclAvailable then
	local saplingChances={20,16,12,10}
	local stickChances={50,45,30,35,10}
	-- Taken and adapted from https://git.minetest.land/MineClone2/MineClone2/src/branch/master/mods/ITEMS/mcl_core/nodes_trees.lua#L157
	local function getDrops(fortuneLevel)
		local drop = {
			max_items=1,
			items = {
				{
					items = {"industrialtest:rubber_sapling"},
					rarity = saplingChances[fortuneLevel+1] or saplingChances[fortuneLevel]
				},
				{
					items = {"mcl_core:stick 1"},
					rarity = stickChances[fortuneLevel+1]
				},
				{
					items = {"mcl_core:stick 2"},
					rarity = stickChances[fortuneLevel+1]
				},
			}
		}
		return drop
	end
	definition.sounds=mcl_sounds.node_sound_leaves_defaults()
	definition.groups={
		handy=1,
		hoey=1,
		shearsy=1,
		swordy=1,
		dig_by_piston=1,
		flammable=2,
		fire_encouragement=30,
		fire_flammability=60,
		leaves=1,
		deco_block=1,
		compostability=30
	}
	definition.drop=getDrops(0)
	definition.after_place_node=mcl_core.make_player_leaves
	definition._mcl_shears_drop=true
	definition._mcl_blast_resistance=0.2
	definition._mcl_hardness=0.2
	definition._mcl_silk_touch_drop=true
	definition._mcl_fortune_drop={getDrops(1),getDrops(2),getDrops(3),getDrops(4)}
end
minetest.register_node("industrialtest:rubber_leaves",definition)
if industrialtest.mtgAvailable then
	default.register_leafdecay({
		trunks={"industrialtest:rubber_wood"},
		leaves={"industrialtest:rubber_leaves"},
		radius=2
	})
end
if industrialtest.mclAvailable then
	definition=table.copy(definition)
	definition._doc_items_create_entry=false
	definition.groups.not_in_creative_inventory=1
	definition.groups.orphan_leaves=1
	definition._mcl_shears_drop={"industrialtest:rubber_leaves"}
	definition._mcl_silk_touch_drop={"industrialtest:rubber_leaves"}
	minetest.register_node("industrialtest:rubber_leaves_orphan",definition)
end
industrialtest.makeRubberTree=function(pos)
	-- FIXME: Replace this with placing schematic
	-- Taken and adapted from https://github.com/minetest/minetest_game/blob/master/mods/default/trees.lua#L182
	local height=industrialtest.random:next(4,5)
	local tree=minetest.get_content_id("industrialtest:rubber_wood")
	local treeWithRubber=minetest.get_content_id("industrialtest:rubber_wood_with_rubber")
	local leaves=minetest.get_content_id("industrialtest:rubber_leaves")
	local air=minetest.get_content_id("air")
	local ignore=minetest.get_content_id("ignore")

	local manip=minetest.get_voxel_manip()
	local minp,maxp=manip:read_from_map(vector.new(pos.x-2,pos.y,pos.z),vector.new(pos.x+2,pos.y+height+1,pos.z+2))
	local area=VoxelArea:new({
			MinEdge=minp,
			MaxEdge=maxp
	})
	local data=manip:get_data()

	-- Trunk
	data[area:index(pos.x,pos.y,pos.z)]=tree
	for y=pos.y+1,pos.y+height-1 do
		local index=area:index(pos.x,y,pos.z)
		local id=data[index]
		if id==air or id==ignore or id==leaves then
			data[index]=(industrialtest.random:next(0,5)==1 and treeWithRubber or tree)
		end
	end
	-- Force leaves near the trunk
	for dz=-1,1 do
		for dy=-2,1 do
			local index=area:index(pos.x-1,pos.y+height+dy,pos.z+dz)
			for dx=-1,1 do
				if data[index]==air or data[index]==ignore then
					data[index]=leaves
				end
				index=index+1
			end
		end
	end
	-- Randomly add leaves in 2x2x2 clusters.
	for i=1,8 do
		local x=pos.x+industrialtest.random:next(-2,1)
		local y=pos.y+height+industrialtest.random:next(-2,0)
		local z=pos.z+industrialtest.random:next(-2,1)
		for dx=0,1 do
			for dy=0,1 do
				for dz=0,1 do
					local index=area:index(x+dx,y+dy,z+dz)
					if data[index]==air or data[index]==ignore then
						data[index]=leaves
					end
				end
			end
		end
	end

	manip:set_data(data)
	manip:write_to_map()
	manip:update_map()
end
definition={
	description=S("Rubber Sapling"),
	inventory_image="industrialtest_rubber_sapling.png",
	wield_image="industrialtest_rubber_sapling.png",
	drawtype="plantlike",
	tiles={"industrialtest_rubber_sapling.png"},
	paramtype="light",
	sunlight_propagates=true,
	walkable=false,
	waving=1,
	on_timer=function(pos)
		-- Use MTG can_grow function if available
		local canGrow
		if industrialtest.mtgAvailable then
			canGrow=default.can_grow
		elseif industrialtest.mclAvailable then
			canGrow=function(pos)
				local under=minetest.get_node_or_nil(vector.offset(pos,0,-1,0))
				if not under then
					return false
				end
				local lightLevel=minetest.get_node_light(pos)
				return (minetest.get_item_group(under.name,"soil")>0 and lightLevel and lightLevel>=13)
			end
		end

		if not canGrow(pos) then
			minetest.get_node_timer(pos):start(300)
			return false
		end

		industrialtest.makeRubberTree(pos)

		return false
	end
}
if industrialtest.mtgAvailable then
	definition.sounds=default.node_sound_leaves_defaults()
	definition.groups={
		snappy=2,
		flammable=2
	}
	definition.on_construct=function(pos)
		minetest.get_node_timer(pos):start(industrialtest.random:next(300,1500))
	end
elseif industrialtest.mclAvailable then
	definition.sounds=mcl_sounds.node_sound_leaves_defaults()
	definition.groups={
		plant=1,
		non_mycelium_plant=1,
		deco_block=1,
		dig_by_water=1,
		dig_by_piston=1,
		destroy_by_lava_flow=1,
		compostability=40
	}
	definition.on_construct=function(pos)
		local meta=minetest.get_meta(pos)
		meta:set_int("stage",0)
	end
end
definition.groups.attached_node=1
definition.groups.dig_immediate=3
definition.groups.sapling=1
minetest.register_node("industrialtest:rubber_sapling",definition)
if industrialtest.mtgAvailable then
	minetest.register_lbm({
		name="industrialtest:rubber_sapling_lbm",
		nodenames={"industrialtest:rubber_sapling"},
		action=function(pos)
			minetest.get_node_timer(pos):start(industrialtest.random:next(300,1500))
		end
	})
end