Compare commits
	
		
			17 Commits
		
	
	
		
			bce5306abe
			...
			9b7c44b453
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					9b7c44b453 | ||
| 
						 | 
					86e083c409 | ||
| 
						 | 
					21e044478e | ||
| 
						 | 
					521c0b74bb | ||
| 
						 | 
					aad1b2875a | ||
| 
						 | 
					66e20a9231 | ||
| 
						 | 
					705961e2fe | ||
| 
						 | 
					6a9dfec36f | ||
| 
						 | 
					d4609f23f2 | ||
| 
						 | 
					091bb2406d | ||
| 
						 | 
					c40189eabf | ||
| 
						 | 
					f61bb82bd1 | ||
| 
						 | 
					7d39136764 | ||
| 
						 | 
					4775d98fb7 | ||
| 
						 | 
					d623715d94 | ||
| 
						 | 
					718a5beda1 | ||
| 
						 | 
					fa39b24ed5 | 
							
								
								
									
										9
									
								
								concrete/locale/ja.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,9 @@
 | 
			
		||||
# technic_concrete japanese translation
 | 
			
		||||
# technic_concreteの日本語への翻訳
 | 
			
		||||
# by damiemk
 | 
			
		||||
 | 
			
		||||
Rebar = 鉄筋
 | 
			
		||||
Concrete Block = コンクリートのブロック
 | 
			
		||||
Blast-resistant Concrete Block = 耐爆性コンクリートのブロック
 | 
			
		||||
Concrete Post Platform = コンクリートのプラットフォーム
 | 
			
		||||
Concrete Post = コンクリートポスト
 | 
			
		||||
							
								
								
									
										8
									
								
								extranodes/locale/ja.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,8 @@
 | 
			
		||||
# technic_extranodes japanese translation
 | 
			
		||||
# technic_extranodesの日本語への翻訳
 | 
			
		||||
# by damiemk
 | 
			
		||||
 | 
			
		||||
Marble = 大理石
 | 
			
		||||
Marble Bricks = 大理石のレンガ
 | 
			
		||||
Granite = 花崗岩
 | 
			
		||||
Concrete = コンクリート
 | 
			
		||||
							
								
								
									
										104
									
								
								manual.md
									
									
									
									
									
								
							
							
						
						@@ -34,6 +34,11 @@ Note ¹: *These ores are provided by Minetest Game. See [Ores](https://wiki.mine
 | 
			
		||||
 | 
			
		||||
Note ²: *These ores are provided by moreores. TODO: Add reference link*
 | 
			
		||||
 | 
			
		||||
#### Chromium
 | 
			
		||||
Use: stainless steel
 | 
			
		||||
 | 
			
		||||
Generated below: -100m, more commonly below -200m
 | 
			
		||||
 | 
			
		||||
#### Coal ¹
 | 
			
		||||
Use: Fuel, alloy as carbon
 | 
			
		||||
 | 
			
		||||
@@ -41,33 +46,61 @@ Burning coal is a way to generate electrical power. Coal is also used,
 | 
			
		||||
usually in dust form, as an ingredient in alloying recipes, wherever
 | 
			
		||||
elemental carbon is required.
 | 
			
		||||
 | 
			
		||||
#### Iron ¹
 | 
			
		||||
Use: multiple, mainly for alloys with carbon (coal).
 | 
			
		||||
 | 
			
		||||
#### Copper ¹
 | 
			
		||||
Copper is a common metal, used either on its own for its electrical
 | 
			
		||||
conductivity, or as the base component of alloys.
 | 
			
		||||
Although common, it is very heavily used, and most of the time it will
 | 
			
		||||
be the material that most limits your activity.
 | 
			
		||||
 | 
			
		||||
#### Diamond ¹
 | 
			
		||||
Use: mainly for cutting machines
 | 
			
		||||
 | 
			
		||||
Diamond is a precious gemstone. It is used moderately, mainly for reasons
 | 
			
		||||
connected to its extreme hardness.
 | 
			
		||||
 | 
			
		||||
#### Gold ¹
 | 
			
		||||
Use: various
 | 
			
		||||
 | 
			
		||||
Generated below: -64m, more commonly below -256m
 | 
			
		||||
 | 
			
		||||
Gold is a precious metal. It is most notably used in electrical items due to
 | 
			
		||||
its combination of good conductivity and corrosion resistance.
 | 
			
		||||
 | 
			
		||||
#### Iron ¹
 | 
			
		||||
Use: multiple, mainly for alloys with carbon (coal).
 | 
			
		||||
 | 
			
		||||
#### Lead
 | 
			
		||||
Use: batteries, HV nuclear reactor layout
 | 
			
		||||
 | 
			
		||||
Generated below: 16m, more common below -128m
 | 
			
		||||
 | 
			
		||||
#### Mese ¹
 | 
			
		||||
Use: various
 | 
			
		||||
 | 
			
		||||
Mese is a precious gemstone, and unlike diamond it is entirely fictional.
 | 
			
		||||
It is used in small quantities, wherever some magic needs to be imparted.
 | 
			
		||||
 | 
			
		||||
#### Mithril ²
 | 
			
		||||
Use: chests
 | 
			
		||||
 | 
			
		||||
Generated below: -512m, evenly common
 | 
			
		||||
 | 
			
		||||
Mithril is a fictional ore, being derived from J. R. R. Tolkien's
 | 
			
		||||
Middle-Earth setting.  It is little used.
 | 
			
		||||
 | 
			
		||||
#### Silver ²
 | 
			
		||||
Use: conductors
 | 
			
		||||
 | 
			
		||||
Generated below: -2m, evenly common
 | 
			
		||||
 | 
			
		||||
Silver is a semi-precious metal and is the best conductor of all the pure elements.
 | 
			
		||||
 | 
			
		||||
#### Tin ¹
 | 
			
		||||
Use: batteries, bronze
 | 
			
		||||
 | 
			
		||||
Tin is a common metal but is used rarely. Its abundance is well in excess
 | 
			
		||||
of its usage, so you will usually have a surplus of it.
 | 
			
		||||
 | 
			
		||||
#### Zinc
 | 
			
		||||
Use: brass
 | 
			
		||||
 | 
			
		||||
Generated below: 2m, more commonly below -32m
 | 
			
		||||
 | 
			
		||||
Zinc only has a few uses but is a common metal.
 | 
			
		||||
 | 
			
		||||
#### Chromium
 | 
			
		||||
Use: stainless steel
 | 
			
		||||
 | 
			
		||||
Generated below: -100m, more commonly below -200m
 | 
			
		||||
 | 
			
		||||
#### Uranium
 | 
			
		||||
Use: nuclear reactor fuel
 | 
			
		||||
 | 
			
		||||
@@ -79,40 +112,13 @@ shielding materials available.
 | 
			
		||||
 | 
			
		||||
Keep a safety distance of a meter to avoid being harmed by radiation.
 | 
			
		||||
 | 
			
		||||
#### Silver ²
 | 
			
		||||
Use: conductors
 | 
			
		||||
#### Zinc
 | 
			
		||||
Use: brass
 | 
			
		||||
 | 
			
		||||
Generated below: -2m, evenly common
 | 
			
		||||
Generated below: 2m, more commonly below -32m
 | 
			
		||||
 | 
			
		||||
Silver is a semi-precious metal and is the best conductor of all the pure elements.
 | 
			
		||||
Zinc only has a few uses but is a common metal.
 | 
			
		||||
 | 
			
		||||
#### Gold ¹
 | 
			
		||||
Use: various
 | 
			
		||||
 | 
			
		||||
Generated below: -64m, more commonly below -256m
 | 
			
		||||
 | 
			
		||||
Gold is a precious metal. It is most notably used in electrical items due to
 | 
			
		||||
its combination of good conductivity and corrosion resistance.
 | 
			
		||||
 | 
			
		||||
#### Mithril ²
 | 
			
		||||
Use: chests
 | 
			
		||||
 | 
			
		||||
Generated below: -512m, evenly common
 | 
			
		||||
 | 
			
		||||
Mithril is a fictional ore, being derived from J. R. R. Tolkien's
 | 
			
		||||
Middle-Earth setting.  It is little used.
 | 
			
		||||
 | 
			
		||||
#### Mese ¹
 | 
			
		||||
Use: various
 | 
			
		||||
 | 
			
		||||
Mese is a precious gemstone, and unlike diamond it is entirely fictional.
 | 
			
		||||
It is used in small quantities, wherever some magic needs to be imparted.
 | 
			
		||||
 | 
			
		||||
#### Diamond ¹
 | 
			
		||||
Use: mainly for cutting machines
 | 
			
		||||
 | 
			
		||||
Diamond is a precious gemstone. It is used moderately, mainly for reasons
 | 
			
		||||
connected to its extreme hardness.
 | 
			
		||||
 | 
			
		||||
### 2.2 Rocks
 | 
			
		||||
 | 
			
		||||
@@ -136,6 +142,12 @@ Granite is found in dense clusters and is much harder to dig than standard
 | 
			
		||||
stone. It has mainly decorative use, but also appears in a couple of
 | 
			
		||||
machine recipes.
 | 
			
		||||
 | 
			
		||||
#### Sulfur
 | 
			
		||||
Uses: battery box
 | 
			
		||||
 | 
			
		||||
Sulur is generated around some lava patches (caves).
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
### 2.3 Rubber
 | 
			
		||||
Rubber is a biologically-derived material that has industrial uses due
 | 
			
		||||
to its electrical resistivity and its impermeability.  In technic, it
 | 
			
		||||
 
 | 
			
		||||
@@ -1 +1,3 @@
 | 
			
		||||
name = technic
 | 
			
		||||
description = technic
 | 
			
		||||
min_minetest_version = 5.0
 | 
			
		||||
 
 | 
			
		||||
@@ -1,14 +1,16 @@
 | 
			
		||||
Technic
 | 
			
		||||
=======
 | 
			
		||||
# Technic (main mod)
 | 
			
		||||
 | 
			
		||||
License
 | 
			
		||||
-------
 | 
			
		||||
 | 
			
		||||
## License
 | 
			
		||||
 | 
			
		||||
### Code
 | 
			
		||||
 | 
			
		||||
Copyright (C) 2012-2014 Maciej Kasatkin (RealBadAngel)
 | 
			
		||||
 | 
			
		||||
Technic chests code is licensed under the GNU LGPLv2+.
 | 
			
		||||
 | 
			
		||||
Texture licenses:
 | 
			
		||||
 | 
			
		||||
### Textures
 | 
			
		||||
 | 
			
		||||
BlockMen modified by Zefram (CC BY-SA 3.0):
 | 
			
		||||
  * technic_chernobylite_block.png
 | 
			
		||||
@@ -24,15 +26,29 @@ sdzen (Elise Staudter) (CC BY-SA 3.0):
 | 
			
		||||
leftshift (CC BY-SA 3.0):
 | 
			
		||||
  * technic_river_water_can.png
 | 
			
		||||
 | 
			
		||||
Neuromancer vis Minetest Game (CC BY-SA 3.0)
 | 
			
		||||
 * `technic_*_electric_furnace_*.png` (derived)
 | 
			
		||||
 | 
			
		||||
[LB Photo Realism Reload](https://www.curseforge.com/minecraft/texture-packs/lb-photo-realism-reload) (CC 0)
 | 
			
		||||
 * `technic_geothermal_*.png` (derived)
 | 
			
		||||
 * `technic_water_mill_*.png` (derived)
 | 
			
		||||
 * `technic_*_alloy_furnace_*.png` (derived)
 | 
			
		||||
 * `technic_*_compressor_*.png` (derived)
 | 
			
		||||
 * `technic_*_grinder_*.png` (derived)
 | 
			
		||||
 | 
			
		||||
RealBadAngel: (WTFPL)
 | 
			
		||||
  * Everything else.
 | 
			
		||||
 | 
			
		||||
CC BY-SA 3.0: <http://creativecommons.org/licenses/by-sa/3.0/>
 | 
			
		||||
 | 
			
		||||
Sound licenses:
 | 
			
		||||
### Sounds
 | 
			
		||||
 | 
			
		||||
veikk0 (Veikko Mäkelä) (CC BY-SA 4.0):
 | 
			
		||||
  * technic_hv_nuclear_reactor_siren_danger_loop.ogg
 | 
			
		||||
    * Derived from "Nuclear alarm.wav" by Freesound.org user rene___ from <https://freesound.org/people/rene___/sounds/56778/>. Originally licensed under CC0 1.0 <https://creativecommons.org/publicdomain/zero/1.0/>
 | 
			
		||||
 | 
			
		||||
CC BY-SA 4.0: <https://creativecommons.org/licenses/by-sa/4.0/>
 | 
			
		||||
 | 
			
		||||
### References
 | 
			
		||||
 | 
			
		||||
CC BY-SA 3.0: http://creativecommons.org/licenses/by-sa/3.0/
 | 
			
		||||
 | 
			
		||||
CC BY-SA 4.0: https://creativecommons.org/licenses/by-sa/4.0/
 | 
			
		||||
 
 | 
			
		||||
@@ -35,6 +35,10 @@ Available functions:
 | 
			
		||||
* `technic.is_tier_cable(nodename, tier)`
 | 
			
		||||
	* Tells whether the node `nodename` is the cable of the tier `tier`.
 | 
			
		||||
	* Short version of `technic.get_cable_tier(nodename) == tier`
 | 
			
		||||
* `technic.register_cable_tier(nodename, tier)`
 | 
			
		||||
	* Register user defined cable to list of known tier cables.
 | 
			
		||||
	* `nodename`: string, name of the node
 | 
			
		||||
	* `tier`: string, tier name
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## Machines
 | 
			
		||||
 
 | 
			
		||||
@@ -22,3 +22,6 @@ dofile(path.."/extractor.lua")
 | 
			
		||||
dofile(path.."/compressor.lua")
 | 
			
		||||
 | 
			
		||||
dofile(path.."/music_player.lua")
 | 
			
		||||
-- NEW LV LAMPS
 | 
			
		||||
dofile(path.."/led.lua")
 | 
			
		||||
dofile(path.."/lamp.lua")
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										156
									
								
								technic/machines/LV/lamp.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,156 @@
 | 
			
		||||
 | 
			
		||||
-- LV Lamp
 | 
			
		||||
-- Illuminates a 7x7x3(H) volume below itself with light bright as the sun.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
local S = technic.getter
 | 
			
		||||
 | 
			
		||||
local desc = S("@1 Lamp", S("LV"))
 | 
			
		||||
local active_desc = S("@1 Active", desc)
 | 
			
		||||
local unpowered_desc = S("@1 Unpowered", desc)
 | 
			
		||||
local off_desc = S("@1 Off", desc)
 | 
			
		||||
local demand = 50
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- Invisible light source node used for illumination
 | 
			
		||||
minetest.register_node("technic:dummy_light_source", {
 | 
			
		||||
	description = S("Dummy light source node"),
 | 
			
		||||
	inventory_image = "technic_dummy_light_source.png",
 | 
			
		||||
	wield_image = "technic_dummy_light_source.png",
 | 
			
		||||
	paramtype = "light",
 | 
			
		||||
	drawtype = "airlike",
 | 
			
		||||
	light_source = 14,
 | 
			
		||||
	sunlight_propagates = true,
 | 
			
		||||
	walkable = false,
 | 
			
		||||
	buildable_to = true,
 | 
			
		||||
	diggable = false,
 | 
			
		||||
	pointable = false,
 | 
			
		||||
	--drop = "",  -- Intentionally allowed to drop itself
 | 
			
		||||
	groups = {not_in_creative_inventory = 1}
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
local function illuminate(pos, active)
 | 
			
		||||
	local pos1 = {x = pos.x - 3, y = pos.y - 1, z = pos.z - 3}
 | 
			
		||||
	local pos2 = {x = pos.x + 3, y = pos.y - 3, z = pos.z + 3}
 | 
			
		||||
 | 
			
		||||
	local find_node = active and "air" or "technic:dummy_light_source"
 | 
			
		||||
	local set_node = {name = (active and "technic:dummy_light_source" or "air")}
 | 
			
		||||
 | 
			
		||||
	for _,p in pairs(minetest.find_nodes_in_area(pos1, pos2, find_node)) do
 | 
			
		||||
		minetest.set_node(p, set_node)
 | 
			
		||||
	end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local function lamp_run(pos, node)
 | 
			
		||||
	local meta = minetest.get_meta(pos)
 | 
			
		||||
 | 
			
		||||
	if meta:get_int("LV_EU_demand") == 0 then
 | 
			
		||||
		return  -- Lamp is turned off
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	local eu_input = meta:get_int("LV_EU_input")
 | 
			
		||||
 | 
			
		||||
	if node.name == "technic:lv_lamp_active" then
 | 
			
		||||
		if eu_input < demand then
 | 
			
		||||
			technic.swap_node(pos, "technic:lv_lamp")
 | 
			
		||||
			meta:set_string("infotext", unpowered_desc)
 | 
			
		||||
			illuminate(pos, false)
 | 
			
		||||
		else
 | 
			
		||||
			illuminate(pos, true)
 | 
			
		||||
		end
 | 
			
		||||
	elseif node.name == "technic:lv_lamp" then
 | 
			
		||||
		if eu_input >= demand then
 | 
			
		||||
			technic.swap_node(pos, "technic:lv_lamp_active")
 | 
			
		||||
			meta:set_string("infotext", active_desc)
 | 
			
		||||
			illuminate(pos, true)
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local function lamp_toggle(pos, node, player)
 | 
			
		||||
	if not player or minetest.is_protected(pos, player:get_player_name()) then
 | 
			
		||||
		return
 | 
			
		||||
	end
 | 
			
		||||
	local meta = minetest.get_meta(pos)
 | 
			
		||||
	if meta:get_int("LV_EU_demand") == 0 then
 | 
			
		||||
		meta:set_string("infotext", active_desc)
 | 
			
		||||
		meta:set_int("LV_EU_demand", demand)
 | 
			
		||||
	else
 | 
			
		||||
		illuminate(pos, false)
 | 
			
		||||
		technic.swap_node(pos, "technic:lv_lamp")
 | 
			
		||||
		meta:set_string("infotext", off_desc)
 | 
			
		||||
		meta:set_int("LV_EU_demand", 0)
 | 
			
		||||
	end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local common_fields = {
 | 
			
		||||
	drawtype = "nodebox",
 | 
			
		||||
	node_box = {
 | 
			
		||||
		type = "fixed",
 | 
			
		||||
		fixed = {0.5,0.5,0.5,-0.5,-0.2,-0.5}
 | 
			
		||||
	},
 | 
			
		||||
	tiles = {
 | 
			
		||||
		"technic_lv_lamp_top.png",
 | 
			
		||||
		"technic_lv_lamp_bottom.png",
 | 
			
		||||
		"technic_lv_lamp_side.png",
 | 
			
		||||
		"technic_lv_lamp_side.png",
 | 
			
		||||
		"technic_lv_lamp_side.png",
 | 
			
		||||
		"technic_lv_lamp_side.png"
 | 
			
		||||
	},
 | 
			
		||||
	connect_sides = {"front", "back", "left", "right", "top"},
 | 
			
		||||
	can_dig = technic.machine_can_dig,
 | 
			
		||||
	technic_run = lamp_run,
 | 
			
		||||
	on_destruct = illuminate,
 | 
			
		||||
	on_rightclick = lamp_toggle
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
local ndef
 | 
			
		||||
 | 
			
		||||
ndef = {
 | 
			
		||||
	description = desc,
 | 
			
		||||
	groups = {cracky = 2, technic_machine = 1, technic_lv = 1},
 | 
			
		||||
	on_construct = function(pos)
 | 
			
		||||
		local meta = minetest.get_meta(pos)
 | 
			
		||||
		meta:set_string("infotext", desc)
 | 
			
		||||
		meta:set_int("LV_EU_demand", demand)
 | 
			
		||||
	end
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
for k, v in pairs(common_fields) do
 | 
			
		||||
	ndef[k] = v
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
minetest.register_node("technic:lv_lamp", ndef)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
ndef = {
 | 
			
		||||
	description = active_desc,
 | 
			
		||||
	paramtype = "light",
 | 
			
		||||
	light_source = 14,
 | 
			
		||||
	drop = "technic:lv_lamp",
 | 
			
		||||
	groups = {cracky = 2, technic_machine = 1, technic_lv = 1, not_in_creative_inventory = 1},
 | 
			
		||||
	technic_on_disable = function(pos)
 | 
			
		||||
		illuminate(pos, false)
 | 
			
		||||
		technic.swap_node(pos, "technic:lv_lamp")
 | 
			
		||||
	end,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
for k, v in pairs(common_fields) do
 | 
			
		||||
	ndef[k] = v
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
minetest.register_node("technic:lv_lamp_active", ndef)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
technic.register_machine("LV", "technic:lv_lamp", technic.receiver)
 | 
			
		||||
technic.register_machine("LV", "technic:lv_lamp_active", technic.receiver)
 | 
			
		||||
 | 
			
		||||
minetest.register_craft({
 | 
			
		||||
	output = "technic:lv_lamp",
 | 
			
		||||
	recipe = {
 | 
			
		||||
		{"default:glass", "default:glass", "default:glass"},
 | 
			
		||||
		{"technic:lv_led", "technic:lv_led", "technic:lv_led"},
 | 
			
		||||
		{"mesecons_materials:glue", "technic:lv_cable", "mesecons_materials:glue"},
 | 
			
		||||
	}
 | 
			
		||||
})
 | 
			
		||||
							
								
								
									
										95
									
								
								technic/machines/LV/led.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,95 @@
 | 
			
		||||
-- LED
 | 
			
		||||
-- Intended primarily as a core component for LED lamps.
 | 
			
		||||
 | 
			
		||||
local S = technic.getter
 | 
			
		||||
 | 
			
		||||
local desc = S("@1 LED", S("LV"))
 | 
			
		||||
local active_desc = S("@1 Active", desc)
 | 
			
		||||
local unpowered_desc = S("@1 Unpowered", desc)
 | 
			
		||||
local demand = 5
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
local function led_run(pos, node)
 | 
			
		||||
	local meta = minetest.get_meta(pos)
 | 
			
		||||
	local eu_input = meta:get_int("LV_EU_input")
 | 
			
		||||
 | 
			
		||||
	if eu_input < demand and node.name == "technic:lv_led_active" then
 | 
			
		||||
		technic.swap_node(pos, "technic:lv_led")
 | 
			
		||||
		meta:set_string("infotext", unpowered_desc)
 | 
			
		||||
	elseif eu_input >= demand and node.name == "technic:lv_led" then
 | 
			
		||||
		technic.swap_node(pos, "technic:lv_led_active")
 | 
			
		||||
		meta:set_string("infotext", active_desc)
 | 
			
		||||
	end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local common_fields = {
 | 
			
		||||
	drawtype = "nodebox",
 | 
			
		||||
	node_box = {
 | 
			
		||||
		type = "fixed",
 | 
			
		||||
		fixed = {0.5, 0.5, 0.5, -0.5, 0.3, -0.5}
 | 
			
		||||
	},
 | 
			
		||||
	tiles = {
 | 
			
		||||
		"technic_lv_led_top.png",
 | 
			
		||||
		"technic_lv_led.png",
 | 
			
		||||
		"technic_lv_led_side.png",
 | 
			
		||||
		"technic_lv_led_side2.png",
 | 
			
		||||
		"technic_lv_led_side2.png",
 | 
			
		||||
		"technic_lv_led_side2.png",
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	connect_sides = {"front", "back", "left", "right", "top", "bottom"},
 | 
			
		||||
	can_dig = technic.machine_can_dig,
 | 
			
		||||
	technic_run = led_run,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
local ndef
 | 
			
		||||
 | 
			
		||||
ndef = {
 | 
			
		||||
	description = desc,
 | 
			
		||||
	inventory_image = "technic_lv_led_inv.png",
 | 
			
		||||
	sunlight_propagates = true,
 | 
			
		||||
	groups = {cracky = 2, technic_machine = 1, technic_lv = 1},
 | 
			
		||||
 | 
			
		||||
	on_construct = function(pos)
 | 
			
		||||
		local meta = minetest.get_meta(pos)
 | 
			
		||||
		meta:set_string("infotext", desc)
 | 
			
		||||
		meta:set_int("LV_EU_demand", demand)
 | 
			
		||||
	end,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
for k, v in pairs(common_fields) do
 | 
			
		||||
	ndef[k] = v
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
minetest.register_node("technic:lv_led", ndef)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
ndef = {
 | 
			
		||||
	description = active_desc,
 | 
			
		||||
	paramtype = "light",
 | 
			
		||||
	light_source = 9,
 | 
			
		||||
	drop = "technic:lv_led",
 | 
			
		||||
	groups = {cracky = 2, technic_machine = 1, technic_lv = 1, not_in_creative_inventory = 1},
 | 
			
		||||
	technic_on_disable = function(pos)
 | 
			
		||||
		technic.swap_node(pos, "technic:lv_led")
 | 
			
		||||
	end,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
for k, v in pairs(common_fields) do
 | 
			
		||||
	ndef[k] = v
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
minetest.register_node("technic:lv_led_active", ndef)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
technic.register_machine("LV", "technic:lv_led", technic.receiver)
 | 
			
		||||
technic.register_machine("LV", "technic:lv_led_active", technic.receiver)
 | 
			
		||||
 | 
			
		||||
minetest.register_craft({
 | 
			
		||||
	output = "technic:lv_led 2",
 | 
			
		||||
	recipe = {
 | 
			
		||||
		{"", "homedecor:plastic_sheeting", ""},
 | 
			
		||||
		{"homedecor:plastic_sheeting", "technic:doped_silicon_wafer", "homedecor:plastic_sheeting"},
 | 
			
		||||
		{"", "technic:fine_silver_wire", ""},
 | 
			
		||||
	}
 | 
			
		||||
})
 | 
			
		||||
@@ -192,10 +192,10 @@ function technic.register_battery_box(data)
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	local run = function(pos, node)
 | 
			
		||||
		local below = minetest.get_node({x=pos.x, y=pos.y-1, z=pos.z})
 | 
			
		||||
		local meta = minetest.get_meta(pos)
 | 
			
		||||
		local network_id = tonumber(meta:get_string(tier.."_network"))
 | 
			
		||||
 | 
			
		||||
		if not technic.is_tier_cable(below.name, tier) then
 | 
			
		||||
		if not technic.networks[network_id] then
 | 
			
		||||
			meta:set_string("infotext", S("%s Battery Box Has No Network"):format(tier))
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
 
 | 
			
		||||
@@ -11,6 +11,13 @@ function technic.get_cable_tier(name)
 | 
			
		||||
	return cable_tier[name]
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function technic.register_cable_tier(name, tier)
 | 
			
		||||
	assert(technic.machines[tier], "Tier does not exist")
 | 
			
		||||
	assert(type(name) == "string", "Invalid node name")
 | 
			
		||||
 | 
			
		||||
	cable_tier[name] = tier
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local function check_connections(pos)
 | 
			
		||||
	-- Build a table of all machines
 | 
			
		||||
	local machines = {}
 | 
			
		||||
@@ -60,7 +67,7 @@ local function clear_networks(pos)
 | 
			
		||||
				local tier = network.tier
 | 
			
		||||
 | 
			
		||||
				-- Actually add it to the (cached) network
 | 
			
		||||
				-- This is similar to check_node_subp
 | 
			
		||||
				-- !! IMPORTANT: ../switching_station.lua -> check_node_subp() must be kept in sync
 | 
			
		||||
				technic.cables[minetest.hash_node_position(pos)] = network_id
 | 
			
		||||
				pos.visited = 1
 | 
			
		||||
				if technic.is_tier_cable(node.name, tier) then
 | 
			
		||||
@@ -69,7 +76,7 @@ local function clear_networks(pos)
 | 
			
		||||
				elseif technic.machines[tier][node.name] then
 | 
			
		||||
					-- Found a machine
 | 
			
		||||
					local eu_type = technic.machines[tier][node.name]
 | 
			
		||||
					meta:set_string(tier.."_network", minetest.pos_to_string(sw_pos))
 | 
			
		||||
					meta:set_string(tier.."_network", string.format("%.20g", network_id))
 | 
			
		||||
					if     eu_type == technic.producer then
 | 
			
		||||
						table.insert(network.PR_nodes, pos)
 | 
			
		||||
					elseif eu_type == technic.receiver then
 | 
			
		||||
 
 | 
			
		||||
@@ -23,6 +23,8 @@ local recipes = {
 | 
			
		||||
	{"technic:sulfur_lump",        "technic:sulfur_dust 2"},
 | 
			
		||||
	{"default:stone",              "technic:stone_dust"},
 | 
			
		||||
	{"default:sand",               "technic:stone_dust"},
 | 
			
		||||
	{"default:desert_sand",        "technic:stone_dust"},
 | 
			
		||||
	{"default:silver_sand",        "technic:stone_dust"},
 | 
			
		||||
 | 
			
		||||
	-- Other
 | 
			
		||||
	{"default:cobble",           "default:gravel"},
 | 
			
		||||
 
 | 
			
		||||
@@ -120,7 +120,7 @@ local run = function(pos, node, run_stage)
 | 
			
		||||
		return
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	local remain = 0.9
 | 
			
		||||
	local efficiency = 0.9
 | 
			
		||||
	-- Machine information
 | 
			
		||||
	local machine_name  = S("Supply Converter")
 | 
			
		||||
	local meta          = minetest.get_meta(pos)
 | 
			
		||||
@@ -133,7 +133,6 @@ local run = function(pos, node, run_stage)
 | 
			
		||||
		enabled = enabled == "1"
 | 
			
		||||
	end
 | 
			
		||||
	enabled = enabled and (meta:get_int("mesecon_mode") == 0 or meta:get_int("mesecon_effect") ~= 0)
 | 
			
		||||
	local demand = enabled and meta:get_int("power") or 0
 | 
			
		||||
 | 
			
		||||
	local pos_up        = {x=pos.x, y=pos.y+1, z=pos.z}
 | 
			
		||||
	local pos_down      = {x=pos.x, y=pos.y-1, z=pos.z}
 | 
			
		||||
@@ -144,14 +143,37 @@ local run = function(pos, node, run_stage)
 | 
			
		||||
	local to   = technic.get_cable_tier(name_down)
 | 
			
		||||
 | 
			
		||||
	if from and to then
 | 
			
		||||
		local input = meta:get_int(from.."_EU_input")
 | 
			
		||||
		meta:set_int(from.."_EU_demand", demand)
 | 
			
		||||
		-- Get the "to" network switching station for EU demand calculation
 | 
			
		||||
		local network_hash = technic.cables[minetest.hash_node_position(pos_down)]
 | 
			
		||||
		local network = network_hash and minetest.get_position_from_hash(network_hash)
 | 
			
		||||
		local sw_pos = network and {x=network.x,y=network.y+1,z=network.z}
 | 
			
		||||
		local timeout = 0
 | 
			
		||||
		for tier in pairs(technic.machines) do
 | 
			
		||||
			-- Supply converter must be connected to a network
 | 
			
		||||
			timeout = math.max(meta:get_int(tier.."_EU_timeout"), timeout)
 | 
			
		||||
		end
 | 
			
		||||
		if timeout > 0 and sw_pos and minetest.get_node(sw_pos).name == "technic:switching_station" then
 | 
			
		||||
			local sw_meta = minetest.get_meta(sw_pos)
 | 
			
		||||
			local demand = 0
 | 
			
		||||
			if enabled then
 | 
			
		||||
				-- Reverse evaluate the required machine and round to a nice number
 | 
			
		||||
				demand = sw_meta:get_int("ba_demand") + sw_meta:get_int("demand")
 | 
			
		||||
				demand = 100 * math.ceil(demand / efficiency / 100)
 | 
			
		||||
				-- Do not draw more than the limit
 | 
			
		||||
				demand = math.min(demand, meta:get_int("power"))
 | 
			
		||||
			end
 | 
			
		||||
 | 
			
		||||
			local input = meta:get_int(from.."_EU_input") -- actual input
 | 
			
		||||
			meta:set_int(from.."_EU_demand", demand) -- desired input
 | 
			
		||||
			meta:set_int(from.."_EU_supply", 0)
 | 
			
		||||
			meta:set_int(to.."_EU_demand", 0)
 | 
			
		||||
		meta:set_int(to.."_EU_supply", input * remain)
 | 
			
		||||
			meta:set_int(to.."_EU_supply", input * efficiency)
 | 
			
		||||
			meta:set_string("infotext", S("@1 (@2 @3 -> @4 @5)", machine_name,
 | 
			
		||||
				technic.EU_string(input), from,
 | 
			
		||||
			technic.EU_string(input * remain), to))
 | 
			
		||||
				technic.EU_string(input * efficiency), to))
 | 
			
		||||
		else
 | 
			
		||||
			meta:set_string("infotext",S("%s Has No Network"):format(machine_name))
 | 
			
		||||
		end
 | 
			
		||||
	else
 | 
			
		||||
		meta:set_string("infotext", S("%s Has Bad Cabling"):format(machine_name))
 | 
			
		||||
		if to then
 | 
			
		||||
 
 | 
			
		||||
@@ -117,6 +117,7 @@ local function add_cable_node(nodes, pos, network_id, queue)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
-- Generic function to add found connected nodes to the right classification array
 | 
			
		||||
-- !! IMPORTANT: register/cables.lua -> clear_networks() must be kept in sync
 | 
			
		||||
local check_node_subp = function(network, pos, machines, sw_pos, from_below, network_id, queue)
 | 
			
		||||
	technic.get_or_load_node(pos)
 | 
			
		||||
	local name = minetest.get_node(pos).name
 | 
			
		||||
@@ -133,7 +134,9 @@ local check_node_subp = function(network, pos, machines, sw_pos, from_below, net
 | 
			
		||||
 | 
			
		||||
	--dprint(name.." is a "..machines[name])
 | 
			
		||||
	local meta = minetest.get_meta(pos)
 | 
			
		||||
	meta:set_string(network.tier.."_network", minetest.pos_to_string(sw_pos))
 | 
			
		||||
	-- Normal tostring() does not have enough precision, neither does meta:set_int()
 | 
			
		||||
	-- Lua 5.1 bug: Cannot use hexadecimal notation for compression (see LuaJIT #911)
 | 
			
		||||
	meta:set_string(network.tier.."_network", string.format("%.20g", network_id))
 | 
			
		||||
 | 
			
		||||
	if     eu_type == technic.producer then
 | 
			
		||||
		add_network_node(network.PR_nodes, pos, network_id)
 | 
			
		||||
@@ -354,6 +357,8 @@ minetest.register_abm({
 | 
			
		||||
			BA_eu_supply = BA_eu_supply + meta1:get_int(eu_supply_str)
 | 
			
		||||
			BA_eu_demand = BA_eu_demand + meta1:get_int(eu_demand_str)
 | 
			
		||||
		end
 | 
			
		||||
		-- Expose value for the supply converter
 | 
			
		||||
		meta:set_int("ba_demand", BA_eu_demand)
 | 
			
		||||
		--dprint("Total BA supply:"..BA_eu_supply)
 | 
			
		||||
		--dprint("Total BA demand:"..BA_eu_demand)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								technic/textures/technic_lv_lamp_bottom.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 995 B  | 
							
								
								
									
										
											BIN
										
									
								
								technic/textures/technic_lv_lamp_side.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 1014 B  | 
							
								
								
									
										
											BIN
										
									
								
								technic/textures/technic_lv_lamp_top.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 466 B  | 
							
								
								
									
										
											BIN
										
									
								
								technic/textures/technic_lv_led.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 738 B  | 
							
								
								
									
										
											BIN
										
									
								
								technic/textures/technic_lv_led_inv.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 429 B  | 
							
								
								
									
										
											BIN
										
									
								
								technic/textures/technic_lv_led_side.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 245 B  | 
							
								
								
									
										
											BIN
										
									
								
								technic/textures/technic_lv_led_side2.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 253 B  | 
							
								
								
									
										
											BIN
										
									
								
								technic/textures/technic_lv_led_top.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 466 B  | 
| 
		 Before Width: | Height: | Size: 916 B After Width: | Height: | Size: 775 B  | 
| 
		 Before Width: | Height: | Size: 346 B After Width: | Height: | Size: 344 B  | 
| 
		 Before Width: | Height: | Size: 501 B After Width: | Height: | Size: 205 B  | 
@@ -1,338 +1,217 @@
 | 
			
		||||
-- Configuration
 | 
			
		||||
 | 
			
		||||
local chainsaw_max_charge      = 30000 -- Maximum charge of the saw
 | 
			
		||||
-- Gives 2500 nodes on a single charge (about 50 complete normal trees)
 | 
			
		||||
local chainsaw_charge_per_node = 12
 | 
			
		||||
-- Cut down tree leaves.  Leaf decay may cause slowness on large trees
 | 
			
		||||
-- if this is disabled.
 | 
			
		||||
local chainsaw_leaves = true
 | 
			
		||||
 | 
			
		||||
-- First value is node name; second is whether the node is considered even if chainsaw_leaves is false.
 | 
			
		||||
local nodes = {
 | 
			
		||||
	-- The default trees
 | 
			
		||||
	{"default:acacia_tree", true},
 | 
			
		||||
	{"default:aspen_tree", true},
 | 
			
		||||
	{"default:jungletree", true},
 | 
			
		||||
	{"default:papyrus", true},
 | 
			
		||||
	{"default:cactus", true},
 | 
			
		||||
	{"default:tree", true},
 | 
			
		||||
	{"default:apple", true},
 | 
			
		||||
	{"default:pine_tree", true},
 | 
			
		||||
	{"default:acacia_leaves", false},
 | 
			
		||||
	{"default:aspen_leaves", false},
 | 
			
		||||
	{"default:leaves", false},
 | 
			
		||||
	{"default:jungleleaves", false},
 | 
			
		||||
	{"default:pine_needles", false},
 | 
			
		||||
local chainsaw_efficiency = 0.95 -- Drops less items
 | 
			
		||||
 | 
			
		||||
	-- The default bushes
 | 
			
		||||
	{"default:acacia_bush_stem", true},
 | 
			
		||||
	{"default:bush_stem", true},
 | 
			
		||||
	{"default:pine_bush_stem", true},
 | 
			
		||||
	{"default:acacia_bush_leaves", false},
 | 
			
		||||
	{"default:blueberry_bush_leaves", false},
 | 
			
		||||
	{"default:blueberry_bush_leaves_with_berries", false},
 | 
			
		||||
	{"default:bush_leaves", false},
 | 
			
		||||
	{"default:pine_bush_needles", false},
 | 
			
		||||
 | 
			
		||||
	-- Rubber trees from moretrees or technic_worldgen if moretrees isn't installed
 | 
			
		||||
	{"moretrees:rubber_tree_trunk_empty", true},
 | 
			
		||||
	{"moretrees:rubber_tree_trunk", true},
 | 
			
		||||
	{"moretrees:rubber_tree_leaves", false},
 | 
			
		||||
 | 
			
		||||
	-- Support moretrees (trunk)
 | 
			
		||||
	{"moretrees:acacia_trunk", true},
 | 
			
		||||
	{"moretrees:apple_tree_trunk", true},
 | 
			
		||||
	{"moretrees:beech_trunk", true},
 | 
			
		||||
	{"moretrees:birch_trunk", true},
 | 
			
		||||
	{"moretrees:cedar_trunk", true},
 | 
			
		||||
	{"moretrees:date_palm_ffruit_trunk", true},
 | 
			
		||||
	{"moretrees:date_palm_fruit_trunk", true},
 | 
			
		||||
	{"moretrees:date_palm_mfruit_trunk", true},
 | 
			
		||||
	{"moretrees:date_palm_trunk", true},
 | 
			
		||||
	{"moretrees:fir_trunk", true},
 | 
			
		||||
	{"moretrees:jungletree_trunk", true},
 | 
			
		||||
	{"moretrees:oak_trunk", true},
 | 
			
		||||
	{"moretrees:palm_trunk", true},
 | 
			
		||||
	{"moretrees:palm_fruit_trunk", true},
 | 
			
		||||
	{"moretrees:palm_fruit_trunk_gen", true},
 | 
			
		||||
	{"moretrees:pine_trunk", true},
 | 
			
		||||
	{"moretrees:poplar_trunk", true},
 | 
			
		||||
	{"moretrees:sequoia_trunk", true},
 | 
			
		||||
	{"moretrees:spruce_trunk", true},
 | 
			
		||||
	{"moretrees:willow_trunk", true},
 | 
			
		||||
	-- Support moretrees (leaves)
 | 
			
		||||
	{"moretrees:acacia_leaves", false},
 | 
			
		||||
	{"moretrees:apple_tree_leaves", false},
 | 
			
		||||
	{"moretrees:beech_leaves", false},
 | 
			
		||||
	{"moretrees:birch_leaves", false},
 | 
			
		||||
	{"moretrees:cedar_leaves", false},
 | 
			
		||||
	{"moretrees:date_palm_leaves", false},
 | 
			
		||||
	{"moretrees:fir_leaves", false},
 | 
			
		||||
	{"moretrees:fir_leaves_bright", false},
 | 
			
		||||
	{"moretrees:jungletree_leaves_green", false},
 | 
			
		||||
	{"moretrees:jungletree_leaves_yellow", false},
 | 
			
		||||
	{"moretrees:jungletree_leaves_red", false},
 | 
			
		||||
	{"moretrees:oak_leaves", false},
 | 
			
		||||
	{"moretrees:palm_leaves", false},
 | 
			
		||||
	{"moretrees:poplar_leaves", false},
 | 
			
		||||
	{"moretrees:pine_leaves", false},
 | 
			
		||||
	{"moretrees:sequoia_leaves", false},
 | 
			
		||||
	{"moretrees:spruce_leaves", false},
 | 
			
		||||
	{"moretrees:willow_leaves", false},
 | 
			
		||||
	-- Support moretrees (fruit)
 | 
			
		||||
	{"moretrees:acorn", false},
 | 
			
		||||
	{"moretrees:apple_blossoms", false},
 | 
			
		||||
	{"moretrees:cedar_cone", false},
 | 
			
		||||
	{"moretrees:coconut", false},
 | 
			
		||||
	{"moretrees:coconut_0", false},
 | 
			
		||||
	{"moretrees:coconut_1", false},
 | 
			
		||||
	{"moretrees:coconut_2", false},
 | 
			
		||||
	{"moretrees:coconut_3", false},
 | 
			
		||||
	{"moretrees:dates_f0", false},
 | 
			
		||||
	{"moretrees:dates_f1", false},
 | 
			
		||||
	{"moretrees:dates_f2", false},
 | 
			
		||||
	{"moretrees:dates_f3", false},
 | 
			
		||||
	{"moretrees:dates_f4", false},
 | 
			
		||||
	{"moretrees:dates_fn", false},
 | 
			
		||||
	{"moretrees:dates_m0", false},
 | 
			
		||||
	{"moretrees:dates_n", false},
 | 
			
		||||
	{"moretrees:fir_cone", false},
 | 
			
		||||
	{"moretrees:pine_cone", false},
 | 
			
		||||
	{"moretrees:spruce_cone", false},
 | 
			
		||||
 | 
			
		||||
	-- Support growing_trees
 | 
			
		||||
	{"growing_trees:trunk", true},
 | 
			
		||||
	{"growing_trees:medium_trunk", true},
 | 
			
		||||
	{"growing_trees:big_trunk", true},
 | 
			
		||||
	{"growing_trees:trunk_top", true},
 | 
			
		||||
	{"growing_trees:trunk_sprout", true},
 | 
			
		||||
	{"growing_trees:branch_sprout", true},
 | 
			
		||||
	{"growing_trees:branch", true},
 | 
			
		||||
	{"growing_trees:branch_xmzm", true},
 | 
			
		||||
	{"growing_trees:branch_xpzm", true},
 | 
			
		||||
	{"growing_trees:branch_xmzp", true},
 | 
			
		||||
	{"growing_trees:branch_xpzp", true},
 | 
			
		||||
	{"growing_trees:branch_zz", true},
 | 
			
		||||
	{"growing_trees:branch_xx", true},
 | 
			
		||||
	{"growing_trees:leaves", false},
 | 
			
		||||
 | 
			
		||||
	-- Support cool_trees
 | 
			
		||||
	{"bamboo:trunk", true},
 | 
			
		||||
	{"bamboo:leaves", false},
 | 
			
		||||
	{"birch:trunk", true},
 | 
			
		||||
	{"birch:leaves", false},
 | 
			
		||||
	{"cherrytree:trunk", true},
 | 
			
		||||
	{"cherrytree:blossom_leaves", false},
 | 
			
		||||
	{"cherrytree:leaves", false},
 | 
			
		||||
	{"chestnuttree:trunk", true},
 | 
			
		||||
	{"chestnuttree:leaves", false},
 | 
			
		||||
	{"clementinetree:trunk", true},
 | 
			
		||||
	{"clementinetree:leaves", false},
 | 
			
		||||
	{"ebony:trunk", true},
 | 
			
		||||
	{"ebony:creeper", false},
 | 
			
		||||
	{"ebony:creeper_leaves", false},
 | 
			
		||||
	{"ebony:leaves", false},
 | 
			
		||||
	{"jacaranda:trunk", true},
 | 
			
		||||
	{"jacaranda:blossom_leaves", false},
 | 
			
		||||
	{"larch:trunk", true},
 | 
			
		||||
	{"larch:leaves", false},
 | 
			
		||||
	{"lemontree:trunk", true},
 | 
			
		||||
	{"lemontree:leaves", false},
 | 
			
		||||
	{"mahogany:trunk", true},
 | 
			
		||||
	{"mahogany:leaves", false},
 | 
			
		||||
	{"palm:trunk", true},
 | 
			
		||||
	{"palm:leaves", false},
 | 
			
		||||
 | 
			
		||||
	-- Support growing_cactus
 | 
			
		||||
	{"growing_cactus:sprout", true},
 | 
			
		||||
	{"growing_cactus:branch_sprout_vertical", true},
 | 
			
		||||
	{"growing_cactus:branch_sprout_vertical_fixed", true},
 | 
			
		||||
	{"growing_cactus:branch_sprout_xp", true},
 | 
			
		||||
	{"growing_cactus:branch_sprout_xm", true},
 | 
			
		||||
	{"growing_cactus:branch_sprout_zp", true},
 | 
			
		||||
	{"growing_cactus:branch_sprout_zm", true},
 | 
			
		||||
	{"growing_cactus:trunk", true},
 | 
			
		||||
	{"growing_cactus:branch_trunk", true},
 | 
			
		||||
	{"growing_cactus:branch", true},
 | 
			
		||||
	{"growing_cactus:branch_xp", true},
 | 
			
		||||
	{"growing_cactus:branch_xm", true},
 | 
			
		||||
	{"growing_cactus:branch_zp", true},
 | 
			
		||||
	{"growing_cactus:branch_zm", true},
 | 
			
		||||
	{"growing_cactus:branch_zz", true},
 | 
			
		||||
	{"growing_cactus:branch_xx", true},
 | 
			
		||||
 | 
			
		||||
	-- Support farming_plus
 | 
			
		||||
	{"farming_plus:banana_leaves", false},
 | 
			
		||||
	{"farming_plus:banana", false},
 | 
			
		||||
	{"farming_plus:cocoa_leaves", false},
 | 
			
		||||
	{"farming_plus:cocoa", false},
 | 
			
		||||
 | 
			
		||||
	-- Support nature
 | 
			
		||||
	{"nature:blossom", false},
 | 
			
		||||
 | 
			
		||||
	-- Support snow
 | 
			
		||||
	{"snow:needles", false},
 | 
			
		||||
	{"snow:needles_decorated", false},
 | 
			
		||||
	{"snow:star", false},
 | 
			
		||||
 | 
			
		||||
	-- Support vines (also generated by moretrees if available)
 | 
			
		||||
	{"vines:vines", false},
 | 
			
		||||
 | 
			
		||||
	{"trunks:moss", false},
 | 
			
		||||
	{"trunks:moss_fungus", false},
 | 
			
		||||
	{"trunks:treeroot", false},
 | 
			
		||||
 | 
			
		||||
	-- Support ethereal
 | 
			
		||||
	{"ethereal:bamboo", true},
 | 
			
		||||
	{"ethereal:bamboo_leaves", false},
 | 
			
		||||
	{"ethereal:banana_trunk", true},
 | 
			
		||||
	{"ethereal:bananaleaves", false},
 | 
			
		||||
	{"ethereal:banana", false},
 | 
			
		||||
	{"ethereal:birch_trunk", true},
 | 
			
		||||
	{"ethereal:birch_leaves", false},
 | 
			
		||||
	{"ethereal:frost_tree", true},
 | 
			
		||||
	{"ethereal:frost_leaves", false},
 | 
			
		||||
	{"ethereal:mushroom_trunk", true},
 | 
			
		||||
	{"ethereal:mushroom", false},
 | 
			
		||||
	{"ethereal:mushroom_pore", true},
 | 
			
		||||
	{"ethereal:orangeleaves", false},
 | 
			
		||||
	{"ethereal:orange", false},
 | 
			
		||||
	{"ethereal:palm_trunk", true},
 | 
			
		||||
	{"ethereal:palmleaves", false},
 | 
			
		||||
	{"ethereal:coconut", false},
 | 
			
		||||
	{"ethereal:redwood_trunk", true},
 | 
			
		||||
	{"ethereal:redwood_leaves", false},
 | 
			
		||||
	{"ethereal:sakura_trunk", true},
 | 
			
		||||
	{"ethereal:sakura_leaves", false},
 | 
			
		||||
	{"ethereal:sakura_leaves2", false},
 | 
			
		||||
	{"ethereal:scorched_tree", true},
 | 
			
		||||
	{"ethereal:willow_trunk", true},
 | 
			
		||||
	{"ethereal:willow_twig", false},
 | 
			
		||||
	{"ethereal:yellow_trunk", true},
 | 
			
		||||
	{"ethereal:yellowleaves", false},
 | 
			
		||||
	{"ethereal:golden_apple", false},
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
local timber_nodenames = {}
 | 
			
		||||
for _, node in pairs(nodes) do
 | 
			
		||||
	if chainsaw_leaves or node[2] then
 | 
			
		||||
		timber_nodenames[node[1]] = true
 | 
			
		||||
	end
 | 
			
		||||
end
 | 
			
		||||
-- Maximal dimensions of the tree to cut
 | 
			
		||||
local tree_max_radius = 10
 | 
			
		||||
local tree_max_height = 70
 | 
			
		||||
 | 
			
		||||
local S = technic.getter
 | 
			
		||||
 | 
			
		||||
--[[
 | 
			
		||||
Format: [node_name] = dig_cost
 | 
			
		||||
 | 
			
		||||
This table is filled automatically afterwards to support mods such as:
 | 
			
		||||
 | 
			
		||||
	cool_trees
 | 
			
		||||
	ethereal
 | 
			
		||||
	moretrees
 | 
			
		||||
]]
 | 
			
		||||
local tree_nodes = {
 | 
			
		||||
	-- For the sake of maintenance, keep this sorted alphabetically!
 | 
			
		||||
	["default:acacia_bush_stem"] = -1,
 | 
			
		||||
	["default:bush_stem"] = -1,
 | 
			
		||||
	["default:pine_bush_stem"] = -1,
 | 
			
		||||
 | 
			
		||||
	["default:cactus"] = -1,
 | 
			
		||||
	["default:papyrus"] = -1,
 | 
			
		||||
 | 
			
		||||
	-- dfcaves "fruits"
 | 
			
		||||
	["df_trees:blood_thorn_spike"] = -1,
 | 
			
		||||
	["df_trees:blood_thorn_spike_dead"] = -1,
 | 
			
		||||
	["df_trees:tunnel_tube_fruiting_body"] = -1,
 | 
			
		||||
 | 
			
		||||
	["ethereal:bamboo"] = -1,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
-- Function to decide whether or not to cut a certain node (and at which energy cost)
 | 
			
		||||
local function populate_costs(name, def)
 | 
			
		||||
	repeat
 | 
			
		||||
		if tree_nodes[name] == -1 then
 | 
			
		||||
			tree_nodes[name] = nil
 | 
			
		||||
			break -- Manually added, but need updating
 | 
			
		||||
		end
 | 
			
		||||
		if (def.groups.tree or 0) > 0 then
 | 
			
		||||
			break -- Tree node
 | 
			
		||||
		end
 | 
			
		||||
		if (def.groups.leaves or 0) > 0 and chainsaw_leaves then
 | 
			
		||||
			break -- Leaves
 | 
			
		||||
		end
 | 
			
		||||
		if (def.groups.leafdecay_drop or 0) > 0 then
 | 
			
		||||
			break -- Food
 | 
			
		||||
		end
 | 
			
		||||
		return -- Abort function: do not dig this node
 | 
			
		||||
 | 
			
		||||
	-- luacheck: push ignore 511
 | 
			
		||||
	until 1
 | 
			
		||||
	-- luacheck: pop
 | 
			
		||||
 | 
			
		||||
	-- Function did not return! --> add content ID to the digging table
 | 
			
		||||
	local content_id = minetest.get_content_id(name)
 | 
			
		||||
 | 
			
		||||
	-- Get 12 in average
 | 
			
		||||
	local cost = 0
 | 
			
		||||
	if def.groups.choppy then
 | 
			
		||||
		cost = def.groups.choppy * 5 -- trunks (usually 3 * 5)
 | 
			
		||||
	elseif def.groups.snappy then
 | 
			
		||||
		cost = def.groups.snappy * 2 -- leaves
 | 
			
		||||
	end
 | 
			
		||||
	tree_nodes[content_id] = math.max(4, cost)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
minetest.register_on_mods_loaded(function()
 | 
			
		||||
	local ndefs = minetest.registered_nodes
 | 
			
		||||
	-- Populate hardcoded nodes
 | 
			
		||||
	for name in pairs(tree_nodes) do
 | 
			
		||||
		local ndef = ndefs[name]
 | 
			
		||||
		if ndef and ndef.groups then
 | 
			
		||||
			populate_costs(name, ndef)
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	-- Find all trees and leaves
 | 
			
		||||
	for name, def in pairs(ndefs) do
 | 
			
		||||
		if def.groups then
 | 
			
		||||
			populate_costs(name, def)
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
end)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
technic.register_power_tool("technic:chainsaw", chainsaw_max_charge)
 | 
			
		||||
 | 
			
		||||
-- This function checks if the specified node should be sawed
 | 
			
		||||
local function check_if_node_sawed(pos)
 | 
			
		||||
	local node_name = minetest.get_node(pos).name
 | 
			
		||||
	if timber_nodenames[node_name]
 | 
			
		||||
			or (chainsaw_leaves and minetest.get_item_group(node_name, "leaves") ~= 0)
 | 
			
		||||
			or minetest.get_item_group(node_name, "tree") ~= 0 then
 | 
			
		||||
		return true
 | 
			
		||||
local pos9dir = {
 | 
			
		||||
	{ 1, 0,  0},
 | 
			
		||||
	{-1, 0,  0},
 | 
			
		||||
	{ 0, 0,  1},
 | 
			
		||||
	{ 0, 0, -1},
 | 
			
		||||
	{ 1, 0,  1},
 | 
			
		||||
	{-1, 0, -1},
 | 
			
		||||
	{ 1, 0, -1},
 | 
			
		||||
	{-1, 0,  1},
 | 
			
		||||
	{ 0, 1,  0}, -- up
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
local cutter = {
 | 
			
		||||
	-- See function cut_tree()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
local c_air = minetest.get_content_id("air")
 | 
			
		||||
local function dig_recursive(x, y, z)
 | 
			
		||||
	local i = cutter.area:index(x, y, z)
 | 
			
		||||
	if cutter.seen[i] then
 | 
			
		||||
		return
 | 
			
		||||
	end
 | 
			
		||||
	cutter.seen[i] = 1 -- Mark as visited
 | 
			
		||||
 | 
			
		||||
	if cutter.param2[i] ~= 0 then
 | 
			
		||||
		-- Do not dig manually placed nodes
 | 
			
		||||
		return
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	return false
 | 
			
		||||
	local c_id = cutter.data[i]
 | 
			
		||||
	local cost = tree_nodes[c_id]
 | 
			
		||||
	if not cost or cost > cutter.charge then
 | 
			
		||||
		return -- Cannot dig this node
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
-- Table for saving what was sawed down
 | 
			
		||||
local produced = {}
 | 
			
		||||
	-- Count dug nodes
 | 
			
		||||
	cutter.drops[c_id] = (cutter.drops[c_id] or 0) + 1
 | 
			
		||||
	cutter.seen[i] = 2 -- Mark as dug (for callbacks)
 | 
			
		||||
	cutter.data[i] = c_air
 | 
			
		||||
	cutter.charge = cutter.charge - cost
 | 
			
		||||
 | 
			
		||||
-- Save the items sawed down so that we can drop them in a nice single stack
 | 
			
		||||
local function handle_drops(drops)
 | 
			
		||||
	for _, item in ipairs(drops) do
 | 
			
		||||
		local stack = ItemStack(item)
 | 
			
		||||
		local name = stack:get_name()
 | 
			
		||||
		local p = produced[name]
 | 
			
		||||
		if not p then
 | 
			
		||||
			produced[name] = stack
 | 
			
		||||
		else
 | 
			
		||||
			p:set_count(p:get_count() + stack:get_count())
 | 
			
		||||
	-- Expand maximal bounds for area protection check
 | 
			
		||||
	if x < cutter.minp.x then cutter.minp.x = x end
 | 
			
		||||
	if y < cutter.minp.y then cutter.minp.y = y end
 | 
			
		||||
	if z < cutter.minp.z then cutter.minp.z = z end
 | 
			
		||||
	if x > cutter.maxp.x then cutter.maxp.x = x end
 | 
			
		||||
	if y > cutter.maxp.y then cutter.maxp.y = y end
 | 
			
		||||
	if z > cutter.maxp.z then cutter.maxp.z = z end
 | 
			
		||||
 | 
			
		||||
	-- Traverse neighbors
 | 
			
		||||
	local xn, yn, zn
 | 
			
		||||
	for _, offset in ipairs(pos9dir) do
 | 
			
		||||
		xn, yn, zn = x + offset[1], y + offset[2], z + offset[3]
 | 
			
		||||
		if cutter.area:contains(xn, yn, zn) then
 | 
			
		||||
			 dig_recursive(xn, yn, zn)
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
--- Iterator over positions to try to saw around a sawed node.
 | 
			
		||||
-- This returns positions in a 3x1x3 area around the position, plus the
 | 
			
		||||
-- position above it.  This does not return the bottom position to prevent
 | 
			
		||||
-- the chainsaw from cutting down nodes below the cutting position.
 | 
			
		||||
-- @param pos Sawing position.
 | 
			
		||||
local function iterSawTries(pos)
 | 
			
		||||
	-- Copy position to prevent mangling it
 | 
			
		||||
	local pos = vector.new(pos)
 | 
			
		||||
	local i = 0
 | 
			
		||||
local handle_drops
 | 
			
		||||
 | 
			
		||||
	return function()
 | 
			
		||||
		i = i + 1
 | 
			
		||||
		-- Given a (top view) area like so (where 5 is the starting position):
 | 
			
		||||
		-- X -->
 | 
			
		||||
		-- Z 123
 | 
			
		||||
		-- | 456
 | 
			
		||||
		-- V 789
 | 
			
		||||
		-- This will return positions 1, 4, 7, 2, 8 (skip 5), 3, 6, 9,
 | 
			
		||||
		-- and the position above 5.
 | 
			
		||||
		if i == 1 then
 | 
			
		||||
			-- Move to starting position
 | 
			
		||||
			pos.x = pos.x - 1
 | 
			
		||||
			pos.z = pos.z - 1
 | 
			
		||||
		elseif i == 4 or i == 7 then
 | 
			
		||||
			-- Move to next X and back to start of Z when we reach
 | 
			
		||||
			-- the end of a Z line.
 | 
			
		||||
			pos.x = pos.x + 1
 | 
			
		||||
			pos.z = pos.z - 2
 | 
			
		||||
		elseif i == 5 then
 | 
			
		||||
			-- Skip the middle position (we've already run on it)
 | 
			
		||||
			-- and double-increment the counter.
 | 
			
		||||
			pos.z = pos.z + 2
 | 
			
		||||
			i = i + 1
 | 
			
		||||
		elseif i <= 9 then
 | 
			
		||||
			-- Go to next Z.
 | 
			
		||||
			pos.z = pos.z + 1
 | 
			
		||||
		elseif i == 10 then
 | 
			
		||||
			-- Move back to center and up.
 | 
			
		||||
			-- The Y+ position must be last so that we don't dig
 | 
			
		||||
			-- straight upward and not come down (since the Y-
 | 
			
		||||
			-- position isn't checked).
 | 
			
		||||
			pos.x = pos.x - 1
 | 
			
		||||
			pos.z = pos.z - 1
 | 
			
		||||
			pos.y = pos.y + 1
 | 
			
		||||
		else
 | 
			
		||||
			return nil
 | 
			
		||||
		end
 | 
			
		||||
		return pos
 | 
			
		||||
	end
 | 
			
		||||
local function chainsaw_dig(player, pos, remaining_charge)
 | 
			
		||||
	local minp = {
 | 
			
		||||
		x = pos.x - (tree_max_radius + 1),
 | 
			
		||||
		y = pos.y,
 | 
			
		||||
		z = pos.z - (tree_max_radius + 1)
 | 
			
		||||
	}
 | 
			
		||||
	local maxp = {
 | 
			
		||||
		x = pos.x + (tree_max_radius + 1),
 | 
			
		||||
		y = pos.y + tree_max_height,
 | 
			
		||||
		z = pos.z + (tree_max_radius + 1)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	local vm = minetest.get_voxel_manip()
 | 
			
		||||
	local emin, emax = vm:read_from_map(minp, maxp)
 | 
			
		||||
 | 
			
		||||
	cutter = {
 | 
			
		||||
		area = VoxelArea:new{MinEdge=emin, MaxEdge=emax},
 | 
			
		||||
		data = vm:get_data(),
 | 
			
		||||
		param2 = vm:get_param2_data(),
 | 
			
		||||
		seen = {},
 | 
			
		||||
		drops = {}, -- [content_id] = count
 | 
			
		||||
		minp = vector.copy(pos),
 | 
			
		||||
		maxp = vector.copy(pos),
 | 
			
		||||
		charge = remaining_charge
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	dig_recursive(pos.x, pos.y, pos.z)
 | 
			
		||||
 | 
			
		||||
	-- Check protection
 | 
			
		||||
	local player_name = player:get_player_name()
 | 
			
		||||
	if minetest.is_area_protected(cutter.minp, cutter.maxp, player_name, 6) then
 | 
			
		||||
		minetest.chat_send_player(player_name, "The chainsaw cannot cut this tree. The cuboid " ..
 | 
			
		||||
			minetest.pos_to_string(cutter.minp) .. ", " .. minetest.pos_to_string(cutter.maxp) ..
 | 
			
		||||
			" contains protected nodes.")
 | 
			
		||||
		minetest.record_protection_violation(pos, player_name)
 | 
			
		||||
		return
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
-- This function does all the hard work. Recursively we dig the node at hand
 | 
			
		||||
-- if it is in the table and then search the surroundings for more stuff to dig.
 | 
			
		||||
local function recursive_dig(pos, remaining_charge)
 | 
			
		||||
	if remaining_charge < chainsaw_charge_per_node then
 | 
			
		||||
		return remaining_charge
 | 
			
		||||
	end
 | 
			
		||||
	local node = minetest.get_node(pos)
 | 
			
		||||
	minetest.sound_play("chainsaw", {
 | 
			
		||||
		pos = pos,
 | 
			
		||||
		gain = 1.0,
 | 
			
		||||
		max_hear_distance = 20
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	if not check_if_node_sawed(pos) then
 | 
			
		||||
		return remaining_charge
 | 
			
		||||
	end
 | 
			
		||||
	handle_drops(pos)
 | 
			
		||||
 | 
			
		||||
	-- Wood found - cut it
 | 
			
		||||
	handle_drops(minetest.get_node_drops(node.name, ""))
 | 
			
		||||
	minetest.remove_node(pos)
 | 
			
		||||
	remaining_charge = remaining_charge - chainsaw_charge_per_node
 | 
			
		||||
	vm:set_data(cutter.data)
 | 
			
		||||
	vm:write_to_map(true)
 | 
			
		||||
	vm:update_map()
 | 
			
		||||
 | 
			
		||||
	-- Check surroundings and run recursively if any charge left
 | 
			
		||||
	for npos in iterSawTries(pos) do
 | 
			
		||||
		if remaining_charge < chainsaw_charge_per_node then
 | 
			
		||||
			break
 | 
			
		||||
		end
 | 
			
		||||
		if check_if_node_sawed(npos) then
 | 
			
		||||
			remaining_charge = recursive_dig(npos, remaining_charge)
 | 
			
		||||
		else
 | 
			
		||||
			minetest.check_for_falling(npos)
 | 
			
		||||
	-- Update falling nodes
 | 
			
		||||
	for i, status in pairs(cutter.seen) do
 | 
			
		||||
		if status == 2 then -- actually dug
 | 
			
		||||
			minetest.check_for_falling(cutter.area:position(i))
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
	return remaining_charge
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
-- Function to randomize positions for new node drops
 | 
			
		||||
@@ -369,30 +248,50 @@ local function get_drop_pos(pos)
 | 
			
		||||
	return pos
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
-- Chainsaw entry point
 | 
			
		||||
local function chainsaw_dig(pos, current_charge)
 | 
			
		||||
	-- Start sawing things down
 | 
			
		||||
	local remaining_charge = recursive_dig(pos, current_charge)
 | 
			
		||||
	minetest.sound_play("chainsaw", {pos = pos, gain = 1.0,
 | 
			
		||||
			max_hear_distance = 10})
 | 
			
		||||
local drop_inv = minetest.create_detached_inventory("technic:chainsaw_drops", {}, ":technic")
 | 
			
		||||
handle_drops = function(pos)
 | 
			
		||||
	local n_slots = 100
 | 
			
		||||
	drop_inv:set_size("main", n_slots)
 | 
			
		||||
	drop_inv:set_list("main", {})
 | 
			
		||||
 | 
			
		||||
	-- Now drop items for the player
 | 
			
		||||
	for name, stack in pairs(produced) do
 | 
			
		||||
		-- Drop stacks of stack max or less
 | 
			
		||||
		local count, max = stack:get_count(), stack:get_stack_max()
 | 
			
		||||
		stack:set_count(max)
 | 
			
		||||
		while count > max do
 | 
			
		||||
			minetest.add_item(get_drop_pos(pos), stack)
 | 
			
		||||
			count = count - max
 | 
			
		||||
	-- Put all dropped items into the detached inventory
 | 
			
		||||
	for c_id, count in pairs(cutter.drops) do
 | 
			
		||||
		local name = minetest.get_name_from_content_id(c_id)
 | 
			
		||||
 | 
			
		||||
		-- Add drops in bulk -> keep some randomness
 | 
			
		||||
		while count > 0 do
 | 
			
		||||
			local drops = minetest.get_node_drops(name, "")
 | 
			
		||||
			-- higher numbers are faster but return uneven sapling counts
 | 
			
		||||
			local decrement = math.ceil(count * 0.3)
 | 
			
		||||
			decrement = math.min(count, math.max(5, decrement))
 | 
			
		||||
 | 
			
		||||
			for _, stack in ipairs(drops) do
 | 
			
		||||
				stack = ItemStack(stack)
 | 
			
		||||
				local total = math.ceil(stack:get_count() * decrement * chainsaw_efficiency)
 | 
			
		||||
				local stack_max = stack:get_stack_max()
 | 
			
		||||
 | 
			
		||||
				-- Split into full stacks
 | 
			
		||||
				while total > 0 do
 | 
			
		||||
					local size = math.min(total, stack_max)
 | 
			
		||||
					stack:set_count(size)
 | 
			
		||||
					drop_inv:add_item("main", stack)
 | 
			
		||||
					total = total - size
 | 
			
		||||
				end
 | 
			
		||||
			end
 | 
			
		||||
			count = count - decrement
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	-- Drop in random places
 | 
			
		||||
	for i = 1, n_slots do
 | 
			
		||||
		local stack = drop_inv:get_stack("main", i)
 | 
			
		||||
		if stack:is_empty() then
 | 
			
		||||
			break
 | 
			
		||||
		end
 | 
			
		||||
		stack:set_count(count)
 | 
			
		||||
		minetest.add_item(get_drop_pos(pos), stack)
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	-- Clean up
 | 
			
		||||
	produced = {}
 | 
			
		||||
 | 
			
		||||
	return remaining_charge
 | 
			
		||||
	drop_inv:set_size("main", 0) -- free RAM
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -408,8 +307,7 @@ minetest.register_tool("technic:chainsaw", {
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		local meta = minetest.deserialize(itemstack:get_metadata())
 | 
			
		||||
		if not meta or not meta.charge or
 | 
			
		||||
				meta.charge < chainsaw_charge_per_node then
 | 
			
		||||
		if not meta or not meta.charge then
 | 
			
		||||
			return
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
@@ -421,7 +319,11 @@ minetest.register_tool("technic:chainsaw", {
 | 
			
		||||
 | 
			
		||||
		-- Send current charge to digging function so that the
 | 
			
		||||
		-- chainsaw will stop after digging a number of nodes
 | 
			
		||||
		meta.charge = chainsaw_dig(pointed_thing.under, meta.charge)
 | 
			
		||||
		chainsaw_dig(user, pointed_thing.under, meta.charge)
 | 
			
		||||
		meta.charge = cutter.charge
 | 
			
		||||
 | 
			
		||||
		cutter = {} -- Free RAM
 | 
			
		||||
 | 
			
		||||
		if not technic.creative_mode then
 | 
			
		||||
			technic.set_RE_wear(itemstack, meta.charge, chainsaw_max_charge)
 | 
			
		||||
			itemstack:set_metadata(minetest.serialize(meta))
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
technic.chests.groups = {snappy=2, choppy=2, oddly_breakable_by_hand=2,
 | 
			
		||||
		tubedevice=1, tubedevice_receiver=1}
 | 
			
		||||
		tubedevice=1, tubedevice_receiver=1, technic_chest=1}
 | 
			
		||||
technic.chests.groups_noinv = {snappy=2, choppy=2, oddly_breakable_by_hand=2,
 | 
			
		||||
		tubedevice=1, tubedevice_receiver=1, not_in_creative_inventory=1}
 | 
			
		||||
		tubedevice=1, tubedevice_receiver=1, not_in_creative_inventory=1, technic_chest=1}
 | 
			
		||||
 | 
			
		||||
technic.chests.tube = {
 | 
			
		||||
	insert_object = function(pos, node, stack, direction)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										41
									
								
								technic_chests/locale/ja.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,41 @@
 | 
			
		||||
# technic_chests japanese translation
 | 
			
		||||
# technic_chestsの日本語への翻訳
 | 
			
		||||
# by damiemk
 | 
			
		||||
 | 
			
		||||
%s Chest = %s のチェスト
 | 
			
		||||
%s Locked Chest = %s ロックされたチェスト
 | 
			
		||||
%s Locked Chest (owned by %s) = %s のロックされたチェスト (%s が所有)
 | 
			
		||||
Color Filter: %s = カラーフィルター: %s
 | 
			
		||||
Edit chest description: = チェストの説明を編集する:
 | 
			
		||||
 | 
			
		||||
# Colors
 | 
			
		||||
Black = 黒
 | 
			
		||||
Blue = 青
 | 
			
		||||
Brown = 茶色
 | 
			
		||||
Cyan = シアン
 | 
			
		||||
Dark Green = 濃い緑色
 | 
			
		||||
Dark Grey = 暗灰色 
 | 
			
		||||
Green = 緑
 | 
			
		||||
Grey = 灰色
 | 
			
		||||
Magenta = マジェンタ
 | 
			
		||||
Orange = 橙色
 | 
			
		||||
Pink = 桃色
 | 
			
		||||
Red = 赤
 | 
			
		||||
Violet = 紫
 | 
			
		||||
White = 白
 | 
			
		||||
Yellow = 黄色
 | 
			
		||||
None = デフォルト
 | 
			
		||||
 | 
			
		||||
# Materials
 | 
			
		||||
Copper = 銅
 | 
			
		||||
Gold = 金
 | 
			
		||||
Iron = 鉄
 | 
			
		||||
Mithril = ミスリル
 | 
			
		||||
Silver = 銀
 | 
			
		||||
Wooden = 木造
 | 
			
		||||
 | 
			
		||||
# Sorting
 | 
			
		||||
Sort = 組織する
 | 
			
		||||
Auto-sort is %s = 自動組織が %s になっている
 | 
			
		||||
Off = オフ
 | 
			
		||||
On = オン
 | 
			
		||||
@@ -4,9 +4,10 @@ local pipeworks = rawget(_G, "pipeworks")
 | 
			
		||||
local fs_helpers
 | 
			
		||||
local tubelib_exists = minetest.global_exists("tubelib")
 | 
			
		||||
 | 
			
		||||
local registered_chest_data = {} -- data passed to :register()
 | 
			
		||||
 | 
			
		||||
local allow_label = ""
 | 
			
		||||
local tube_entry = ""
 | 
			
		||||
local shift_edit_field = 0
 | 
			
		||||
 | 
			
		||||
if not minetest.get_modpath("pipeworks") then
 | 
			
		||||
	-- Pipeworks is not installed. Simulate using a dummy table...
 | 
			
		||||
@@ -26,11 +27,11 @@ if not minetest.get_modpath("pipeworks") then
 | 
			
		||||
	fs_helpers.cycling_button = function() return "" end
 | 
			
		||||
else
 | 
			
		||||
	fs_helpers = pipeworks.fs_helpers
 | 
			
		||||
	allow_label = "label[0.9,0.36;Allow splitting incoming stacks from tubes]"
 | 
			
		||||
	shift_edit_field = 3
 | 
			
		||||
	allow_label = "Allow splitting incoming stacks from tubes"
 | 
			
		||||
	tube_entry = "^pipeworks_tube_connection_metallic.png"
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
-- Change the appearance of the chest
 | 
			
		||||
local chest_mark_colors = {
 | 
			
		||||
	{"black", S("Black")},
 | 
			
		||||
	{"blue", S("Blue")},
 | 
			
		||||
@@ -84,33 +85,43 @@ end
 | 
			
		||||
 | 
			
		||||
local function set_formspec(pos, data, page)
 | 
			
		||||
	local meta = minetest.get_meta(pos)
 | 
			
		||||
	local formspec = data.base_formspec
 | 
			
		||||
	formspec = formspec..fs_helpers.cycling_button(
 | 
			
		||||
 | 
			
		||||
	-- Static formspec elements are in base_formspec
 | 
			
		||||
	local fs = { data.base_formspec }
 | 
			
		||||
 | 
			
		||||
	-- Pipeworks splitting setting
 | 
			
		||||
	fs[#fs + 1] = fs_helpers.cycling_button(
 | 
			
		||||
		meta,
 | 
			
		||||
				"image_button[0,0.35;1,0.6",
 | 
			
		||||
		"image_button[0,0.5;1,0.6",
 | 
			
		||||
		"splitstacks",
 | 
			
		||||
		{
 | 
			
		||||
			pipeworks.button_off,
 | 
			
		||||
			pipeworks.button_on
 | 
			
		||||
		}
 | 
			
		||||
			)..allow_label
 | 
			
		||||
	)
 | 
			
		||||
 | 
			
		||||
	if data.autosort then
 | 
			
		||||
		local status = meta:get_int("autosort")
 | 
			
		||||
		formspec = formspec.."button["..(data.hileft+2)..","..(data.height+1.1)..";3,0.8;autosort_to_"..(1-status)..";"..
 | 
			
		||||
			S("Auto-sort is %s"):format(status == 1 and S("On") or S("Off")).."]"
 | 
			
		||||
		fs[#fs + 1] = ("checkbox[%g,%g;autosort_to_%s;%s;%s]"):format(
 | 
			
		||||
			data.hileft + 2.2, data.lotop - 1.15,
 | 
			
		||||
			tostring(1 - status), S("Auto-sort upon exit"), tostring(status == 1))
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	if data.infotext then
 | 
			
		||||
		local formspec_infotext = minetest.formspec_escape(meta:get_string("infotext"))
 | 
			
		||||
 | 
			
		||||
		local button_fmt = "image_button[%g,0;0.8,0.8;%s;%s;]"
 | 
			
		||||
		if page == "main" then
 | 
			
		||||
			formspec = formspec.."image_button["..(shift_edit_field+data.hileft+2.1)..",0.1;0.8,0.8;"
 | 
			
		||||
					.."technic_pencil_icon.png;edit_infotext;]"
 | 
			
		||||
					.."label["..(shift_edit_field+data.hileft+3)..",0;"..formspec_infotext.."]"
 | 
			
		||||
			fs[#fs + 1] = button_fmt:format(data.hileft + 6.1,
 | 
			
		||||
				"technic_pencil_icon.png", "edit_infotext")
 | 
			
		||||
 | 
			
		||||
			fs[#fs + 1] = "label["..(data.hileft+7.1)..",0.1;"..formspec_infotext.."]"
 | 
			
		||||
		elseif page == "edit_infotext" then
 | 
			
		||||
			formspec = formspec.."image_button["..(shift_edit_field+data.hileft+2.1)..",0.1;0.8,0.8;"
 | 
			
		||||
					.."technic_checkmark_icon.png;save_infotext;]"
 | 
			
		||||
					.."field["..(shift_edit_field+data.hileft+3.3)..",0.2;4.8,1;"
 | 
			
		||||
					.."infotext_box;"..S("Edit chest description:")..";"
 | 
			
		||||
			fs[#fs + 1] = button_fmt:format(data.hileft + 6.1,
 | 
			
		||||
				"technic_checkmark_icon.png", "save_infotext")
 | 
			
		||||
 | 
			
		||||
			fs[#fs + 1] = "field["..(data.hileft+7.3)..",0.2;4,1;"
 | 
			
		||||
					.."infotext_box;;"
 | 
			
		||||
					..formspec_infotext.."]"
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
@@ -122,9 +133,9 @@ local function set_formspec(pos, data, page)
 | 
			
		||||
		else
 | 
			
		||||
			colorName = S("None")
 | 
			
		||||
		end
 | 
			
		||||
		formspec = formspec.."label["..(data.coleft+0.2)..","..(data.lotop+3)..";"..S("Color Filter: %s"):format(colorName).."]"
 | 
			
		||||
		fs[#fs + 1] = "label["..(data.coleft+0.2)..","..(data.lotop+3)..";"..S("Color Filter: %s"):format(colorName).."]"
 | 
			
		||||
	end
 | 
			
		||||
	meta:set_string("formspec", formspec)
 | 
			
		||||
	meta:set_string("formspec", table.concat(fs))
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local function sort_inventory(inv)
 | 
			
		||||
@@ -171,6 +182,7 @@ local function get_receive_fields(name, data)
 | 
			
		||||
 | 
			
		||||
		if fields.sort or (data.autosort and fields.quit and meta:get_int("autosort") == 1) then
 | 
			
		||||
			sort_inventory(meta:get_inventory())
 | 
			
		||||
			return -- No formspec update
 | 
			
		||||
		end
 | 
			
		||||
		if fields.edit_infotext then
 | 
			
		||||
			page = "edit_infotext"
 | 
			
		||||
@@ -191,7 +203,6 @@ local function get_receive_fields(name, data)
 | 
			
		||||
			fs_helpers.on_receive_fields(pos, fields)
 | 
			
		||||
		end
 | 
			
		||||
 | 
			
		||||
		meta:get_inventory():set_size("main", data.width * data.height)
 | 
			
		||||
		set_formspec(pos, data, page)
 | 
			
		||||
	end
 | 
			
		||||
end
 | 
			
		||||
@@ -199,10 +210,8 @@ end
 | 
			
		||||
function technic.chests:definition(name, data)
 | 
			
		||||
	local lname = name:lower()
 | 
			
		||||
	name = S(name)
 | 
			
		||||
	local d = {}
 | 
			
		||||
	for k, v in pairs(data) do d[k] = v end
 | 
			
		||||
	data = d
 | 
			
		||||
 | 
			
		||||
	-- Calculate formspec positions
 | 
			
		||||
	data.lowidth = 8
 | 
			
		||||
	data.ovwidth = math.max(data.lowidth, data.width)
 | 
			
		||||
	data.hileft = (data.ovwidth - data.width) / 2
 | 
			
		||||
@@ -222,23 +231,29 @@ function technic.chests:definition(name, data)
 | 
			
		||||
	data.lotop = data.height + 2
 | 
			
		||||
	data.ovheight = data.lotop + 4
 | 
			
		||||
 | 
			
		||||
	local front = {"technic_"..lname.."_chest_front.png"}
 | 
			
		||||
	data.base_formspec = "size["..data.ovwidth..","..data.ovheight.."]"..
 | 
			
		||||
			"label[0,0;"..S("%s Chest"):format(name).."]"..
 | 
			
		||||
			"list[context;main;"..data.hileft..",1;"..data.width..","..data.height..";]"..
 | 
			
		||||
			"list[current_player;main;"..data.loleft..","..data.lotop..";8,4;]"..
 | 
			
		||||
			"background[-0.19,-0.25;"..(data.ovwidth+0.4)..","..(data.ovheight+0.75)..";technic_chest_form_bg.png]"..
 | 
			
		||||
			"background["..data.hileft..",1;"..data.width..","..data.height..";technic_"..lname.."_chest_inventory.png]"..
 | 
			
		||||
			"background["..data.loleft..","..data.lotop..";8,4;technic_main_inventory.png]"..
 | 
			
		||||
	-- Set up constant formspec fields
 | 
			
		||||
	local fs = {
 | 
			
		||||
		"size["..data.ovwidth..","..data.ovheight.."]",
 | 
			
		||||
		"label[0,0;"..S("%s Chest"):format(name).."]",
 | 
			
		||||
		"list[context;main;"..data.hileft..",1;"..data.width..","..data.height..";]",
 | 
			
		||||
		"list[current_player;main;"..data.loleft..","..data.lotop..";8,4;]",
 | 
			
		||||
		"listring[]"
 | 
			
		||||
	}
 | 
			
		||||
	if #allow_label > 0 then
 | 
			
		||||
		fs[#fs + 1] = ("label[0.9,0.5;%s]"):format(allow_label)
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	if data.color then
 | 
			
		||||
		fs[#fs + 1] = get_color_buttons(data.coleft, data.lotop)
 | 
			
		||||
	end
 | 
			
		||||
 | 
			
		||||
	if data.sort then
 | 
			
		||||
		data.base_formspec = data.base_formspec.."button["..data.hileft..","..(data.height+1.1)..";1,0.8;sort;"..S("Sort").."]"
 | 
			
		||||
	end
 | 
			
		||||
	if data.color then
 | 
			
		||||
		data.base_formspec = data.base_formspec..get_color_buttons(data.coleft, data.lotop)
 | 
			
		||||
		fs[#fs + 1] = ("button[%g,%g;2,0.7;sort;%s]"):format(
 | 
			
		||||
			data.hileft, data.lotop - 1, S("Sort now"))
 | 
			
		||||
	end
 | 
			
		||||
	data.base_formspec = table.concat(fs)
 | 
			
		||||
 | 
			
		||||
	local front = {"technic_"..lname.."_chest_front.png"}
 | 
			
		||||
	local locked_after_place
 | 
			
		||||
	if data.locked then
 | 
			
		||||
		locked_after_place = function(pos, placer)
 | 
			
		||||
@@ -372,10 +387,12 @@ local _TUBELIB_CALLBACKS = {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function technic.chests:register(name, data)
 | 
			
		||||
	data = table.copy(data) -- drop reference
 | 
			
		||||
	local def = technic.chests:definition(name, data)
 | 
			
		||||
 | 
			
		||||
	local nn = "technic:"..name:lower()..(data.locked and "_locked" or "").."_chest"
 | 
			
		||||
	minetest.register_node(":"..nn, def)
 | 
			
		||||
	registered_chest_data[nn] = data
 | 
			
		||||
 | 
			
		||||
	if tubelib_exists then
 | 
			
		||||
		tubelib.register_node(nn, {}, _TUBELIB_CALLBACKS)
 | 
			
		||||
@@ -397,7 +414,11 @@ function technic.chests:register(name, data)
 | 
			
		||||
			colordef.drop = nn
 | 
			
		||||
			colordef.groups = self.groups_noinv
 | 
			
		||||
			colordef.tiles = { def.tiles[1], def.tiles[2], def.tiles[3], def.tiles[4], def.tiles[5], mk_front("technic_chest_overlay"..postfix..".png") }
 | 
			
		||||
			minetest.register_node(":"..nn..postfix, colordef)
 | 
			
		||||
 | 
			
		||||
			local new_name = nn .. postfix
 | 
			
		||||
			minetest.register_node(":" .. new_name, colordef)
 | 
			
		||||
			registered_chest_data[new_name] = data -- for all colors
 | 
			
		||||
 | 
			
		||||
			if tubelib_exists then
 | 
			
		||||
				tubelib.register_node(nn..postfix, {}, _TUBELIB_CALLBACKS)
 | 
			
		||||
			end
 | 
			
		||||
@@ -405,3 +426,15 @@ function technic.chests:register(name, data)
 | 
			
		||||
	end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
-- Migration of chest formspecs
 | 
			
		||||
-- Group is specified in common.lua
 | 
			
		||||
minetest.register_lbm({
 | 
			
		||||
	label = "technic_chests formspec upgrade",
 | 
			
		||||
	name = "technic_chests:upgrade_formspec",
 | 
			
		||||
	nodenames = {"group:technic_chest"},
 | 
			
		||||
	run_at_every_load = false,
 | 
			
		||||
	action = function(pos, node)
 | 
			
		||||
		set_formspec(pos, registered_chest_data[node.name], "main")
 | 
			
		||||
	end
 | 
			
		||||
})
 | 
			
		||||
 
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 1.6 KiB  | 
| 
		 Before Width: | Height: | Size: 3.3 KiB  | 
| 
		 Before Width: | Height: | Size: 1.6 KiB  | 
| 
		 Before Width: | Height: | Size: 4.0 KiB  | 
| 
		 Before Width: | Height: | Size: 3.1 KiB  | 
| 
		 Before Width: | Height: | Size: 4.5 KiB  | 
| 
		 Before Width: | Height: | Size: 4.0 KiB  | 
| 
		 Before Width: | Height: | Size: 3.8 KiB  | 
| 
		 Before Width: | Height: | Size: 1.7 KiB  | 
@@ -69,6 +69,8 @@ local function restore(pos, placer, itemstack)
 | 
			
		||||
	return itemstack
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
minetest.register_on_mods_loaded(function()
 | 
			
		||||
	-- Delayed registration for foreign mod support
 | 
			
		||||
	for name, info in pairs(wrench.registered_nodes) do
 | 
			
		||||
		local olddef = minetest.registered_nodes[name]
 | 
			
		||||
		if olddef then
 | 
			
		||||
@@ -86,6 +88,7 @@ for name, info in pairs(wrench.registered_nodes) do
 | 
			
		||||
			minetest.register_node(":"..get_pickup_name(name), newdef)
 | 
			
		||||
		end
 | 
			
		||||
	end
 | 
			
		||||
end)
 | 
			
		||||
 | 
			
		||||
minetest.register_tool("wrench:wrench", {
 | 
			
		||||
	description = S("Wrench"),
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										6
									
								
								wrench/locale/ja.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,6 @@
 | 
			
		||||
# technic_wrench japanese translation
 | 
			
		||||
# technic_wrenchの日本語への翻訳
 | 
			
		||||
# by damiemk
 | 
			
		||||
 | 
			
		||||
Wrench = レンチ
 | 
			
		||||
%s with items = アイテム付きレンチ %s
 | 
			
		||||