mirror of
https://github.com/minetest-mods/digtron.git
synced 2024-08-19 04:14:05 +02:00
clean the slate! Old code will be brought back as it's needed.
This commit is contained in:
parent
b394214ffa
commit
6a38e68433
38
README.md
38
README.md
@ -1,38 +0,0 @@
|
|||||||
# Modular Tunnel Boring Machine
|
|
||||||
## aka The Almighty Digtron
|
|
||||||
|
|
||||||
|
|
||||||
This mod contains a set of blocks that can be used to construct highly customizable and modular tunnel-boring machines, bridge-builders, road-pavers, wall-o-matics, and other such construction/destruction contraptions.
|
|
||||||
|
|
||||||
A digging machine's components must be connected to the control block via a path leading through the faces of the blocks - diagonal connections across edges and corners don't count.
|
|
||||||
|
|
||||||
The basic block types that can be assembled into a functioning digging machine are:
|
|
||||||
|
|
||||||
* Digger heads, which excavate material in front of them when the machine is triggered
|
|
||||||
* Builder heads, which build a user-configured node in the direction they're facing
|
|
||||||
* Inventory modules, which hold material produced by the digger and provide material to the builders
|
|
||||||
* Fuel modules, which holds flammable materials to feed the beast
|
|
||||||
* Control block, used to trigger the machine and move it in a particular direction.
|
|
||||||
|
|
||||||
Diggers mine out blocks and shunt them into the Digtron's inventory, or drop them on the ground if there isn't room in the inventory to store them.
|
|
||||||
|
|
||||||
Builder heads can be used to lay down a solid surface as the Digtron moves, useful for situations where a tunnel-borer intersects a cavern. Builder heads can be set to construct their target block "intermittently", allowing for regularly-spaced structures to be constructed. Common uses include building support arches at regular intervals in a tunnel, adding a torch on the wall at regular intervals, laying rails with regularly-spaced powered rails interspersed, and adding stairs to vertical shafts.
|
|
||||||
|
|
||||||
The auto-controller block is able to trigger automatically for a user-selected number of cycles. A player can ride their Digtron as it goes.
|
|
||||||
|
|
||||||
Other specialized Digtron blocks include:
|
|
||||||
|
|
||||||
* An "axle" block that allows an assembled Digtron to be rotated into new orientations without needing to be rebuilt block-by-block
|
|
||||||
* A crate that can store an assembled Digtron and allow the player to transport it to a new location
|
|
||||||
* A duplicator that can create a copy of an existing Digtron (if provided with enough spare parts)
|
|
||||||
* An item ejector to clear Digtron's inventory of excavated materials and inject it into pipeworks tubes if that mod is installed.
|
|
||||||
* A light that can be mounted on a Digtron to illuminate the workspace as it moves
|
|
||||||
* Structural components to make it look cool
|
|
||||||
|
|
||||||
The Digtron mod only depends on the default mod, but includes optional support for several other mods:
|
|
||||||
|
|
||||||
* [https://forum.minetest.net/viewtopic.php?t=15912](doc), an in-game documentation mod. Detailed documentation for all of the Digtron's individual blocks are included as well as pages of general concepts and design tips.
|
|
||||||
* [https://forum.minetest.net/viewtopic.php?id=2155](pipeworks), a set of pneumatic tubes that allows inventory items to be extracted from or inserted into Digtron inventories.
|
|
||||||
* [https://forum.minetest.net/viewtopic.php?&t=12379](hopper), a different mod for inserting into and extracting from Digtron inventories. Note that only [https://github.com/minetest-mods/hopper](the most recent version of hopper is Digtron-capable,) earlier versions lack a suitable API.
|
|
||||||
* [https://forum.minetest.net/viewtopic.php?&t=4870](awards), a mod that adds achievements to the game. Over thirty Digtron-specific achievements are included.
|
|
||||||
* [https://forum.minetest.net/viewtopic.php?f=11&t=2538](technic), which adds rechargeable batteries and power cables to the game that Digtron can use instead of fuel.
|
|
436
awards.lua
436
awards.lua
@ -1,436 +0,0 @@
|
|||||||
if not minetest.get_modpath("awards") then
|
|
||||||
digtron.award_item_dug = function (items, name, count) end
|
|
||||||
digtron.award_layout = function (layout, name) end
|
|
||||||
digtron.award_item_built = function(item_name, name) end
|
|
||||||
digtron.award_crate = function (layout, name) end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
---------------------------------------------------------------------------
|
|
||||||
|
|
||||||
-- internationalization boilerplate
|
|
||||||
local MP = minetest.get_modpath(minetest.get_current_modname())
|
|
||||||
local S, NS = dofile(MP.."/intllib.lua")
|
|
||||||
|
|
||||||
awards.register_trigger("digtron_dig", {
|
|
||||||
type = "counted_key",
|
|
||||||
progress = "@1/@2 excavated",
|
|
||||||
auto_description = {"Excavate 1 @2 using a Digtron.", "Excavate @1 @2 using a Digtron."},
|
|
||||||
auto_description_total = {"Excavate @1 block using a Digtron.", "Excavate @1 blocks using a Digtron."},
|
|
||||||
get_key = function(self, def)
|
|
||||||
return minetest.registered_aliases[def.trigger.node] or def.trigger.node
|
|
||||||
end,
|
|
||||||
key_is_item = true,
|
|
||||||
})
|
|
||||||
|
|
||||||
digtron.award_item_dug = function(items_dropped, player)
|
|
||||||
if #items_dropped == 0 or not player then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
for _, item in pairs(items_dropped) do
|
|
||||||
awards.notify_digtron_dig(player, item)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
awards.register_trigger("digtron_build", {
|
|
||||||
type = "counted_key",
|
|
||||||
progress = "@1/@2 built",
|
|
||||||
auto_description = {"Build 1 @2 using a Digtron.", "Build @1 @2 using a Digtron."},
|
|
||||||
auto_description_total = {"Build @1 block using a Digtron.", "Build @1 blocks using a Digtron."},
|
|
||||||
get_key = function(self, def)
|
|
||||||
return minetest.registered_aliases[def.trigger.node] or def.trigger.node
|
|
||||||
end,
|
|
||||||
key_is_item = true,
|
|
||||||
})
|
|
||||||
|
|
||||||
digtron.award_item_built = function(item_name, player)
|
|
||||||
if not player then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
awards.notify_digtron_build(player, item_name)
|
|
||||||
end
|
|
||||||
|
|
||||||
digtron.award_layout = function(layout, player)
|
|
||||||
if layout == nil or not player then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local name = player:get_player_name()
|
|
||||||
|
|
||||||
if layout.water_touching then
|
|
||||||
awards.unlock(name, "digtron_water")
|
|
||||||
end
|
|
||||||
if layout.lava_touching then
|
|
||||||
awards.unlock(name, "digtron_lava")
|
|
||||||
end
|
|
||||||
if table.getn(layout.all) > 9 then
|
|
||||||
awards.unlock(name, "digtron_size10")
|
|
||||||
if table.getn(layout.all) > 99 then
|
|
||||||
awards.unlock(name, "digtron_size100")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if layout.diggers ~= nil and table.getn(layout.diggers) > 24 then
|
|
||||||
awards.unlock(name, "digtron_digger25")
|
|
||||||
end
|
|
||||||
if layout.builders ~= nil and table.getn(layout.builders) > 24 then
|
|
||||||
awards.unlock(name, "digtron_builder25")
|
|
||||||
end
|
|
||||||
|
|
||||||
if layout.controller.y > 100 then
|
|
||||||
awards.unlock(name, "digtron_height100")
|
|
||||||
if layout.controller.y > 1000 then
|
|
||||||
awards.unlock(name, "digtron_height1000")
|
|
||||||
end
|
|
||||||
elseif layout.controller.y < -100 then
|
|
||||||
awards.unlock(name, "digtron_depth100")
|
|
||||||
if layout.controller.y < -1000 then
|
|
||||||
awards.unlock(name, "digtron_depth1000")
|
|
||||||
if layout.controller.y < -2000 then
|
|
||||||
awards.unlock(name, "digtron_depth2000")
|
|
||||||
if layout.controller.y < -4000 then
|
|
||||||
awards.unlock(name, "digtron_depth4000")
|
|
||||||
if layout.controller.y < -8000 then
|
|
||||||
awards.unlock(name, "digtron_depth8000")
|
|
||||||
if layout.controller.y < -16000 then
|
|
||||||
awards.unlock(name, "digtron_depth16000")
|
|
||||||
if layout.controller.y < -30000 then
|
|
||||||
awards.unlock(name, "digtron_depth30000")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
digtron.award_crate = function(layout, name)
|
|
||||||
if layout == nil or not name or name == "" then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Note that we're testing >10 rather than >9 because this layout includes the crate node
|
|
||||||
if table.getn(layout.all) > 10 then
|
|
||||||
awards.unlock(name, "digtron_crate10")
|
|
||||||
if table.getn(layout.all) > 100 then
|
|
||||||
awards.unlock(name, "digtron_crate100")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
awards.register_award("digtron_water",{
|
|
||||||
title = S("Deep Blue Digtron"),
|
|
||||||
description = S("Encounter water while operating a Digtron."),
|
|
||||||
background = "awards_bg_mining.png",
|
|
||||||
icon = "default_water.png^digtron_digger_yb_frame.png",
|
|
||||||
})
|
|
||||||
|
|
||||||
awards.register_award("digtron_lava",{
|
|
||||||
title = S("Digtrons of Fire"),
|
|
||||||
description = S("Encounter lava while operating a Digtron."),
|
|
||||||
background = "awards_bg_mining.png",
|
|
||||||
icon = "default_lava.png^digtron_digger_yb_frame.png",
|
|
||||||
})
|
|
||||||
|
|
||||||
awards.register_award("digtron_size10",{
|
|
||||||
title = S("Bigtron"),
|
|
||||||
description = S("Operate a Digtron with 10 or more component blocks."),
|
|
||||||
background = "awards_bg_mining.png",
|
|
||||||
icon = "digtron_plate.png^digtron_crate.png",
|
|
||||||
})
|
|
||||||
|
|
||||||
awards.register_award("digtron_size100",{
|
|
||||||
title = S("Really Bigtron"),
|
|
||||||
description = S("Operate a Digtron with 100 or more component blocks."),
|
|
||||||
background = "awards_bg_mining.png",
|
|
||||||
icon = "digtron_plate.png^digtron_crate.png", -- TODO: Visually distinguish this from Bigtron
|
|
||||||
})
|
|
||||||
|
|
||||||
awards.register_award("digtron_builder25",{
|
|
||||||
title = S("Buildtron"),
|
|
||||||
description = S("Operate a Digtron with 25 or more builder modules."),
|
|
||||||
background = "awards_bg_mining.png",
|
|
||||||
icon = "digtron_plate.png^digtron_builder.png^digtron_crate.png",
|
|
||||||
})
|
|
||||||
|
|
||||||
awards.register_award("digtron_digger25",{
|
|
||||||
title = S("Digging Leviathan"),
|
|
||||||
description = S("Operate a Digtron with 25 or more digger heads."),
|
|
||||||
background = "awards_bg_mining.png",
|
|
||||||
icon = "digtron_plate.png^digtron_motor.png^digtron_crate.png",
|
|
||||||
})
|
|
||||||
|
|
||||||
awards.register_award("digtron_height1000",{
|
|
||||||
title = S("Digtron In The Sky"),
|
|
||||||
description = S("Operate a Digtron above 1000m elevation"),
|
|
||||||
background = "awards_bg_mining.png",
|
|
||||||
icon = "default_river_water.png^default_snow_side.png^[transformR180^digtron_digger_yb_frame.png",
|
|
||||||
})
|
|
||||||
|
|
||||||
awards.register_award("digtron_height100",{
|
|
||||||
title = S("Digtron High"),
|
|
||||||
description = S("Operate a Digtron above 100m elevation"),
|
|
||||||
background = "awards_bg_mining.png",
|
|
||||||
icon = "default_river_water.png^default_snow_side.png^digtron_digger_yb_frame.png",
|
|
||||||
})
|
|
||||||
|
|
||||||
awards.register_award("digtron_depth100",{
|
|
||||||
title = S("Scratching the Surface"),
|
|
||||||
description = S("Operate a Digtron 100m underground"),
|
|
||||||
background = "awards_bg_mining.png",
|
|
||||||
icon = "default_cobble.png^digtron_digger_yb_frame.png^awards_level1.png",
|
|
||||||
})
|
|
||||||
|
|
||||||
awards.register_award("digtron_depth1000",{
|
|
||||||
title = S("Digging Deeper"),
|
|
||||||
description = S("Operate a Digtron 1,000m underground"),
|
|
||||||
background = "awards_bg_mining.png",
|
|
||||||
icon = "default_cobble.png^[colorize:#0002^digtron_digger_yb_frame.png^awards_level2.png",
|
|
||||||
})
|
|
||||||
|
|
||||||
awards.register_award("digtron_depth2000",{
|
|
||||||
title = S("More Than a Mile"),
|
|
||||||
description = S("Operate a Digtron 2,000m underground"),
|
|
||||||
background = "awards_bg_mining.png",
|
|
||||||
icon = "default_cobble.png^[colorize:#0004^digtron_digger_yb_frame.png^awards_level3.png",
|
|
||||||
})
|
|
||||||
|
|
||||||
awards.register_award("digtron_depth4000",{
|
|
||||||
title = S("Digging Below Plausibility"),
|
|
||||||
description = S("The deepest mine in the world is only 3.9 km deep, you operated a Digtron below 4km"),
|
|
||||||
background = "awards_bg_mining.png",
|
|
||||||
icon = "default_cobble.png^[colorize:#0006^digtron_digger_yb_frame.png^awards_level4.png",
|
|
||||||
})
|
|
||||||
|
|
||||||
awards.register_award("digtron_depth8000",{
|
|
||||||
title = S("Double Depth"),
|
|
||||||
description = S("Operate a Digtron 8,000m underground"),
|
|
||||||
background = "awards_bg_mining.png",
|
|
||||||
icon = "default_cobble.png^[colorize:#0008^digtron_digger_yb_frame.png^awards_level5.png",
|
|
||||||
})
|
|
||||||
|
|
||||||
awards.register_award("digtron_depth16000",{
|
|
||||||
title = S("Halfway to the Core"),
|
|
||||||
description = S("Operate a Digtron 16,000m underground"),
|
|
||||||
background = "awards_bg_mining.png",
|
|
||||||
icon = "default_cobble.png^[colorize:#000A^digtron_digger_yb_frame.png^awards_level6.png",
|
|
||||||
})
|
|
||||||
|
|
||||||
awards.register_award("digtron_depth30000",{
|
|
||||||
title = S("Nowhere To Go But Up"),
|
|
||||||
description = S("Operate a Digtron 30,000m underground"),
|
|
||||||
background = "awards_bg_mining.png",
|
|
||||||
icon = "default_cobble.png^[colorize:#000C^digtron_digger_yb_frame.png^awards_level7.png",
|
|
||||||
})
|
|
||||||
|
|
||||||
awards.register_award("digtron_100mese_dug",{
|
|
||||||
title = S("Mese Master"),
|
|
||||||
description = S("Mine 100 Mese crystals with a Digtron"),
|
|
||||||
background = "awards_bg_mining.png",
|
|
||||||
icon = "digtron_plate.png^default_mese_crystal.png^digtron_digger_yb_frame.png",
|
|
||||||
trigger = {
|
|
||||||
type = "digtron_dig",
|
|
||||||
node = "default:mese_crystal",
|
|
||||||
target = 100,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
awards.register_award("digtron_100diamond_dug",{
|
|
||||||
title = S("Diamond Vs. Diamond"),
|
|
||||||
description = S("Mine 100 diamonds with a Digtron"),
|
|
||||||
background = "awards_bg_mining.png",
|
|
||||||
icon = "digtron_plate.png^default_diamond.png^digtron_digger_yb_frame.png",
|
|
||||||
trigger = {
|
|
||||||
type = "digtron_dig",
|
|
||||||
node = "default:diamond",
|
|
||||||
target = 100,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
awards.register_award("digtron_1000dirt_dug",{
|
|
||||||
title = S("Strip Mining"),
|
|
||||||
description = S("Excavate 1000 units of dirt with a Digtron"),
|
|
||||||
background = "awards_bg_mining.png",
|
|
||||||
icon = "default_dirt.png^digtron_digger_yb_frame.png",
|
|
||||||
trigger = {
|
|
||||||
type = "digtron_dig",
|
|
||||||
node = "default:dirt",
|
|
||||||
target = 1000,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
awards.register_award("digtron_1000_dug",{
|
|
||||||
title = S("Digtron Miner"),
|
|
||||||
description = S("Excavate 1000 blocks using a Digtron"),
|
|
||||||
background = "awards_bg_mining.png",
|
|
||||||
icon = "digtron_plate.png^default_tool_bronzepick.png^digtron_digger_yb_frame.png",
|
|
||||||
trigger = {
|
|
||||||
type = "digtron_dig",
|
|
||||||
target = 1000,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
awards.register_award("digtron_10000_dug",{
|
|
||||||
title = S("Digtron Expert Miner"),
|
|
||||||
description = S("Excavate 10,000 blocks using a Digtron"),
|
|
||||||
background = "awards_bg_mining.png",
|
|
||||||
icon = "digtron_plate.png^default_tool_steelpick.png^digtron_digger_yb_frame.png",
|
|
||||||
trigger = {
|
|
||||||
type = "digtron_dig",
|
|
||||||
target = 10000,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
awards.register_award("digtron_100000_dug",{
|
|
||||||
title = S("Digtron Master Miner"),
|
|
||||||
description = S("Excavate 100,000 blocks using a Digtron"),
|
|
||||||
background = "awards_bg_mining.png",
|
|
||||||
icon = "digtron_plate.png^default_tool_diamondpick.png^digtron_digger_yb_frame.png",
|
|
||||||
trigger = {
|
|
||||||
type = "digtron_dig",
|
|
||||||
target = 100000,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
awards.register_award("digtron_1000000_dug",{
|
|
||||||
title = S("DIGTRON MEGAMINER"),
|
|
||||||
description = S("Excavate over a million blocks using a Digtron!"),
|
|
||||||
background = "awards_bg_mining.png",
|
|
||||||
icon = "digtron_plate.png^default_tool_mesepick.png^digtron_digger_yb_frame.png",
|
|
||||||
trigger = {
|
|
||||||
type = "digtron_dig",
|
|
||||||
target = 1000000,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
awards.register_award("digtron_1000wood_dug",{
|
|
||||||
title = S("Clear Cutting"),
|
|
||||||
description = S("Chop down 1000 units of tree with a Digtron"),
|
|
||||||
background = "awards_bg_mining.png",
|
|
||||||
icon = "digtron_plate.png^default_sapling.png^digtron_digger_yb_frame.png",
|
|
||||||
trigger = {
|
|
||||||
type = "digtron_dig",
|
|
||||||
node = "group:tree",
|
|
||||||
target = 1000,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
awards.register_award("digtron_10000wood_dug",{
|
|
||||||
title = S("Digtron Deforestation"),
|
|
||||||
description = S("Chop down 10,000 units of tree with a Digtron"),
|
|
||||||
background = "awards_bg_mining.png",
|
|
||||||
icon = "digtron_plate.png^default_sapling.png^digtron_digger_yb_frame.png",
|
|
||||||
trigger = {
|
|
||||||
type = "digtron_dig",
|
|
||||||
node = "group:tree",
|
|
||||||
target = 10000,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
awards.register_award("digtron_1000grass_dug",{
|
|
||||||
title = S("Lawnmower"),
|
|
||||||
description = S("Harvest 1000 units of grass with a Digtron"),
|
|
||||||
background = "awards_bg_mining.png",
|
|
||||||
icon = "digtron_plate.png^default_grass_5.png^digtron_digger_yb_frame.png",
|
|
||||||
trigger = {
|
|
||||||
type = "digtron_dig",
|
|
||||||
node = "group:grass",
|
|
||||||
target = 1000,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
awards.register_award("digtron_1000iron_dug",{
|
|
||||||
title = S("Iron Digtron"),
|
|
||||||
description = S("Excavate 1000 units of iron ore with a Digtron"),
|
|
||||||
background = "awards_bg_mining.png",
|
|
||||||
icon = "digtron_plate.png^default_steel_ingot.png^digtron_digger_yb_frame.png",
|
|
||||||
trigger = {
|
|
||||||
type = "digtron_dig",
|
|
||||||
node = "default:iron_lump",
|
|
||||||
target = 1000,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
awards.register_award("digtron_1000copper_dug",{
|
|
||||||
title = S("Copper Digtron"),
|
|
||||||
description = S("Excavate 1000 units of copper ore with a Digtron"),
|
|
||||||
background = "awards_bg_mining.png",
|
|
||||||
icon = "digtron_plate.png^default_copper_ingot.png^digtron_digger_yb_frame.png",
|
|
||||||
trigger = {
|
|
||||||
type = "digtron_dig",
|
|
||||||
node = "default:copper_lump",
|
|
||||||
target = 1000,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
awards.register_award("digtron_1000coal_dug",{
|
|
||||||
title = S("Coal Digtron"),
|
|
||||||
description = S("Excavate 1,000 units if coal with a Digtron"),
|
|
||||||
background = "awards_bg_mining.png",
|
|
||||||
icon = "digtron_plate.png^default_coal_lump.png^digtron_digger_yb_frame.png",
|
|
||||||
trigger = {
|
|
||||||
type = "digtron_dig",
|
|
||||||
node = "default:coal_lump",
|
|
||||||
target = 1000,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
awards.register_award("digtron_10000coal_dug",{
|
|
||||||
title = S("Bagger 288"),
|
|
||||||
description = S("Excavate 10,000 units of coal with a Digtron"),
|
|
||||||
background = "awards_bg_mining.png",
|
|
||||||
icon = "digtron_plate.png^default_coal_block.png^digtron_digger_yb_frame.png",
|
|
||||||
trigger = {
|
|
||||||
type = "digtron_dig",
|
|
||||||
node = "default:coal_lump",
|
|
||||||
target = 10000,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
awards.register_award("digtron_100gold_dug",{
|
|
||||||
title = S("Digtron 49er"),
|
|
||||||
description = S("Excavate 100 units of gold with a Digtron"),
|
|
||||||
background = "awards_bg_mining.png",
|
|
||||||
icon = "digtron_plate.png^default_gold_ingot.png^digtron_digger_yb_frame.png",
|
|
||||||
trigger = {
|
|
||||||
type = "digtron_dig",
|
|
||||||
node = "default:gold_lump",
|
|
||||||
target = 100,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
awards.register_award("digtron_1000_built",{
|
|
||||||
title = S("Constructive Digging"),
|
|
||||||
description = S("Build 1,000 blocks with a Digtron"),
|
|
||||||
background = "awards_bg_mining.png",
|
|
||||||
icon = "digtron_plate.png^digtron_builder.png",
|
|
||||||
trigger = {
|
|
||||||
type = "digtron_build",
|
|
||||||
target = 1000,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
awards.register_award("digtron_10000_built",{
|
|
||||||
title = S("Highly Constructive Digging"),
|
|
||||||
description = S("Build 10,000 blocks with a Digtron"),
|
|
||||||
background = "awards_bg_mining.png",
|
|
||||||
icon = "digtron_plate.png^digtron_axel_side.png^[transformR90^digtron_builder.png",
|
|
||||||
trigger = {
|
|
||||||
type = "digtron_build",
|
|
||||||
target = 10000,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
awards.register_award("digtron_crate10",{
|
|
||||||
title = S("Digtron Packrat"),
|
|
||||||
description = S("Stored 10 or more Digtron blocks in one crate."),
|
|
||||||
background = "awards_bg_mining.png",
|
|
||||||
icon = "digtron_plate.png^digtron_crate.png", -- TODO: Visually distinguish this from Bigtron
|
|
||||||
})
|
|
||||||
|
|
||||||
awards.register_award("digtron_crate100",{
|
|
||||||
title = S("Digtron Hoarder"),
|
|
||||||
description = S("Stored 100 or more Digtron blocks in one crate."),
|
|
||||||
background = "awards_bg_mining.png",
|
|
||||||
icon = "digtron_plate.png^digtron_crate.png", -- TODO: Visually distinguish this from Bigtron
|
|
||||||
})
|
|
@ -1,145 +0,0 @@
|
|||||||
-- The purpose of this class is to have something that can be passed into callbacks that
|
|
||||||
-- demand a "Player" object as a parameter and hopefully prevent the mods that have
|
|
||||||
-- registered with those callbacks from crashing on a nil dereference or bad function
|
|
||||||
-- call. This is not supposed to be a remotely functional thing, it's just supposed
|
|
||||||
-- to provide dummy methods and return values of the correct data type for anything that
|
|
||||||
-- might ignore the false "is_player()" return and go ahead and try to use this thing
|
|
||||||
-- anyway.
|
|
||||||
|
|
||||||
-- I'm trying to patch holes in bad mod programming, essentially. If a mod is so badly
|
|
||||||
-- programmed that it crashes anyway there's not a lot else I can do on my end of things.
|
|
||||||
|
|
||||||
DigtronFakePlayer = {}
|
|
||||||
DigtronFakePlayer.__index = DigtronFakePlayer
|
|
||||||
|
|
||||||
local function return_value(x)
|
|
||||||
return (function() return x end)
|
|
||||||
end
|
|
||||||
|
|
||||||
local function return_nil()
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
|
|
||||||
local function return_empty_string()
|
|
||||||
return ""
|
|
||||||
end
|
|
||||||
|
|
||||||
local function return_zero()
|
|
||||||
return 0
|
|
||||||
end
|
|
||||||
|
|
||||||
local function return_empty_table()
|
|
||||||
return {}
|
|
||||||
end
|
|
||||||
|
|
||||||
function DigtronFakePlayer.update(self, pos, player_name)
|
|
||||||
self.is_fake_player = ":digtron " .. player_name
|
|
||||||
self.get_pos = return_value(pos)
|
|
||||||
end
|
|
||||||
|
|
||||||
function DigtronFakePlayer.create(pos, player_name)
|
|
||||||
local self = {}
|
|
||||||
setmetatable(self, DigtronFakePlayer)
|
|
||||||
|
|
||||||
self.is_fake_player = ":digtron " .. player_name
|
|
||||||
|
|
||||||
-- ObjectRef
|
|
||||||
self.get_pos = return_value(pos)
|
|
||||||
self.set_pos = return_nil
|
|
||||||
self.move_to = return_nil
|
|
||||||
self.punch = return_nil
|
|
||||||
self.right_click = return_nil
|
|
||||||
self.get_hp = return_value(10)
|
|
||||||
self.set_hp = return_nil
|
|
||||||
self.get_inventory = return_nil -- returns an `InvRef`
|
|
||||||
self.get_wield_list = return_empty_string
|
|
||||||
self.get_wield_index = return_value(1)
|
|
||||||
self.get_wielded_item = return_value(ItemStack(nil))
|
|
||||||
self.set_wielded_item = return_value(false)
|
|
||||||
self.set_armor_groups = return_nil
|
|
||||||
self.get_armor_groups = return_empty_table
|
|
||||||
self.set_animation = return_nil
|
|
||||||
self.get_animation = return_nil -- a set of values, maybe important?
|
|
||||||
self.set_attach = return_nil
|
|
||||||
self.get_attach = return_nil
|
|
||||||
self.set_detach = return_nil
|
|
||||||
self.set_bone_position = return_nil
|
|
||||||
self.get_bone_position = return_nil
|
|
||||||
self.set_properties = return_nil
|
|
||||||
self.get_properties = return_empty_table
|
|
||||||
|
|
||||||
self.is_player = return_value(false)
|
|
||||||
|
|
||||||
self.get_nametag_attributes = return_empty_table
|
|
||||||
self.set_nametag_attributes = return_nil
|
|
||||||
|
|
||||||
--LuaEntitySAO
|
|
||||||
self.set_velocity = return_nil
|
|
||||||
self.get_velocity = return_value({x=0,y=0,z=0})
|
|
||||||
self.set_acceleration = return_nil
|
|
||||||
self.get_acceleration = return_value({x=0,y=0,z=0})
|
|
||||||
self.set_yaw = return_nil
|
|
||||||
self.get_yaw = return_zero
|
|
||||||
self.set_texture_mod = return_nil
|
|
||||||
self.get_texture_mod = return_nil -- maybe important?
|
|
||||||
self.set_sprite = return_nil
|
|
||||||
--self.get_entity_name` (**Deprecated**: Will be removed in a future version)
|
|
||||||
self.get_luaentity = return_nil
|
|
||||||
|
|
||||||
-- Player object
|
|
||||||
|
|
||||||
self.get_player_name = return_empty_string
|
|
||||||
self.get_player_velocity = return_nil
|
|
||||||
self.get_look_dir = return_value({x=0,y=1,z=0})
|
|
||||||
self.get_look_horizontal = return_zero
|
|
||||||
self.set_look_horizontal = return_nil
|
|
||||||
self.get_look_vertical = return_zero
|
|
||||||
self.set_look_vertical = return_nil
|
|
||||||
|
|
||||||
--self.get_look_pitch`: pitch in radians - Deprecated as broken. Use `get_look_vertical`
|
|
||||||
--self.get_look_yaw`: yaw in radians - Deprecated as broken. Use `get_look_horizontal`
|
|
||||||
--self.set_look_pitch(radians)`: sets look pitch - Deprecated. Use `set_look_vertical`.
|
|
||||||
--self.set_look_yaw(radians)`: sets look yaw - Deprecated. Use `set_look_horizontal`.
|
|
||||||
self.get_breath = return_value(10)
|
|
||||||
self.set_breath = return_nil
|
|
||||||
self.get_attribute = return_nil
|
|
||||||
self.set_attribute = return_nil
|
|
||||||
|
|
||||||
self.set_inventory_formspec = return_nil
|
|
||||||
self.get_inventory_formspec = return_empty_string
|
|
||||||
self.get_player_control = return_value({jump=false, right=false, left=false, LMB=false, RMB=false, sneak=false, aux1=false, down=false, up=false} )
|
|
||||||
self.get_player_control_bits = return_zero
|
|
||||||
|
|
||||||
self.set_physics_override = return_nil
|
|
||||||
self.get_physics_override = return_value({speed = 1, jump = 1, gravity = 1, sneak = true, sneak_glitch = false, new_move = true,})
|
|
||||||
|
|
||||||
|
|
||||||
self.hud_add = return_nil
|
|
||||||
self.hud_remove = return_nil
|
|
||||||
self.hud_change = return_nil
|
|
||||||
self.hud_get = return_nil -- possibly important return value?
|
|
||||||
self.hud_set_flags = return_nil
|
|
||||||
self.hud_get_flags = return_value({ hotbar=true, healthbar=true, crosshair=true, wielditem=true, breathbar=true, minimap=true })
|
|
||||||
self.hud_set_hotbar_itemcount = return_nil
|
|
||||||
self.hud_get_hotbar_itemcount = return_zero
|
|
||||||
self.hud_set_hotbar_image = return_nil
|
|
||||||
self.hud_get_hotbar_image = return_empty_string
|
|
||||||
self.hud_set_hotbar_selected_image = return_nil
|
|
||||||
self.hud_get_hotbar_selected_image = return_empty_string
|
|
||||||
self.set_sky = return_nil
|
|
||||||
self.get_sky = return_empty_table -- may need members on this table
|
|
||||||
|
|
||||||
self.set_clouds = return_nil
|
|
||||||
self.get_clouds = return_value({density = 0, color = "#fff0f0e5", ambient = "#000000", height = 120, thickness = 16, speed = {x=0, y=-2}})
|
|
||||||
|
|
||||||
self.override_day_night_ratio = return_nil
|
|
||||||
self.get_day_night_ratio = return_nil
|
|
||||||
|
|
||||||
self.set_local_animation = return_nil
|
|
||||||
self.get_local_animation = return_empty_table
|
|
||||||
|
|
||||||
self.set_eye_offset = return_nil
|
|
||||||
self.get_eye_offset = return_value({x=0,y=0,z=0},{x=0,y=0,z=0})
|
|
||||||
|
|
||||||
return self
|
|
||||||
end
|
|
532
class_layout.lua
532
class_layout.lua
@ -1,532 +0,0 @@
|
|||||||
DigtronLayout = {}
|
|
||||||
DigtronLayout.__index = DigtronLayout
|
|
||||||
|
|
||||||
local modpath_awards = minetest.get_modpath("awards")
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------
|
|
||||||
-- Creation
|
|
||||||
|
|
||||||
local get_node_image = function(pos, node)
|
|
||||||
local node_image = {node=node, pos={x=pos.x, y=pos.y, z=pos.z}}
|
|
||||||
local node_def = minetest.registered_nodes[node.name]
|
|
||||||
node_image.paramtype2 = node_def.paramtype2
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
node_image.meta = meta:to_table()
|
|
||||||
if node_image.meta ~= nil and node_def._digtron_formspec ~= nil then
|
|
||||||
node_image.meta.fields.formspec = node_def._digtron_formspec(pos, meta) -- causes formspec to be automatically upgraded whenever Digtron moves
|
|
||||||
end
|
|
||||||
|
|
||||||
local group = minetest.get_item_group(node.name, "digtron")
|
|
||||||
-- group 1 has no special metadata
|
|
||||||
if group > 1 and group < 10 then
|
|
||||||
assert(node_image ~= nil and node_image.meta ~= nil, "[Digtron] Digtron failed to get a metadata table for a Digtron node in group "
|
|
||||||
.. tostring(group) .. ". This error should not be possible. Please see https://github.com/minetest/minetest/issues/8067")
|
|
||||||
-- These groups have inventories
|
|
||||||
if group == 2 or (group > 3 and group < 8) then
|
|
||||||
assert(node_image.meta.inventory ~= nil, "[Digtron] Digtron failed to get a metadata inventory table for a Digtron node in group "
|
|
||||||
.. tostring(group) .. ". This error should not be possible. Please see https://github.com/minetest/minetest/issues/8067")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Record what kind of thing we've got in a builder node so its facing can be rotated properly
|
|
||||||
if group == 4 then
|
|
||||||
local build_item = ""
|
|
||||||
if node_image.meta.inventory.main then
|
|
||||||
build_item = node_image.meta.inventory.main[1]
|
|
||||||
end
|
|
||||||
if build_item ~= "" then
|
|
||||||
local build_item_def = minetest.registered_nodes[ItemStack(build_item):get_name()]
|
|
||||||
if build_item_def ~= nil then
|
|
||||||
node_image.build_item_paramtype2 = build_item_def.paramtype2
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return node_image
|
|
||||||
end
|
|
||||||
|
|
||||||
-- temporary pointsets used while searching
|
|
||||||
local to_test = Pointset.create()
|
|
||||||
local tested = Pointset.create()
|
|
||||||
|
|
||||||
function DigtronLayout.create(pos, player)
|
|
||||||
local self = {}
|
|
||||||
setmetatable(self, DigtronLayout)
|
|
||||||
|
|
||||||
--initialize. We're assuming that the start position is a controller digtron, should be a safe assumption since only the controller node should call this
|
|
||||||
self.traction = 0
|
|
||||||
self.all = {}
|
|
||||||
self.water_touching = false
|
|
||||||
self.lava_touching = false
|
|
||||||
self.protected = Pointset.create() -- if any nodes we look at are protected, make note of that. That way we don't need to keep re-testing protection state later.
|
|
||||||
self.old_pos_pointset = Pointset.create() -- For tracking original location of nodes if we do transformations on the Digtron
|
|
||||||
self.nodes_dug = Pointset.create() -- For tracking adjacent nodes that will have been dug by digger heads in future
|
|
||||||
self.contains_protected_node = false -- used to indicate if at least one node in this digtron array is protected from the player.
|
|
||||||
self.controller = {x=pos.x, y=pos.y, z=pos.z} --Make a deep copy of the pos parameter just in case the calling code wants to play silly buggers with it
|
|
||||||
|
|
||||||
table.insert(self.all, get_node_image(pos, minetest.get_node(pos))) -- We never visit the source node, so insert it into the all table a priori. Revisit this design decision if a controller node is created that contains fuel or inventory or whatever.
|
|
||||||
|
|
||||||
self.extents_max_x = pos.x
|
|
||||||
self.extents_min_x = pos.x
|
|
||||||
self.extents_max_y = pos.y
|
|
||||||
self.extents_min_y = pos.y
|
|
||||||
self.extents_max_z = pos.z
|
|
||||||
self.extents_min_z = pos.z
|
|
||||||
|
|
||||||
tested:set(pos.x, pos.y, pos.z, true)
|
|
||||||
to_test:set(pos.x + 1, pos.y, pos.z, true)
|
|
||||||
to_test:set(pos.x - 1, pos.y, pos.z, true)
|
|
||||||
to_test:set(pos.x, pos.y + 1, pos.z, true)
|
|
||||||
to_test:set(pos.x, pos.y - 1, pos.z, true)
|
|
||||||
to_test:set(pos.x, pos.y, pos.z + 1, true)
|
|
||||||
to_test:set(pos.x, pos.y, pos.z - 1, true)
|
|
||||||
|
|
||||||
if minetest.is_protected(pos, player:get_player_name()) and not minetest.check_player_privs(player, "protection_bypass") then
|
|
||||||
self.protected:set(pos.x, pos.y, pos.z, true)
|
|
||||||
self.contains_protected_node = true
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Do a loop on to_test positions, adding new to_test positions as we find digtron nodes. This is a flood fill operation
|
|
||||||
-- that follows node faces (no diagonals)
|
|
||||||
local testpos, _ = to_test:pop()
|
|
||||||
while testpos ~= nil do
|
|
||||||
tested:set(testpos.x, testpos.y, testpos.z, true) -- track nodes we've looked at to prevent infinite loops
|
|
||||||
local node = minetest.get_node(testpos)
|
|
||||||
|
|
||||||
if node.name == "ignore" then
|
|
||||||
--digtron array is next to unloaded nodes, too dangerous to do anything. Abort.
|
|
||||||
self.ignore_touching = true
|
|
||||||
end
|
|
||||||
|
|
||||||
if minetest.get_item_group(node.name, "water") ~= 0 then
|
|
||||||
self.water_touching = true
|
|
||||||
elseif minetest.get_item_group(node.name, "lava") ~= 0 then
|
|
||||||
self.lava_touching = true
|
|
||||||
if digtron.config.lava_impassible then
|
|
||||||
self.protected:set(testpos.x, testpos.y, testpos.z, true)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local is_protected = false
|
|
||||||
if minetest.is_protected(testpos, player:get_player_name()) and not minetest.check_player_privs(player, "protection_bypass") then
|
|
||||||
self.protected:set(testpos.x, testpos.y, testpos.z, true)
|
|
||||||
is_protected = true
|
|
||||||
end
|
|
||||||
|
|
||||||
local group_number = minetest.get_item_group(node.name, "digtron")
|
|
||||||
if group_number > 0 then
|
|
||||||
--found one. Add it to the digtrons output
|
|
||||||
local node_image = get_node_image(testpos, node)
|
|
||||||
|
|
||||||
table.insert(self.all, node_image)
|
|
||||||
|
|
||||||
-- add a reference to this node's position to special node lists
|
|
||||||
if group_number == 2 then
|
|
||||||
self.inventories = self.inventories or {}
|
|
||||||
table.insert(self.inventories, node_image)
|
|
||||||
elseif group_number == 3 then
|
|
||||||
self.diggers = self.diggers or {}
|
|
||||||
table.insert(self.diggers, node_image)
|
|
||||||
elseif group_number == 4 then
|
|
||||||
self.builders = self.builders or {}
|
|
||||||
table.insert(self.builders, node_image)
|
|
||||||
elseif group_number == 5 then
|
|
||||||
self.fuelstores = self.fuelstores or {}
|
|
||||||
table.insert(self.fuelstores, node_image)
|
|
||||||
elseif group_number == 6 then
|
|
||||||
self.inventories = self.inventories or {}
|
|
||||||
self.fuelstores = self.fuelstores or {}
|
|
||||||
table.insert(self.inventories, node_image)
|
|
||||||
table.insert(self.fuelstores, node_image)
|
|
||||||
elseif group_number == 7 then -- technic batteries
|
|
||||||
self.battery_holders = self.battery_holders or {}
|
|
||||||
table.insert(self.battery_holders, node_image)
|
|
||||||
elseif group_number == 8 then
|
|
||||||
self.power_connectors = self.power_connectors or {}
|
|
||||||
table.insert(self.power_connectors, node_image) -- technic power connectors
|
|
||||||
elseif group_number == 9 and node_image.meta.fields["autoeject"] == "true" then
|
|
||||||
self.auto_ejectors = self.auto_ejectors or {}
|
|
||||||
table.insert(self.auto_ejectors, node_image)
|
|
||||||
end
|
|
||||||
|
|
||||||
if is_protected then
|
|
||||||
self.contains_protected_node = true
|
|
||||||
end
|
|
||||||
|
|
||||||
-- update extents
|
|
||||||
self.extents_max_x = math.max(self.extents_max_x, testpos.x)
|
|
||||||
self.extents_min_x = math.min(self.extents_min_x, testpos.x)
|
|
||||||
self.extents_max_y = math.max(self.extents_max_y, testpos.y)
|
|
||||||
self.extents_min_y = math.min(self.extents_min_y, testpos.y)
|
|
||||||
self.extents_max_z = math.max(self.extents_max_z, testpos.z)
|
|
||||||
self.extents_min_z = math.min(self.extents_min_z, testpos.z)
|
|
||||||
|
|
||||||
--queue up potential new test points adjacent to this digtron node
|
|
||||||
to_test:set_if_not_in(tested, testpos.x + 1, testpos.y, testpos.z, true)
|
|
||||||
to_test:set_if_not_in(tested, testpos.x - 1, testpos.y, testpos.z, true)
|
|
||||||
to_test:set_if_not_in(tested, testpos.x, testpos.y + 1, testpos.z, true)
|
|
||||||
to_test:set_if_not_in(tested, testpos.x, testpos.y - 1, testpos.z, true)
|
|
||||||
to_test:set_if_not_in(tested, testpos.x, testpos.y, testpos.z + 1, true)
|
|
||||||
to_test:set_if_not_in(tested, testpos.x, testpos.y, testpos.z - 1, true)
|
|
||||||
elseif not minetest.registered_nodes[node.name] or minetest.registered_nodes[node.name].buildable_to ~= true then
|
|
||||||
-- Tracks whether the digtron is hovering in mid-air. If any part of the digtron array touches something solid it gains traction.
|
|
||||||
-- Allowing unknown nodes to provide traction, since they're not buildable_to either
|
|
||||||
self.traction = self.traction + 1
|
|
||||||
end
|
|
||||||
|
|
||||||
testpos, _ = to_test:pop()
|
|
||||||
end
|
|
||||||
|
|
||||||
digtron.award_layout(self, player) -- hook for achievements mod
|
|
||||||
|
|
||||||
to_test:clear()
|
|
||||||
tested:clear()
|
|
||||||
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
------------------------------------------------------------------------
|
|
||||||
-- Rotation
|
|
||||||
|
|
||||||
local facedir_rotate = {
|
|
||||||
['x'] = {
|
|
||||||
[-1] = {[0]=4, 5, 6, 7, 22, 23, 20, 21, 0, 1, 2, 3, 13, 14, 15, 12, 19, 16, 17, 18, 10, 11, 8, 9}, -- 270 degrees
|
|
||||||
[1] = {[0]=8, 9, 10, 11, 0, 1, 2, 3, 22, 23, 20, 21, 15, 12, 13, 14, 17, 18, 19, 16, 6, 7, 4, 5}, -- 90 degrees
|
|
||||||
},
|
|
||||||
['y'] = {
|
|
||||||
[-1] = {[0]=3, 0, 1, 2, 19, 16, 17, 18, 15, 12, 13, 14, 7, 4, 5, 6, 11, 8, 9, 10, 21, 22, 23, 20}, -- 270 degrees
|
|
||||||
[1] = {[0]=1, 2, 3, 0, 13, 14, 15, 12, 17, 18, 19, 16, 9, 10, 11, 8, 5, 6, 7, 4, 23, 20, 21, 22}, -- 90 degrees
|
|
||||||
},
|
|
||||||
['z'] = {
|
|
||||||
[-1] = {[0]=16, 17, 18, 19, 5, 6, 7, 4, 11, 8, 9, 10, 0, 1, 2, 3, 20, 21, 22, 23, 12, 13, 14, 15}, -- 270 degrees
|
|
||||||
[1] = {[0]=12, 13, 14, 15, 7, 4, 5, 6, 9, 10, 11, 8, 20, 21, 22, 23, 0, 1, 2, 3, 16, 17, 18, 19}, -- 90 degrees
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
local wallmounted_rotate = {
|
|
||||||
['x'] = {
|
|
||||||
[-1] = {[0]=4, 5, 2, 3, 1, 0}, -- 270 degrees
|
|
||||||
[1] = {[0]=5, 4, 2, 3, 0, 1}, -- 90 degrees
|
|
||||||
},
|
|
||||||
['y'] = {
|
|
||||||
[-1] = {[0]=0, 1, 4, 5, 3, 2}, -- 270 degrees
|
|
||||||
[1] = {[0]=0, 1, 5, 4, 2, 3}, -- 90 degrees
|
|
||||||
},
|
|
||||||
['z'] = {
|
|
||||||
[-1] = {[0]=3, 2, 0, 1, 4, 5}, -- 270 degrees
|
|
||||||
[1] = {[0]=2, 3, 1, 0, 4, 5}, -- 90 degrees
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
--90 degrees CW about x-axis: (x, y, z) -> (x, -z, y)
|
|
||||||
--90 degrees CCW about x-axis: (x, y, z) -> (x, z, -y)
|
|
||||||
--90 degrees CW about y-axis: (x, y, z) -> (-z, y, x)
|
|
||||||
--90 degrees CCW about y-axis: (x, y, z) -> (z, y, -x)
|
|
||||||
--90 degrees CW about z-axis: (x, y, z) -> (y, -x, z)
|
|
||||||
--90 degrees CCW about z-axis: (x, y, z) -> (-y, x, z)
|
|
||||||
-- operates directly on the pos vector
|
|
||||||
local rotate_pos = function(axis, direction, pos)
|
|
||||||
if axis == "x" then
|
|
||||||
if direction < 0 then
|
|
||||||
local temp_z = pos.z
|
|
||||||
pos.z = pos.y
|
|
||||||
pos.y = -temp_z
|
|
||||||
else
|
|
||||||
local temp_z = pos.z
|
|
||||||
pos.z = -pos.y
|
|
||||||
pos.y = temp_z
|
|
||||||
end
|
|
||||||
elseif axis == "y" then
|
|
||||||
if direction < 0 then
|
|
||||||
local temp_x = pos.x
|
|
||||||
pos.x = -pos.z
|
|
||||||
pos.z = temp_x
|
|
||||||
else
|
|
||||||
local temp_x = pos.x
|
|
||||||
pos.x = pos.z
|
|
||||||
pos.z = -temp_x
|
|
||||||
end
|
|
||||||
else
|
|
||||||
if direction < 0 then
|
|
||||||
local temp_x = pos.x
|
|
||||||
pos.x = -pos.y
|
|
||||||
pos.y = temp_x
|
|
||||||
else
|
|
||||||
local temp_x = pos.x
|
|
||||||
pos.x = pos.y
|
|
||||||
pos.y = -temp_x
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return pos
|
|
||||||
end
|
|
||||||
|
|
||||||
-- operates directly on the pos vector
|
|
||||||
local subtract_in_place = function(pos, subtract)
|
|
||||||
pos.x = pos.x - subtract.x
|
|
||||||
pos.y = pos.y - subtract.y
|
|
||||||
pos.z = pos.z - subtract.z
|
|
||||||
return pos
|
|
||||||
end
|
|
||||||
local add_in_place = function(pos, add)
|
|
||||||
pos.x = pos.x + add.x
|
|
||||||
pos.y = pos.y + add.y
|
|
||||||
pos.z = pos.z + add.z
|
|
||||||
return pos
|
|
||||||
end
|
|
||||||
|
|
||||||
local rotate_node_image = function(node_image, origin, axis, direction, old_pos_pointset)
|
|
||||||
-- Facings
|
|
||||||
if node_image.paramtype2 == "wallmounted" then
|
|
||||||
node_image.node.param2 = wallmounted_rotate[axis][direction][node_image.node.param2]
|
|
||||||
elseif node_image.paramtype2 == "facedir" then
|
|
||||||
node_image.node.param2 = facedir_rotate[axis][direction][node_image.node.param2]
|
|
||||||
end
|
|
||||||
|
|
||||||
if node_image.build_item_paramtype2 == "wallmounted" then
|
|
||||||
node_image.meta.fields.build_facing = wallmounted_rotate[axis][direction][tonumber(node_image.meta.fields.build_facing)]
|
|
||||||
elseif node_image.build_item_paramtype2 == "facedir" then
|
|
||||||
node_image.meta.fields.build_facing = facedir_rotate[axis][direction][tonumber(node_image.meta.fields.build_facing)]
|
|
||||||
end
|
|
||||||
|
|
||||||
node_image.meta.fields.waiting = nil -- If we're rotating a controller that's in the "waiting" state, clear it. Otherwise it may stick like that.
|
|
||||||
|
|
||||||
-- record the old location so we can destroy the old node if the rotation operation is possible
|
|
||||||
old_pos_pointset:set(node_image.pos.x, node_image.pos.y, node_image.pos.z, true)
|
|
||||||
|
|
||||||
-- position in space relative to origin
|
|
||||||
local pos = subtract_in_place(node_image.pos, origin)
|
|
||||||
pos = rotate_pos(axis, direction, pos)
|
|
||||||
-- Move back to original reference frame
|
|
||||||
node_image.pos = add_in_place(pos, origin)
|
|
||||||
|
|
||||||
return node_image
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
local top = {
|
|
||||||
[0]={axis="y", dir=-1},
|
|
||||||
{axis="z", dir=1},
|
|
||||||
{axis="z", dir=-1},
|
|
||||||
{axis="x", dir=1},
|
|
||||||
{axis="x", dir=-1},
|
|
||||||
{axis="y", dir=1},
|
|
||||||
}
|
|
||||||
-- Rotates 90 degrees widdershins around the axis defined by facedir (which in this case is pointing out the front of the node, so it needs to be converted into an upward-pointing axis internally)
|
|
||||||
function DigtronLayout.rotate_layout_image(self, facedir)
|
|
||||||
|
|
||||||
if self == nil or self.all == nil or self.controller == nil or self.old_pos_pointset == nil then
|
|
||||||
-- this should not be possible, but if it is then abort.
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
-- To convert this into the direction the "top" of the axle node is pointing in:
|
|
||||||
-- 0, 1, 2, 3 == (0,1,0)
|
|
||||||
-- 4, 5, 6, 7 == (0,0,1)
|
|
||||||
-- 8, 9, 10, 11 == (0,0,-1)
|
|
||||||
-- 12, 13, 14, 15 == (1,0,0)
|
|
||||||
-- 16, 17, 18, 19 == (-1,0,0)
|
|
||||||
-- 20, 21, 22, 23== (0,-1,0)
|
|
||||||
|
|
||||||
local params = top[math.floor(facedir/4)]
|
|
||||||
|
|
||||||
for k, node_image in pairs(self.all) do
|
|
||||||
rotate_node_image(node_image, self.controller, params.axis, params.dir, self.old_pos_pointset)
|
|
||||||
end
|
|
||||||
return self
|
|
||||||
end
|
|
||||||
|
|
||||||
-----------------------------------------------------------------------------------------------
|
|
||||||
-- Translation
|
|
||||||
|
|
||||||
function DigtronLayout.move_layout_image(self, dir)
|
|
||||||
self.extents_max_x = self.extents_max_x + dir.x
|
|
||||||
self.extents_min_x = self.extents_min_x + dir.x
|
|
||||||
self.extents_max_y = self.extents_max_y + dir.y
|
|
||||||
self.extents_min_y = self.extents_min_y + dir.y
|
|
||||||
self.extents_max_z = self.extents_max_z + dir.z
|
|
||||||
self.extents_min_z = self.extents_min_z + dir.z
|
|
||||||
|
|
||||||
for k, node_image in pairs(self.all) do
|
|
||||||
self.old_pos_pointset:set(node_image.pos.x, node_image.pos.y, node_image.pos.z, true)
|
|
||||||
node_image.pos = add_in_place(node_image.pos, dir)
|
|
||||||
self.nodes_dug:set(node_image.pos.x, node_image.pos.y, node_image.pos.z, false) -- we've moved a digtron node into this space, mark it so that we don't dig it.
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-----------------------------------------------------------------------------------------------
|
|
||||||
-- Writing to world
|
|
||||||
|
|
||||||
function DigtronLayout.can_write_layout_image(self)
|
|
||||||
for k, node_image in pairs(self.all) do
|
|
||||||
--check if we're moving into a protected node
|
|
||||||
if self.protected:get(node_image.pos.x, node_image.pos.y, node_image.pos.z) then
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
-- check if the target node is buildable_to or is marked as part of the digtron that's moving
|
|
||||||
if not (
|
|
||||||
self.old_pos_pointset:get(node_image.pos.x, node_image.pos.y, node_image.pos.z)
|
|
||||||
or minetest.registered_nodes[minetest.get_node(node_image.pos).name].buildable_to
|
|
||||||
) then
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
-- We need to call on_dignode and on_placenode for dug and placed nodes,
|
|
||||||
-- but that triggers falling nodes (sand and whatnot) and destroys Digtrons
|
|
||||||
-- if done during mid-write. So we need to defer the calls until after the
|
|
||||||
-- Digtron has been fully written.
|
|
||||||
|
|
||||||
-- using local counters and shared tables like this allows us to avoid some needless allocating and garbage-collecting of tables
|
|
||||||
local dug_nodes_count = 0
|
|
||||||
local dug_node_pos = {}
|
|
||||||
local dug_node = {}
|
|
||||||
local dug_node_meta = {}
|
|
||||||
|
|
||||||
local placed_nodes_count = 0
|
|
||||||
local placed_node_pos = {}
|
|
||||||
local placed_new_node = {}
|
|
||||||
local placed_old_node = {}
|
|
||||||
|
|
||||||
local node_callbacks = function(player)
|
|
||||||
if dug_nodes_count > 0 then
|
|
||||||
for i = 1, dug_nodes_count do
|
|
||||||
local old_pos = dug_node_pos[i]
|
|
||||||
local old_node = dug_node[i]
|
|
||||||
local old_meta = dug_node_meta[i]
|
|
||||||
|
|
||||||
for _, callback in ipairs(minetest.registered_on_dignodes) do
|
|
||||||
-- Copy pos and node because callback can modify them
|
|
||||||
local pos_copy = {x=old_pos.x, y=old_pos.y, z=old_pos.z}
|
|
||||||
local oldnode_copy = {name=old_node.name, param1=old_node.param1, param2=old_node.param2}
|
|
||||||
callback(pos_copy, oldnode_copy, digtron.fake_player)
|
|
||||||
end
|
|
||||||
|
|
||||||
local old_def = minetest.registered_nodes[old_node.name]
|
|
||||||
if old_def ~= nil and old_def.after_dig_node ~= nil then
|
|
||||||
old_def.after_dig_node(old_pos, old_node, old_meta, player)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if placed_nodes_count > 0 then
|
|
||||||
for i = 1, placed_nodes_count do
|
|
||||||
local new_pos = placed_node_pos[i]
|
|
||||||
local new_node = placed_new_node[i]
|
|
||||||
local old_node = placed_old_node[i]
|
|
||||||
|
|
||||||
for _, callback in ipairs(minetest.registered_on_placenodes) do
|
|
||||||
-- Copy pos and node because callback can modify them
|
|
||||||
local pos_copy = {x=new_pos.x, y=new_pos.y, z=new_pos.z}
|
|
||||||
local oldnode_copy = {name=old_node.name, param1=old_node.param1, param2=old_node.param2}
|
|
||||||
local newnode_copy = {name=new_node.name, param1=new_node.param1, param2=new_node.param2}
|
|
||||||
callback(pos_copy, newnode_copy, digtron.fake_player, oldnode_copy)
|
|
||||||
end
|
|
||||||
|
|
||||||
local new_def = minetest.registered_nodes[new_node.name]
|
|
||||||
if new_def ~= nil and new_def.after_place_node ~= nil then
|
|
||||||
new_def.after_place_node(new_pos, player)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local set_node_with_retry = function(pos, node)
|
|
||||||
local start_time = minetest.get_us_time()
|
|
||||||
while not minetest.set_node(pos, node) do
|
|
||||||
if minetest.get_us_time() - start_time > 1000000 then -- 1 second in useconds
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
local set_meta_with_retry = function(meta, meta_table)
|
|
||||||
local start_time = minetest.get_us_time()
|
|
||||||
while not meta:from_table(meta_table) do
|
|
||||||
if minetest.get_us_time() - start_time > 1000000 then -- 1 second in useconds
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
local air_node = {name="air"}
|
|
||||||
function DigtronLayout.write_layout_image(self, player)
|
|
||||||
-- destroy the old digtron
|
|
||||||
local oldpos, _ = self.old_pos_pointset:pop()
|
|
||||||
while oldpos ~= nil do
|
|
||||||
local old_node = minetest.get_node(oldpos)
|
|
||||||
local old_meta = minetest.get_meta(oldpos)
|
|
||||||
|
|
||||||
if not set_node_with_retry(oldpos, air_node) then
|
|
||||||
minetest.log("error", "DigtronLayout.write_layout_image failed to destroy old Digtron node, aborting write.")
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
dug_nodes_count = dug_nodes_count + 1
|
|
||||||
dug_node_pos[dug_nodes_count] = oldpos
|
|
||||||
dug_node[dug_nodes_count] = old_node
|
|
||||||
dug_node_meta[dug_nodes_count] = old_meta
|
|
||||||
oldpos, _ = self.old_pos_pointset:pop()
|
|
||||||
end
|
|
||||||
|
|
||||||
-- create the new one
|
|
||||||
for k, node_image in pairs(self.all) do
|
|
||||||
local new_pos = node_image.pos
|
|
||||||
local new_node = node_image.node
|
|
||||||
local old_node = minetest.get_node(new_pos)
|
|
||||||
|
|
||||||
if not (set_node_with_retry(new_pos, new_node) and set_meta_with_retry(minetest.get_meta(new_pos), node_image.meta)) then
|
|
||||||
minetest.log("error", "DigtronLayout.write_layout_image failed to write a Digtron node, aborting write.")
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
placed_nodes_count = placed_nodes_count + 1
|
|
||||||
placed_node_pos[placed_nodes_count] = new_pos
|
|
||||||
placed_new_node[placed_nodes_count] = new_node
|
|
||||||
placed_old_node[placed_nodes_count] = old_node
|
|
||||||
end
|
|
||||||
|
|
||||||
-- fake_player will be passed to callbacks to prevent actual player from "taking the blame" for this action.
|
|
||||||
-- For example, the hunger mod shouldn't be making the player hungry when he moves Digtron.
|
|
||||||
digtron.fake_player:update(self.controller, player:get_player_name())
|
|
||||||
-- note that the actual player is still passed to the per-node after_place_node and after_dig_node, should they exist.
|
|
||||||
node_callbacks(player)
|
|
||||||
dug_nodes_count = 0
|
|
||||||
placed_nodes_count = 0
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
---------------------------------------------------------------------------------------------
|
|
||||||
-- Serialization. Currently only serializes the data that is needed by the crate, upgrade this function if more is needed
|
|
||||||
|
|
||||||
function DigtronLayout.serialize(self)
|
|
||||||
-- serialize can't handle ItemStack objects, convert them to strings.
|
|
||||||
for _, node_image in pairs(self.all) do
|
|
||||||
for k, inv in pairs(node_image.meta.inventory) do
|
|
||||||
for index, item in pairs(inv) do
|
|
||||||
inv[index] = item:to_string()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return minetest.serialize({controller=self.controller, all=self.all})
|
|
||||||
end
|
|
||||||
|
|
||||||
function DigtronLayout.deserialize(layout_string)
|
|
||||||
local self = {}
|
|
||||||
setmetatable(self, DigtronLayout)
|
|
||||||
|
|
||||||
if not layout_string or layout_string == "" then
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
local deserialized_layout = minetest.deserialize(layout_string)
|
|
||||||
|
|
||||||
self.all = deserialized_layout.all
|
|
||||||
self.controller = deserialized_layout.controller
|
|
||||||
self.old_pos_pointset = Pointset.create() -- needed by the write_layout method, leave empty
|
|
||||||
|
|
||||||
return self
|
|
||||||
end
|
|
@ -1,77 +0,0 @@
|
|||||||
-- A simple special-purpose class, this is used for building up sets of three-dimensional points for fast reference
|
|
||||||
|
|
||||||
Pointset = {}
|
|
||||||
Pointset.__index = Pointset
|
|
||||||
|
|
||||||
-- from builtin\game\misc.lua, modified to take values directly to avoid creating an intermediate vector
|
|
||||||
local hash_node_position_values = function(x, y, z)
|
|
||||||
return (z + 32768) * 65536 * 65536
|
|
||||||
+ (y + 32768) * 65536
|
|
||||||
+ x + 32768
|
|
||||||
end
|
|
||||||
|
|
||||||
function Pointset.create()
|
|
||||||
local set = {}
|
|
||||||
setmetatable(set,Pointset)
|
|
||||||
set.points = {}
|
|
||||||
return set
|
|
||||||
end
|
|
||||||
|
|
||||||
function Pointset:clear()
|
|
||||||
local points = self.points
|
|
||||||
for k, v in pairs(points) do
|
|
||||||
points[k] = nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function Pointset:set(x, y, z, value)
|
|
||||||
-- sets a value in the 3D array "points".
|
|
||||||
self.points[hash_node_position_values(x,y,z)] = value
|
|
||||||
end
|
|
||||||
|
|
||||||
function Pointset:set_if_not_in(excluded, x, y, z, value)
|
|
||||||
-- If a value is not already set for this point in the 3D array "excluded", set it in "points"
|
|
||||||
if excluded:get(x, y, z) ~= nil then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
self:set(x, y, z, value)
|
|
||||||
end
|
|
||||||
|
|
||||||
function Pointset:get(x, y, z)
|
|
||||||
-- return a value from the 3D array "points"
|
|
||||||
return self.points[hash_node_position_values(x,y,z)]
|
|
||||||
end
|
|
||||||
|
|
||||||
function Pointset:set_pos(pos, value)
|
|
||||||
self:set(pos.x, pos.y, pos.z, value)
|
|
||||||
end
|
|
||||||
|
|
||||||
function Pointset:set_pos_if_not_in(excluded, pos, value)
|
|
||||||
self:set_if_not_in(excluded, pos.x, pos.y, pos.z, value)
|
|
||||||
end
|
|
||||||
|
|
||||||
function Pointset:get_pos(pos)
|
|
||||||
return self:get(pos.x, pos.y, pos.z)
|
|
||||||
end
|
|
||||||
|
|
||||||
function Pointset:pop()
|
|
||||||
-- returns a point that's in the 3D array, and then removes it.
|
|
||||||
local hash, value = next(self.points)
|
|
||||||
if hash == nil then return nil end
|
|
||||||
local pos = minetest.get_position_from_hash(hash)
|
|
||||||
self.points[hash] = nil
|
|
||||||
return pos, value
|
|
||||||
end
|
|
||||||
|
|
||||||
function Pointset:get_pos_list(value)
|
|
||||||
-- Returns a list of all points with the given value in standard Minetest vector format. If no value is provided, returns all points
|
|
||||||
local outlist = {}
|
|
||||||
for hash, pointsval in pairs(self.points) do
|
|
||||||
if value == nil or pointsval == value then
|
|
||||||
table.insert(outlist, minetest.get_position_from_hash(hash))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return outlist
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
69
config.lua
69
config.lua
@ -1,69 +0,0 @@
|
|||||||
local CONFIG_FILE_PREFIX = "digtron_"
|
|
||||||
|
|
||||||
digtron.config = {}
|
|
||||||
|
|
||||||
local print_settingtypes = false
|
|
||||||
|
|
||||||
local function setting(stype, name, default, description)
|
|
||||||
local value
|
|
||||||
if stype == "bool" then
|
|
||||||
value = minetest.settings:get_bool(CONFIG_FILE_PREFIX..name)
|
|
||||||
elseif stype == "string" then
|
|
||||||
value = minetest.settings:get(CONFIG_FILE_PREFIX..name)
|
|
||||||
elseif stype == "int" or stype == "float" then
|
|
||||||
value = tonumber(minetest.settings:get(CONFIG_FILE_PREFIX..name))
|
|
||||||
end
|
|
||||||
if value == nil then
|
|
||||||
value = default
|
|
||||||
end
|
|
||||||
digtron.config[name] = value
|
|
||||||
|
|
||||||
if print_settingtypes then
|
|
||||||
minetest.debug(CONFIG_FILE_PREFIX..name.." ("..description..") "..stype.." "..tostring(default))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
setting("bool", "uses_resources", true, "Digtron uses resources when active")
|
|
||||||
setting("bool", "lava_impassible", true, "Lava counts as a protected node")
|
|
||||||
setting("bool", "damage_creatures", true, "Diggers damage creatures") -- TODO: legacy setting, remove eventually
|
|
||||||
setting("int", "damage_hp", 8, "Damage diggers do")
|
|
||||||
setting("int", "size_limit", 1000, "Digtron size limit in nodes per moving digtron")
|
|
||||||
|
|
||||||
if digtron.config.damage_creatures == false then digtron.config.damage_hp = 0 end -- TODO: remove when damage_creatures is removed
|
|
||||||
|
|
||||||
-- Enables the spray of particles out the back of a digger head and puffs of smoke from the controller
|
|
||||||
local particle_effects = minetest.settings:get_bool("enable_particles")
|
|
||||||
digtron.config.particle_effects = particle_effects or particle_effects == nil -- default true
|
|
||||||
|
|
||||||
|
|
||||||
setting("int", "maximum_extrusion", 25, "Maximum builder extrusion distance")
|
|
||||||
setting("float", "cycle_time", 1.0, "Minimum Digtron cycle time")
|
|
||||||
setting("float", "traction_factor", 3.0, "Traction factor")
|
|
||||||
|
|
||||||
-- fuel costs. For comparison, in the default game:
|
|
||||||
-- one default tree block is 30 units
|
|
||||||
-- one coal lump is 40 units
|
|
||||||
-- one coal block is 370 units (apparently it's slightly more productive making your coal lumps into blocks before burning)
|
|
||||||
-- one book is 3 units
|
|
||||||
|
|
||||||
-- how much fuel is required to dig a node if not in one of the following groups.
|
|
||||||
setting("float", "dig_cost_default", 3.0, "Default dig cost")
|
|
||||||
-- eg, stone
|
|
||||||
setting("float", "dig_cost_cracky", 1.0, "Cracky dig cost")
|
|
||||||
-- eg, dirt, sand
|
|
||||||
setting("float", "dig_cost_crumbly", 0.5, "Crumbly dig cost")
|
|
||||||
-- eg, wood
|
|
||||||
setting("float", "dig_cost_choppy", 0.75, "Choppy dig cost")
|
|
||||||
-- how much fuel is required to build a node
|
|
||||||
setting("float", "build_cost", 1.0, "Build cost")
|
|
||||||
|
|
||||||
-- How much charge (an RE battery holds 10000 EU) is equivalent to 1 unit of heat produced by burning coal
|
|
||||||
-- With 100, the battery is 2.5 better than a coal lump, yet 3.7 less powerful than a coal block
|
|
||||||
-- Being rechargeable should pay off for this "average" performance.
|
|
||||||
setting("int", "power_ratio", 100, "The electrical charge to 1 coal heat unit conversion ratio")
|
|
||||||
|
|
||||||
|
|
||||||
setting("float", "marker_crate_good_duration", 3.0, "Duration that 'good' crate markers last")
|
|
||||||
setting("float", "marker_crate_bad_duration", 9.0, "Duration that 'bad' crate markers last")
|
|
||||||
|
|
||||||
setting("bool", "emerge_unloaded_mapblocks", true, "When Digtron encounters unloaded map blocks, emerge them.")
|
|
200
controller.lua
Normal file
200
controller.lua
Normal file
@ -0,0 +1,200 @@
|
|||||||
|
-- internationalization boilerplate
|
||||||
|
local MP = minetest.get_modpath(minetest.get_current_modname())
|
||||||
|
local S, NS = dofile(MP.."/intllib.lua")
|
||||||
|
|
||||||
|
local controller_nodebox = {
|
||||||
|
type = "fixed",
|
||||||
|
fixed = {
|
||||||
|
{-0.3125, -0.3125, -0.3125, 0.3125, 0.3125, 0.3125}, -- Core
|
||||||
|
{-0.1875, 0.3125, -0.1875, 0.1875, 0.5, 0.1875}, -- +y_connector
|
||||||
|
{-0.1875, -0.5, -0.1875, 0.1875, -0.3125, 0.1875}, -- -y_Connector
|
||||||
|
{0.3125, -0.1875, -0.1875, 0.5, 0.1875, 0.1875}, -- +x_connector
|
||||||
|
{-0.5, -0.1875, -0.1875, -0.3125, 0.1875, 0.1875}, -- -x_connector
|
||||||
|
{-0.1875, -0.1875, 0.3125, 0.1875, 0.1875, 0.5}, -- +z_connector
|
||||||
|
{-0.5, 0.125, -0.5, -0.125, 0.5, -0.3125}, -- back_connector_3
|
||||||
|
{0.125, 0.125, -0.5, 0.5, 0.5, -0.3125}, -- back_connector_1
|
||||||
|
{0.125, -0.5, -0.5, 0.5, -0.125, -0.3125}, -- back_connector_2
|
||||||
|
{-0.5, -0.5, -0.5, -0.125, -0.125, -0.3125}, -- back_connector_4
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
local get_controller_unconstructed_formspec = function(pos, player_name)
|
||||||
|
return "size[8,8]button[1,1;1,1;construct;Construct]"
|
||||||
|
end
|
||||||
|
|
||||||
|
local get_controller_constructed_formspec = function(pos, digtron_id, player_name)
|
||||||
|
return "size[9,9]button[1,1;1,1;deconstruct;Deconstruct]"
|
||||||
|
end
|
||||||
|
|
||||||
|
minetest.register_node("digtron:controller", {
|
||||||
|
description = S("Digtron Control Module"),
|
||||||
|
_doc_items_longdesc = nil,
|
||||||
|
_doc_items_usagehelp = nil,
|
||||||
|
groups = {cracky = 3, oddly_breakable_by_hand = 3, digtron = 1},
|
||||||
|
paramtype = "light",
|
||||||
|
paramtype2= "facedir",
|
||||||
|
is_ground_content = false,
|
||||||
|
-- Aims in the +Z direction by default
|
||||||
|
tiles = {
|
||||||
|
"digtron_plate.png^[transformR90",
|
||||||
|
"digtron_plate.png^[transformR270",
|
||||||
|
"digtron_plate.png",
|
||||||
|
"digtron_plate.png^[transformR180",
|
||||||
|
"digtron_plate.png",
|
||||||
|
"digtron_plate.png^digtron_control.png",
|
||||||
|
},
|
||||||
|
drawtype = "nodebox",
|
||||||
|
node_box = controller_nodebox,
|
||||||
|
|
||||||
|
-- on_construct = function(pos)
|
||||||
|
-- end,
|
||||||
|
|
||||||
|
on_dig = function(pos, node, digger)
|
||||||
|
local meta = minetest.get_meta(pos)
|
||||||
|
if meta:get("digtron_id") ~= nil then
|
||||||
|
return
|
||||||
|
else
|
||||||
|
return minetest.node_dig(pos, node, digger)
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
|
||||||
|
on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
|
||||||
|
local meta = minetest.get_meta(pos)
|
||||||
|
local digtron_id = meta:get("digtron_id")
|
||||||
|
local player_name = clicker:get_player_name()
|
||||||
|
if digtron_id ~= "" then
|
||||||
|
minetest.show_formspec(player_name,
|
||||||
|
"digtron_controller_unconstructed:"..minetest.pos_to_string(pos)..":"..player_name,
|
||||||
|
get_controller_unconstructed_formspec(pos, player_name))
|
||||||
|
else
|
||||||
|
-- initialized
|
||||||
|
minetest.show_formspec(player_name,
|
||||||
|
"digtron_controller_constructed:"..minetest.pos_to_string(pos)..":"..player_name..":"..digtron_id,
|
||||||
|
get_controller_construted_formspec(pos, digtron_id, player_name))
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
|
||||||
|
on_timer = function(pos, elapsed)
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
|
local cardinal_directions = {
|
||||||
|
{x=1,y=0,z=0},
|
||||||
|
{x=-1,y=0,z=0},
|
||||||
|
{x=0,y=1,z=0},
|
||||||
|
{x=0,y=-1,z=0},
|
||||||
|
{x=0,y=0,z=1},
|
||||||
|
{x=0,y=0,z=-1},
|
||||||
|
}
|
||||||
|
local origin_hash = minetest.hash_node_position({x=0,y=0,z=0})
|
||||||
|
|
||||||
|
local get_all_adjacent_digtron_nodes
|
||||||
|
get_all_adjacent_digtron_nodes = function(pos, digtron_nodes, not_digtron)
|
||||||
|
for _, dir in ipairs(cardinal_directions) do
|
||||||
|
local test_pos = vector.add(pos, dir)
|
||||||
|
local test_hash = minetest.hash_node_position(test_pos)
|
||||||
|
if not (digtron_nodes[test_hash] or not_digtron[test_hash]) then -- don't test twice
|
||||||
|
local test_node = minetest.get_node(test_pos)
|
||||||
|
local group_value = minetest.get_item_group(test_node.name, "digtron")
|
||||||
|
if group_value > 0 then
|
||||||
|
digtron_nodes[test_hash] = test_node
|
||||||
|
get_all_adjacent_digtron_nodes(test_pos, digtron_nodes, not_digtron) -- recurse
|
||||||
|
else
|
||||||
|
not_digtron[test_hash] = test_node
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
digtron.construct = function(pos, player_name)
|
||||||
|
local node = minetest.get_node(pos)
|
||||||
|
if node.name ~= "digtron:controller" then
|
||||||
|
-- Called on an incorrect node
|
||||||
|
minetest.log("error", "[Digtron] digtron.construct called with pos " .. minetest.pos_to_string(pos) .. " but the node at this location was " .. node.name)
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
local meta = minetest.get_meta(pos)
|
||||||
|
if meta:get("digtron_id") ~= nil then
|
||||||
|
-- Already constructed. TODO: validate that the digtron_id actually exists as well
|
||||||
|
minetest.log("error", "[Digtron] digtron.construct called with pos " .. minetest.pos_to_string(pos) .. " but the controller at this location was already part of a constructed Digtron.")
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
local root_hash = minetest.hash_node_position(pos)
|
||||||
|
local digtron_nodes = {[root_hash] = node}
|
||||||
|
local not_digtron = {}
|
||||||
|
get_all_adjacent_digtron_nodes(pos, digtron_nodes, not_digtron)
|
||||||
|
for hash, node in pairs(digtron_nodes) do
|
||||||
|
local relative_hash = hash - root_hash + origin_hash
|
||||||
|
minetest.chat_send_all("constructing " .. minetest.pos_to_string(minetest.get_position_from_hash(relative_hash)))
|
||||||
|
local digtron_meta
|
||||||
|
if hash == root_hash then
|
||||||
|
digtron_meta = meta -- we're processing the controller, we already have a reference to its meta
|
||||||
|
else
|
||||||
|
digtron_meta = minetest.get_meta(minetest.get_position_from_hash(hash))
|
||||||
|
end
|
||||||
|
|
||||||
|
local meta_table = digtron_meta:to_table()
|
||||||
|
meta_table.node = node
|
||||||
|
-- Process inventories specially
|
||||||
|
-- Builder inventory gets turned into an itemname in a special key in the builder's meta
|
||||||
|
-- fuel and main get added to corresponding detached inventory lists
|
||||||
|
-- then wipe them from the meta_table. They'll be re-added in digtron.deconstruct.
|
||||||
|
--meta_table.inventory = nil
|
||||||
|
node.param1 = nil -- we don't care about param1, wipe it to save space
|
||||||
|
minetest.chat_send_all(dump(meta_table))
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- Dealing with an unconstructed Digtron controller
|
||||||
|
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||||
|
local formname_split = formname:split(":")
|
||||||
|
if #formname_split ~= 3 or formname_split[1] ~= "digtron_controller_unconstructed" then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local pos = minetest.string_to_pos(formname_split[2])
|
||||||
|
if pos == nil then
|
||||||
|
minetest.log("error", "[Digtron] Unable to parse position from formspec name " .. formname)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local name = formname_split[3]
|
||||||
|
if player:get_player_name() ~= name then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if fields.construct then
|
||||||
|
local digtron_id = digtron.construct(pos, name)
|
||||||
|
if digtron_id then
|
||||||
|
minetest.show_formspec(name,
|
||||||
|
"digtron_controller_constructed:"..minetest.pos_to_string(pos)..":"..name..":"..digtron_id,
|
||||||
|
get_controller_construted_formspec(pos, digtron_id, name))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end)
|
||||||
|
|
||||||
|
-- Controlling a fully armed and operational Digtron
|
||||||
|
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||||
|
local formname_split = formname:split(":")
|
||||||
|
if #formname_split ~= 4 or formname_split[1] ~= "digtron_controller_constructed" then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local pos = minetest.string_to_pos(formname_split[2])
|
||||||
|
if pos == nil then
|
||||||
|
minetest.log("error", "[Digtron] Unable to parse position from formspec name " .. formname)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local name = formname_split[3]
|
||||||
|
if player:get_player_name() ~= name then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local digtron_id = formname_splot[4]
|
||||||
|
|
||||||
|
if fields.deconstruct then
|
||||||
|
minetest.chat_send_all("Deconstructing " .. digtron_id)
|
||||||
|
end
|
||||||
|
|
||||||
|
end)
|
@ -1,8 +1,2 @@
|
|||||||
default
|
default
|
||||||
pipeworks?
|
intllib?
|
||||||
doc?
|
|
||||||
hopper?
|
|
||||||
awards?
|
|
||||||
catacomb?
|
|
||||||
intllib?
|
|
||||||
technic?
|
|
@ -1,5 +0,0 @@
|
|||||||
digtron - a modular tunnel boring/building machine for minetest, v0.7.6 - 2017-01-22
|
|
||||||
|
|
||||||
Forum : https://forum.minetest.net/viewtopic.php?t=16295
|
|
||||||
Github: https://github.com/FaceDeer/digtron/
|
|
||||||
Wiki: http://wiki.minetest.net/Mods/digtron
|
|
311
doc.lua
311
doc.lua
@ -1,311 +0,0 @@
|
|||||||
digtron.doc = {}
|
|
||||||
|
|
||||||
if not minetest.get_modpath("doc") then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local coal_fuel = minetest.get_craft_result({method="fuel", width=1, items={"default:coal_lump"}}).time
|
|
||||||
local dig_stone_count = coal_fuel/digtron.config.dig_cost_cracky
|
|
||||||
local dig_dirt_count = coal_fuel/digtron.config.dig_cost_crumbly
|
|
||||||
local dig_wood_count = coal_fuel/digtron.config.dig_cost_choppy
|
|
||||||
local build_count = coal_fuel/digtron.config.build_cost
|
|
||||||
|
|
||||||
local battery_ratio = (10000/digtron.config.power_ratio) / coal_fuel
|
|
||||||
|
|
||||||
-- internationalization boilerplate
|
|
||||||
local MP = minetest.get_modpath(minetest.get_current_modname())
|
|
||||||
local S, NS = dofile(MP.."/intllib.lua")
|
|
||||||
|
|
||||||
local pipeworks_enabled = minetest.get_modpath("pipeworks") ~= nil
|
|
||||||
local hoppers_enabled = minetest.get_modpath("hopper") and hopper ~= nil and hopper.add_container ~= nil
|
|
||||||
|
|
||||||
digtron.doc.core_longdesc = S("A crafting component used in the manufacture of all Digtron block types.")
|
|
||||||
digtron.doc.core_usagehelp = S("Place the Digtron Core in the center of the crafting grid. All Digtron recipes consist of arranging various other materials around the central Digtron Core.")
|
|
||||||
|
|
||||||
--------------------------------------------------------------------
|
|
||||||
|
|
||||||
digtron.doc.builder_longdesc = S("A 'builder' module for a Digtron. By itself it does nothing, but as part of a Digtron it is used to construct user-defined blocks.")
|
|
||||||
digtron.doc.builder_usagehelp = S("A builder head is the most complex component of this system. It has period and offset properties, and also an inventory slot where you \"program\" it by placing an example of the block type that you want it to build."
|
|
||||||
.."\n\n"..
|
|
||||||
"When the \"Save & Show\" button is clicked the properties for period and offset will be saved, and markers will briefly be shown to indicate where the nearest spots corresponding to those values are. The builder will build its output at those locations provided it is moving along the matching axis."
|
|
||||||
.."\n\n"..
|
|
||||||
"There is also an \"Extrusion\" setting. This allows your builder to extrude a line of identical blocks from the builder output, in the direction the output side is facing, until it reaches an obstruction or until it reaches the extrusion limit. This can be useful for placing columns below a bridge, or for filling a large volume with a uniform block type without requiring a large number of builder heads."
|
|
||||||
.."\n\n"..
|
|
||||||
"The \"output\" side of a builder is the side with a black crosshair on it."
|
|
||||||
.."\n\n"..
|
|
||||||
"Builders also have a \"facing\" setting. If you haven't memorized the meaning of the 24 facing values yet, builder heads have a helpful \"Read & Save\" button to fill this value in for you. Simply build a temporary instance of the block in the output location in front of the builder, adjust it to the orientation you want using the screwdriver tool, and then when you click the \"Read & Save\" button the block's facing will be read and saved."
|
|
||||||
.."\n\n"..
|
|
||||||
"Note: if more than one builder tries to build into the same space simultaneously, it is not predictable which builder will take priority. One will succeed and the other will fail. You should arrange your builders to avoid this for consistent results.")
|
|
||||||
|
|
||||||
|
|
||||||
--------------------------------------------------------------------
|
|
||||||
|
|
||||||
digtron.doc.inventory_longdesc = S("Stores building materials for use by builder heads and materials dug up by digger heads.")
|
|
||||||
digtron.doc.inventory_usagehelp = S("Inventory modules have the same capacity as a chest. They're used both for storing the products of the digger heads and as the source of materials used by the builder heads. A digging machine whose builder heads are laying down cobble can automatically self-replenish in this way, but note that an inventory module is still required as buffer space even if the digger heads produced everything needed by the builder heads in a given cycle."
|
|
||||||
.."\n\n"..
|
|
||||||
"Inventory modules are not required for a digging-only machine. If there's not enough storage space to hold the materials produced by the digging heads the excess material will be ejected out the back of the control block. They're handy for accumulating ores and other building materials, though."
|
|
||||||
.."\n\n"..
|
|
||||||
"Digging machines can have multiple inventory modules added to expand their capacity.")
|
|
||||||
|
|
||||||
if hoppers_enabled then
|
|
||||||
digtron.doc.inventory_usagehelp = digtron.doc.inventory_usagehelp
|
|
||||||
.."\n\n"..
|
|
||||||
S("Digtron inventory modules are compatible with hoppers, adjacent hoppers will add to or take from their inventories. Hoppers are not part of the Digtron and will not move with it, however. They may be useful for creating a \"docking station\" for a Digtron.")
|
|
||||||
end
|
|
||||||
|
|
||||||
if pipeworks_enabled then
|
|
||||||
digtron.doc.inventory_usagehelp = digtron.doc.inventory_usagehelp
|
|
||||||
.."\n\n"..
|
|
||||||
S("Inventory modules are compatible with Pipeworks blocks. When a Digtron moves one of the inventory modules adjacent to a pipe it will automatically hook up to it, and disconnect again when it moves on.")
|
|
||||||
end
|
|
||||||
|
|
||||||
local standard_fuel_doc = S("When a control unit is triggered, it will tally up how much fuel is required for the next cycle and then burn items from the fuel hopper until a sufficient amount of heat has been generated to power the operation. Any leftover heat will be retained by the control unit for use in the next cycle; this is the \"heat remaining in controller furnace\". This means you don't have to worry too much about what kinds of fuel you put in the fuel store, none will be wasted (unless you dig away a control unit with some heat remaining in it, that heat does get wasted)."
|
|
||||||
.."\n\n"..
|
|
||||||
"By using one lump of coal as fuel a digtron can:\n"..
|
|
||||||
"\tBuild @1 blocks\n"..
|
|
||||||
"\tDig @2 stone blocks\n"..
|
|
||||||
"\tDig @3 wood blocks\n"..
|
|
||||||
"\tDig @4 dirt or sand blocks", math.floor(build_count), math.floor(dig_stone_count), math.floor(dig_wood_count), math.floor(dig_dirt_count))
|
|
||||||
|
|
||||||
|
|
||||||
digtron.doc.fuelstore_longdesc = S("Stores fuel to run a Digtron")
|
|
||||||
digtron.doc.fuelstore_usagehelp = S("Digtrons have an appetite. Build operations and dig operations require a certain amount of fuel, and that fuel comes from fuel store modules. Note that movement does not require fuel, only digging and building.")
|
|
||||||
.."\n\n".. standard_fuel_doc
|
|
||||||
|
|
||||||
if hoppers_enabled then
|
|
||||||
digtron.doc.fuelstore_usagehelp = digtron.doc.fuelstore_usagehelp
|
|
||||||
.."\n\n"..
|
|
||||||
S("Digtron fuel store modules are compatible with hoppers, adjacent hoppers will add to or take from their inventories. Hoppers are not part of the Digtron and will not move with it, however. They may be useful for creating a \"docking station\" for a Digtron.")
|
|
||||||
end
|
|
||||||
|
|
||||||
if pipeworks_enabled then
|
|
||||||
digtron.doc.fuelstore_usagehelp = digtron.doc.fuelstore_usagehelp
|
|
||||||
.."\n\n"..
|
|
||||||
S("Fuel modules are compatible with Pipeworks blocks. When a Digtron moves one of the inventory modules adjacent to a pipe it will automatically hook up to it, and disconnect again when it moves on.")
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
-- Battery holders
|
|
||||||
digtron.doc.battery_holder_longdesc = S("Holds RE batteries to run a Digtron")
|
|
||||||
digtron.doc.battery_holder_usagehelp = S("Digtrons have an appetite, and it can be satisfied by electricity as well. Build operations and dig operations require a certain amount of power, and that power comes from the batteries place in the holder. Note that movement does not consume charge, only digging and building."
|
|
||||||
.."\n\n"..
|
|
||||||
"When a control unit is triggered, it will tally up how much power is required for the next cycle and then discharge the batteries in the battery holder until a sufficient amount of heat has been generated to power the operation. Any leftover heat will be retained by the control unit for use in the next cycle; this is the \"heat remaining in controller furnace\". Thus no power is wasted (unless you dig away a control unit with some heat remaining in it, that heat does get wasted), and the discharged batteries can be taken away to be recharged."
|
|
||||||
.."\n\n"..
|
|
||||||
"One fully charged battery can:\n"..
|
|
||||||
"\tBuild @1 blocks\n"..
|
|
||||||
"\tDig @2 stone blocks\n"..
|
|
||||||
"\tDig @3 wood blocks\n"..
|
|
||||||
"\tDig @4 dirt or sand blocks", math.floor(build_count*battery_ratio), math.floor(dig_stone_count*battery_ratio), math.floor(dig_wood_count*battery_ratio), math.floor(dig_dirt_count*battery_ratio))
|
|
||||||
|
|
||||||
if pipeworks_enabled then
|
|
||||||
digtron.doc.battery_holder_usagehelp = digtron.doc.battery_holder_usagehelp
|
|
||||||
.."\n\n"..
|
|
||||||
S("Fuel modules are compatible with Pipeworks blocks. When a Digtron moves one of the inventory modules adjacent to a pipe it will automatically hook up to it, and disconnect again when it moves on.")
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
digtron.doc.combined_storage_longdesc = S("Stores fuel for a Digtron and also has an inventory for building materials")
|
|
||||||
digtron.doc.combined_storage_usagehelp = S("For smaller jobs the two dedicated modules may simply be too much of a good thing, wasting precious Digtron space to give unneeded capacity. The combined storage module is the best of both worlds, splitting its internal space between building material inventory and fuel storage. It has 3/4 building material capacity and 1/4 fuel storage capacity.") .. "\n\n" .. standard_fuel_doc
|
|
||||||
|
|
||||||
if hoppers_enabled then
|
|
||||||
digtron.doc.combined_storage_usagehelp = digtron.doc.combined_storage_usagehelp
|
|
||||||
.."\n\n"..
|
|
||||||
S("Digtron inventory modules are compatible with hoppers, adjacent hoppers will add to or take from their inventories. A hopper on top of a combined inventory module will insert items into its general inventory, a side hopper will insert items into its fuel inventory, and a hopper on the bottom of a combined inventory module will take items from its general inventory. Hoppers are not part of the Digtron and will not move with it, however. They may be useful for creating a \"docking station\" for a Digtron.")
|
|
||||||
end
|
|
||||||
|
|
||||||
if pipeworks_enabled then
|
|
||||||
digtron.doc.combined_storage_usagehelp = digtron.doc.combined_storage_usagehelp
|
|
||||||
.."\n\n"..
|
|
||||||
S("Combination modules are compatible with Pipeworks blocks. When a Digtron moves one of the inventory modules adjacent to a pipe it will automatically hook up to it, and disconnect again when it moves on. Items are extracted from the \"main\" inventory, and items coming into the combination module from any direction except the underside are inserted into \"main\". However, a pipe entering the combination module from the underside will attempt to insert items into the \"fuel\" inventory instead.")
|
|
||||||
end
|
|
||||||
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
|
|
||||||
local locked_suffix = "\n\n" .. S("This is the \"locked\" version of the Digtron crate. It can only be used by the player who placed it.")
|
|
||||||
|
|
||||||
digtron.doc.empty_crate_longdesc = S("An empty crate that a Digtron can be stored in")
|
|
||||||
digtron.doc.empty_crate_usagehelp = S("Digtrons can be pushed around and rotated, and that may be enough for getting them perfectly positioned for the start of a run. But once your digger is a kilometer down under a shaft filled with stairs, how to get it back to the surface to run another pass?"
|
|
||||||
.."\n\n"..
|
|
||||||
"Place an empty Digtron crate next to a Digtron and right-click it to pack the Digtron (and all its inventory and settings) into the crate. You can then collect the crate, bring it somewhere else, build the crate, and then unpack the Digtron from it again. The Digtron will appear in the same relative location and orientation to the crate as when it was packed away inside it.")
|
|
||||||
|
|
||||||
digtron.doc.loaded_crate_longdesc = S("A crate containing a Digtron array")
|
|
||||||
digtron.doc.loaded_crate_usagehelp = S("This crate contains a Digtron assembly that was stored in it earlier. Place it somewhere and right-click on it to access the label text that was applied to it. There's also a button that causes it to display the shape the deployed Digtron would take if you unpacked the crate, marking unbuildable blocks with a warning marker. And finally there's a button to actually deploy the Digtron, replacing this loaded crate with an empty that can be reused later.")
|
|
||||||
|
|
||||||
digtron.doc.empty_locked_crate_longdesc = digtron.doc.empty_crate_longdesc
|
|
||||||
digtron.doc.empty_locked_crate_usagehelp = digtron.doc.empty_crate_usagehelp .. locked_suffix
|
|
||||||
|
|
||||||
digtron.doc.loaded_locked_crate_longdesc = digtron.doc.loaded_crate_longdesc
|
|
||||||
digtron.doc.loaded_locked_crate_usagehelp = digtron.doc.loaded_crate_usagehelp .. locked_suffix
|
|
||||||
|
|
||||||
----------------------------------------------------------------------
|
|
||||||
|
|
||||||
digtron.doc.controller_longdesc = S("A basic controller to make a Digtron array move and operate.")
|
|
||||||
digtron.doc.controller_usagehelp = S("Right-click on this module to make the digging machine go one step. The digging machine will go in the direction that the control module is oriented."
|
|
||||||
.."\n\n"..
|
|
||||||
"A control module can only trigger once per second. Gives you time to enjoy the scenery and smell the flowers (or their mulched remains, at any rate)."
|
|
||||||
.."\n\n"..
|
|
||||||
"If you're standing within the digging machine's volume, or in a block adjacent to it, you will be pulled along with the machine when it moves.")
|
|
||||||
|
|
||||||
digtron.doc.auto_controller_longdesc = S("A more sophisticated controller that includes the ability to set the number of cycles it will run for, as well as diagonal movement.")
|
|
||||||
digtron.doc.auto_controller_usagehelp = S("An Auto-control module can be set to run for an arbitrary number of cycles. Once it's running, right-click on it again to interrupt its rampage. If anything interrupts it - the player's click, an undiggable obstruction, running out of fuel - it will remember the number of remaining cycles so that you can fix the problem and set it running again to complete the original plan."
|
|
||||||
.."\n\n"..
|
|
||||||
"The digging machine will go in the direction that the control module is oriented."
|
|
||||||
.."\n\n"..
|
|
||||||
"Auto-controllers can also be set to move diagonally by setting the \"Slope\" parameter to a non-zero value. The controller will then shunt the Digtron in the direction of the arrows painted on its sides every X steps it moves. The Digtron will trigger dig heads when it shunts to the side, but will not trigger builder modules or intermittent dig heads. The \"Offset\" setting determines at what point the lateral motion will take place."
|
|
||||||
.."\n\n"..
|
|
||||||
"The \"Stop block\" inventory slot in an auto-controller allows you to program an auto-controller to treat certain block types as impenetrable obstructions. This can allow you to fence a Digtron in with something so you don't have to carefully count exactly how many steps it should take, for example."
|
|
||||||
.."\n\n"..
|
|
||||||
"Note that the Digtron detects an undiggable block by the item that would be produced when digging it. Setting cobble as the stop block will make both cobble and regular stone undiggable, but setting a block of regular stone (produced from cobble in a furnace) as the stop block will *not* stop a Digtron from digging regular stone (since digging regular stone produces cobble, not stone).")
|
|
||||||
|
|
||||||
digtron.doc.pusher_longdesc = S("A simplified controller that merely moves a Digtron around without triggering its builder or digger modules")
|
|
||||||
digtron.doc.pusher_usagehelp = S("Aka the \"can you rebuild it six inches to the left\" module. This is a much simplified control module that does not trigger the digger or builder heads when right-clicked, it only moves the digging machine. It's up to you to ensure there's space for it to move into."
|
|
||||||
.."\n\n"..
|
|
||||||
"Since movement alone does not require fuel, a pusher module has no internal furnace. Pushers also don't require traction, since their primary purpose is repositioning Digtrons let's say they have a built-in crane or something.")
|
|
||||||
|
|
||||||
digtron.doc.axle_longdesc = S("A device that allows one to rotate their Digtron into new orientations")
|
|
||||||
digtron.doc.axle_usagehelp = S("This magical module can rotate a Digtron array in place around itself. Right-clicking on it will rotate the Digtron 90 degrees in the direction the orange arrows on its sides indicate (widdershins around the Y axis by default, use the screwdriver to change this) assuming there's space for the Digtron in its new orientation. Builders and diggers will not trigger on rotation.")
|
|
||||||
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
|
|
||||||
digtron.doc.digger_longdesc = S("A standard Digtron digger head")
|
|
||||||
digtron.doc.digger_usagehelp = S("Facing of a digger head is significant; it will excavate material from the block on the spinning grinder wheel face of the digger head. Generally speaking, you'll want these to face forward - though having them aimed to the sides can also be useful.")
|
|
||||||
|
|
||||||
digtron.doc.dual_digger_longdesc = S("Two standard Digtron digger heads merged at 90 degrees to each other")
|
|
||||||
digtron.doc.dual_digger_usagehelp = S("This digger head is mainly of use when you want to build a Digtron capable of digging diagonal paths. A normal one-direction dig head would be unable to clear blocks in both of the directions it would be called upon to move, resulting in a stuck Digtron."
|
|
||||||
.."\n\n"..
|
|
||||||
"One can also make use of dual dig heads to simplify the size and layout of a Digtron, though this is generally not of practical use.")
|
|
||||||
|
|
||||||
digtron.doc.dual_soft_digger_longdesc = S("Two standard soft-material Digtron digger heads merged at 90 degrees to each other")
|
|
||||||
digtron.doc.dual_soft_digger_usagehelp = S("This digger head is mainly of use when you want to build a Digtron capable of digging diagonal paths. A normal one-direction dig head would be unable to clear blocks in both of the directions it would be called upon to move, resulting in a stuck Digtron."
|
|
||||||
.."\n\n"..
|
|
||||||
"Like a normal single-direction soft digger head, this digger only excavates material belonging to groups softer than stone."
|
|
||||||
.."\n\n"..
|
|
||||||
"One can make use of dual dig heads to simplify the size and layout of a Digtron.")
|
|
||||||
|
|
||||||
digtron.doc.intermittent_digger_longdesc = S("A standard Digtron digger head that only triggers periodically")
|
|
||||||
digtron.doc.intermittent_digger_usagehelp = S("This is a standard digger head capable of digging any material, but it will only trigger periodically as the Digtron moves. This can be useful for punching regularly-spaced holes in a tunnel wall, for example.")
|
|
||||||
|
|
||||||
digtron.doc.intermittent_soft_digger_longdesc = S("A standard soft-material Digtron digger head that only triggers periodically")
|
|
||||||
digtron.doc.intermittent_soft_digger_usagehelp = S("This is a standard soft-material digger head capable of digging any material, but it will only trigger periodically as the Digtron moves. This can be useful for punching regularly-spaced holes in a tunnel wall, for example.")
|
|
||||||
|
|
||||||
digtron.doc.soft_digger_longdesc = S("A Digtron digger head that only excavates soft materials")
|
|
||||||
digtron.doc.soft_digger_usagehelp = S("This specialized digger head is designed to excavate only softer material such as sand or gravel. In technical terms, this digger digs blocks belonging to the \"crumbly\", \"choppy\", \"snappy\", \"oddly_diggable_by_hand\" and \"fleshy\" groups."
|
|
||||||
.."\n\n"..
|
|
||||||
"The intended purpose of this digger is to be aimed at the ceiling or walls of a tunnel being dug, making spaces to allow shoring blocks to be inserted into unstable roofs but leaving the wall alone if it's composed of a more stable material."
|
|
||||||
.."\n\n"..
|
|
||||||
"It can also serve as part of a lawnmower or tree-harvester.")
|
|
||||||
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
|
|
||||||
digtron.doc.power_connector_longdesc = S("High-voltage power connector allowing a Digtron to be powered from a Technic power network.")
|
|
||||||
digtron.doc.power_connector_usagehelp = S("A power connector node automatically hooks into adjacent high-voltage (HV) power cables, but it must be configured to set how much power it will draw from the attached network. Right-click on the power connector to bring up a form that shows the current estimated maximum power usage of the Digtron the power connector is part of and a field where a power value can be entered. The estimated maximum power usage is the amount of power this Digtron will use in the worst case situation, with all of its digger heads digging the toughest material and all of its builder heads building a block simultaneously."
|
|
||||||
.."\n\n"..
|
|
||||||
"You can set the power connector's usage lower than this, and if the Digtron is unable to get sufficient power from the network it will use on-board batteries or burnable fuel to make up the shortfall.")
|
|
||||||
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
|
|
||||||
digtron.doc.inventory_ejector_longdesc = S("An outlet that can be used to eject accumulated detritus from a Digtron's inventory.")
|
|
||||||
digtron.doc.inventory_ejector_usagehelp = S("When this block is punched it will search the entire inventory of the Digtron and will eject a stack of items taken from it, provided the items are not set for use by any of the Digtron's builders. It will not eject if the destination block is occupied.")
|
|
||||||
|
|
||||||
if pipeworks_enabled then
|
|
||||||
digtron.doc.inventory_ejector_usagehelp = digtron.doc.inventory_ejector_usagehelp
|
|
||||||
.."\n\n"..
|
|
||||||
S("Item ejectors are compatible with pipeworks and will automatically connect to a pipeworks tube if one is adjacent in the output location.")
|
|
||||||
end
|
|
||||||
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
|
|
||||||
digtron.doc.duplicator_longdesc = S("A device for duplicating an adjacent Digtron using parts from its inventory.")
|
|
||||||
digtron.doc.duplicator_usagehelp = S("Place the duplicator block adjacent to a Digtron, and then fill the duplicator's inventory with enough parts to recreate the adjacent Digtron. Then place an empty Digtron crate at the duplicator's output (the side with the black \"+\") and click the \"Duplicate\" button in the duplicator's right-click GUI. If enough parts are available the Digtron will be duplicated and packed into the crate, along with all of its programming but with empty inventories.")
|
|
||||||
|
|
||||||
---------------------------------------------------------------------
|
|
||||||
|
|
||||||
digtron.doc.structure_longdesc = S("Structural component for a Digtron array")
|
|
||||||
digtron.doc.structure_usagehelp = S("These blocks allow otherwise-disconnected sections of digtron blocks to be linked together. They are not usually necessary for simple diggers but more elaborate builder arrays might have builder blocks that can't be placed directly adjacent to other digtron blocks and these blocks can serve to keep them connected to the controller."
|
|
||||||
.."\n\n"..
|
|
||||||
"They may also be used for providing additional traction if your digtron array is very tall compared to the terrain surface that it's touching."
|
|
||||||
.."\n\n"..
|
|
||||||
"You can also use them decoratively, or to build a platform to stand on as you ride your mighty mechanical leviathan through the landscape.")
|
|
||||||
|
|
||||||
digtron.doc.light_longdesc = S("Digtron light source")
|
|
||||||
digtron.doc.light_usagehelp = S("A light source that moves along with the digging machine. Convenient if you're digging a tunnel that you don't intend to outfit with torches or other permanent light fixtures. Not quite as bright as a torch since the protective lens tends to get grimy while burrowing through the earth.")
|
|
||||||
|
|
||||||
digtron.doc.panel_longdesc = S("Digtron panel")
|
|
||||||
digtron.doc.panel_usagehelp = S("A structural panel that can be made part of a Digtron to provide shelter for an operator, keep sand out of the Digtron's innards, or just to look cool.")
|
|
||||||
|
|
||||||
digtron.doc.edge_panel_longdesc = S("Digtron edge panel")
|
|
||||||
digtron.doc.edge_panel_usagehelp = S("A pair of structural panels that can be made part of a Digtron to provide shelter for an operator, keep sand out of the Digtron's innards, or just to look cool.")
|
|
||||||
|
|
||||||
digtron.doc.corner_panel_longdesc = S("Digtron corner panel")
|
|
||||||
digtron.doc.corner_panel_usagehelp = S("A trio of structural panels that can be made part of a Digtron to provide shelter for an operator, keep sand out of the Digtron's innards, or just to look cool.")
|
|
||||||
|
|
||||||
doc.add_category("digtron",
|
|
||||||
{
|
|
||||||
name = S("Digtron"),
|
|
||||||
description = S("The Digtron system is a set of blocks used to construct tunnel-boring and construction machines."),
|
|
||||||
sorting = "custom",
|
|
||||||
sorting_data = {"summary", "concepts", "noises", "tips"},
|
|
||||||
build_formspec = doc.entry_builders.text_and_gallery,
|
|
||||||
})
|
|
||||||
|
|
||||||
doc.add_entry("digtron", "summary", {
|
|
||||||
name = S("Summary"),
|
|
||||||
data = { text = S("Digtron blocks can be used to construct highly customizable and modular tunnel-boring machines, bridge-builders, road-pavers, wall-o-matics, and other such construction/destruction contraptions."
|
|
||||||
.."\n\n"..
|
|
||||||
"The basic blocks that can be assembled into a functioning digging machine are:"
|
|
||||||
.."\n\n"..
|
|
||||||
"* Diggers, which excavate material in front of them when the machine is triggered\n"..
|
|
||||||
"* Builders, which build a user-configured block in front of them\n"..
|
|
||||||
"* Inventory modules, which hold material produced by the digger and provide material to the builders\n"..
|
|
||||||
"* Control block, used to trigger the machine and move it in a particular direction."
|
|
||||||
.."\n\n"..
|
|
||||||
"A digging machine's components must be connected to the control block via a path leading through the faces of the blocks - diagonal connections across edges and corners don't count.")
|
|
||||||
}})
|
|
||||||
|
|
||||||
doc.add_entry("digtron", "concepts", {
|
|
||||||
name = S("Concepts"),
|
|
||||||
data = { text =
|
|
||||||
S("Several general concepts are important when building more sophisticated diggers."
|
|
||||||
.."\n\n"..
|
|
||||||
"Facing - a number between 0-23 that determines which direction a block is facing and what orientation it has. Not all blocks make use of facing (basic blocks such as cobble or sand have no facing, for example) so it's not always necessary to set this when configuring a builder head. The facing of already-placed blocks can be altered through the use of the screwdriver tool."
|
|
||||||
.."\n\n"..
|
|
||||||
"Period - Builder and digger heads can be made periodic by changing the period value to something other than 1. This determines how frequently they trigger. A period of 1 triggers on every block, a period of 2 triggers once every second block, a period of 3 triggers once every third block, etc. These are useful when setting up a machine to place regularly-spaced features as it goes. For example, you could have a builder head that places a torch every 8 steps, or a digger block that punches a landing in the side of a vertical stairwell at every level."
|
|
||||||
.."\n\n"..
|
|
||||||
"Offset - The location at which a periodic module triggers is globally uniform. This is handy if you want to line up the blocks you're building (for example, placing pillars and a crosspiece every 4 blocks in a tunnel, or punching alcoves in a wall to place glass windows). If you wish to change how the pattern lines up, modify the \"offset\" setting."
|
|
||||||
.."\n\n"..
|
|
||||||
"Shift-right-clicking - since most of the blocks of the digging machine have control screens associated with right-clicking, building additional blocks on top of them or rotating them with the screwdriver requires the shift key to be held down when right-clicking on them."
|
|
||||||
.."\n\n"..
|
|
||||||
"Traction - Digtrons cannot fly. By default, they need to be touching one block of solid ground for every three blocks of Digtron in order to move. Digtrons can fall, though - traction is never needed when a Digtron is moving downward. \"Pusher\" controllers can ignore the need for traction when moving in any direction.")
|
|
||||||
}})
|
|
||||||
|
|
||||||
doc.add_entry("digtron", "noises", {
|
|
||||||
name = S("Audio cues"),
|
|
||||||
data = { text =
|
|
||||||
S("When a digging machine is unable to complete a cycle it will make one of several noises to indicate what the problem is. It will also set its mouseover text to explain what went wrong."
|
|
||||||
.."\n\n"..
|
|
||||||
"Squealing traction wheels indicates a mobility problem. If the squealing is accompanied by a buzzer, the digging machine has encountered an obstruction it can't dig through. This could be a protected region (the digging machine has only the priviledges of the player triggering it), a chest containing items, or perhaps the digger was incorrectly designed and can't dig the correctly sized and shaped cavity for it to move forward into. There are many possibilities."
|
|
||||||
.."\n\n"..
|
|
||||||
"Squealing traction wheels with no accompanying buzzer indicates that the digging machine doesn't have enough solid adjacent blocks to push off of. Tunnel boring machines cannot fly or swim, not even through lava, and they don't dig fast enough to \"catch sick air\" when they emerge from a cliffside. If you wish to cross a chasm you'll need to ensure that there are builder heads placing a solid surface as you go. If you've built a very tall digtron with a small surface footprint you may need to improve its traction by adding structural modules that touch the ground."
|
|
||||||
.."\n\n"..
|
|
||||||
"A buzzer by itself indicates that the Digtron has run out of fuel. There may be traces remaining in the hopper, but they're not enough to execute the next dig/build cycle."
|
|
||||||
.."\n\n"..
|
|
||||||
"A ringing bell indicates that there are insufficient materials in inventory to supply all the builder heads for this cycle."
|
|
||||||
.."\n\n"..
|
|
||||||
"A short high-pitched honk means that one or more of the builder heads don't have an item set. A common oversight, especially with large and elaborate digging machines, that might be hard to notice and annoying to fix if not noticed right away."
|
|
||||||
.."\n\n"..
|
|
||||||
"Splashing water sounds means your Digtron is digging adjacent to (or through) water-containing blocks. Digtrons are waterproof, but this might be a useful indication that you should take care when installing doors in the tunnel walls you've placed here."
|
|
||||||
.."\n\n"..
|
|
||||||
"A triple \"voop voop voop!\" alarm indicates that there is lava adjacent to your Digtron. Digtrons can't penetrate lava by default, and this alarm indicates that a non-lava-proof Digtron operator may wish to exercise caution when opening the door to clear the obstruction.")
|
|
||||||
}})
|
|
||||||
|
|
||||||
doc.add_entry("digtron", "tips", {
|
|
||||||
name = S("Tips and Tricks"),
|
|
||||||
data = { text =
|
|
||||||
S("To more easily visualize the operation of a Digtron, imagine that its cycle of operation follows these steps in order:"
|
|
||||||
.."\n\n"..
|
|
||||||
"* Dig\n* Move\n* Build\n* Allow dust to settle (ie, sand and gravel fall)"
|
|
||||||
.."\n\n"..
|
|
||||||
"If you're building a repeating pattern of blocks, your periodicity should be one larger than your largest offset. For example, if you've laid out builders to create a set of spiral stairs and the offsets are from 0 to 11, you'll want to use periodicity 12."
|
|
||||||
.."\n\n"..
|
|
||||||
"A good way to program a set of builders is to build a complete example of the structure you want them to create, then place builders against the structure and have them \"read\" all of its facings. This also lets you more easily visualize the tricks that might be needed to allow the digtron to pass through the structure as it's being built.")
|
|
||||||
}})
|
|
146
entities.lua
146
entities.lua
@ -1,146 +0,0 @@
|
|||||||
minetest.register_entity("digtron:marker", {
|
|
||||||
initial_properties = {
|
|
||||||
visual = "cube",
|
|
||||||
visual_size = {x=1.05, y=1.05},
|
|
||||||
textures = {"digtron_marker_side.png","digtron_marker_side.png","digtron_marker.png","digtron_marker.png","digtron_marker_side.png","digtron_marker_side.png"},
|
|
||||||
collisionbox = {-0.525, -0.525, -0.525, 0.525, 0.525, 0.525},
|
|
||||||
physical = false,
|
|
||||||
},
|
|
||||||
|
|
||||||
on_activate = function(self, staticdata)
|
|
||||||
minetest.after(5.0,
|
|
||||||
function(self)
|
|
||||||
self.object:remove()
|
|
||||||
end,
|
|
||||||
self)
|
|
||||||
end,
|
|
||||||
|
|
||||||
on_rightclick=function(self, clicker)
|
|
||||||
self.object:remove()
|
|
||||||
end,
|
|
||||||
|
|
||||||
on_punch = function(self, hitter)
|
|
||||||
self.object:remove()
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_entity("digtron:marker_vertical", {
|
|
||||||
initial_properties = {
|
|
||||||
visual = "cube",
|
|
||||||
visual_size = {x=1.05, y=1.05},
|
|
||||||
textures = {"digtron_marker.png","digtron_marker.png","digtron_marker_side.png^[transformR90","digtron_marker_side.png^[transformR90","digtron_marker_side.png^[transformR90","digtron_marker_side.png^[transformR90"},
|
|
||||||
collisionbox = {-0.525, -0.525, -0.525, 0.525, 0.525, 0.525},
|
|
||||||
physical = false,
|
|
||||||
},
|
|
||||||
|
|
||||||
on_activate = function(self, staticdata)
|
|
||||||
minetest.after(5.0,
|
|
||||||
function(self)
|
|
||||||
self.object:remove()
|
|
||||||
end,
|
|
||||||
self)
|
|
||||||
end,
|
|
||||||
|
|
||||||
on_rightclick=function(self, clicker)
|
|
||||||
self.object:remove()
|
|
||||||
end,
|
|
||||||
|
|
||||||
on_punch = function(self, hitter)
|
|
||||||
self.object:remove()
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_entity("digtron:marker_crate_good", {
|
|
||||||
initial_properties = {
|
|
||||||
visual = "cube",
|
|
||||||
visual_size = {x=1.05, y=1.05},
|
|
||||||
textures = {"digtron_crate.png", "digtron_crate.png", "digtron_crate.png", "digtron_crate.png", "digtron_crate.png", "digtron_crate.png"},
|
|
||||||
collisionbox = {-0.525, -0.525, -0.525, 0.525, 0.525, 0.525},
|
|
||||||
physical = false,
|
|
||||||
},
|
|
||||||
|
|
||||||
on_activate = function(self, staticdata)
|
|
||||||
minetest.after(digtron.config.marker_crate_good_duration,
|
|
||||||
function(self)
|
|
||||||
self.object:remove()
|
|
||||||
end,
|
|
||||||
self)
|
|
||||||
end,
|
|
||||||
|
|
||||||
on_rightclick=function(self, clicker)
|
|
||||||
self.object:remove()
|
|
||||||
end,
|
|
||||||
|
|
||||||
on_punch = function(self, hitter)
|
|
||||||
self.object:remove()
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_entity("digtron:marker_crate_bad", {
|
|
||||||
initial_properties = {
|
|
||||||
visual = "cube",
|
|
||||||
visual_size = {x=1.05, y=1.05},
|
|
||||||
textures = {"digtron_no_entry.png", "digtron_no_entry.png", "digtron_no_entry.png", "digtron_no_entry.png", "digtron_no_entry.png", "digtron_no_entry.png"},
|
|
||||||
collisionbox = {-0.525, -0.525, -0.525, 0.525, 0.525, 0.525},
|
|
||||||
physical = false,
|
|
||||||
},
|
|
||||||
|
|
||||||
on_activate = function(self, staticdata)
|
|
||||||
minetest.after(digtron.config.marker_crate_bad_duration,
|
|
||||||
function(self)
|
|
||||||
self.object:remove()
|
|
||||||
end,
|
|
||||||
self)
|
|
||||||
end,
|
|
||||||
|
|
||||||
on_rightclick=function(self, clicker)
|
|
||||||
self.object:remove()
|
|
||||||
end,
|
|
||||||
|
|
||||||
on_punch = function(self, hitter)
|
|
||||||
self.object:remove()
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_entity("digtron:builder_item", {
|
|
||||||
|
|
||||||
initial_properties = {
|
|
||||||
hp_max = 1,
|
|
||||||
is_visible = true,
|
|
||||||
visual = "wielditem",
|
|
||||||
visual_size = {x=0.25, y=0.25},
|
|
||||||
collisionbox = {0,0,0,0,0,0},
|
|
||||||
physical = false,
|
|
||||||
textures = {""},
|
|
||||||
automatic_rotate = math.pi * 0.25,
|
|
||||||
},
|
|
||||||
|
|
||||||
on_activate = function(self, staticdata)
|
|
||||||
local props = self.object:get_properties()
|
|
||||||
if staticdata ~= nil and staticdata ~= "" then
|
|
||||||
local pos = self.object:getpos()
|
|
||||||
local node = minetest.get_node(pos)
|
|
||||||
if minetest.get_node_group(node.name, "digtron") ~= 4 then
|
|
||||||
-- We were reactivated without a builder node on our location, self-destruct
|
|
||||||
self.object:remove()
|
|
||||||
return
|
|
||||||
end
|
|
||||||
props.textures = {staticdata}
|
|
||||||
self.object:set_properties(props)
|
|
||||||
elseif digtron.create_builder_item ~= nil then
|
|
||||||
props.textures = {digtron.create_builder_item}
|
|
||||||
self.object:set_properties(props)
|
|
||||||
digtron.create_builder_item = nil
|
|
||||||
else
|
|
||||||
self.object:remove()
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
|
|
||||||
get_staticdata = function(self)
|
|
||||||
local props = self.object:get_properties()
|
|
||||||
if props ~= nil and props.textures ~= nil and props.textures[1] ~= nil then
|
|
||||||
return props.textures[1]
|
|
||||||
end
|
|
||||||
return ""
|
|
||||||
end,
|
|
||||||
})
|
|
118
init.lua
118
init.lua
@ -1,116 +1,8 @@
|
|||||||
digtron = {}
|
digtron = {}
|
||||||
|
digtron.doc = {}
|
||||||
|
|
||||||
digtron.auto_controller_colorize = "#88000030"
|
local modpath = minetest.get_modpath(minetest.get_current_modname())
|
||||||
digtron.pusher_controller_colorize = "#00880030"
|
|
||||||
digtron.soft_digger_colorize = "#88880030"
|
|
||||||
|
|
||||||
-- A global dictionary is used here so that other substitutions can be added easily by other mods, if necessary
|
dofile(modpath.."/controller.lua")
|
||||||
digtron.builder_read_item_substitutions = {
|
dofile(modpath.."/nodes/node_misc.lua")
|
||||||
["default:torch_ceiling"] = "default:torch",
|
dofile(modpath.."/nodes/node_storage.lua")
|
||||||
["default:torch_wall"] = "default:torch",
|
|
||||||
["default:dirt_with_grass"] = "default:dirt",
|
|
||||||
["default:dirt_with_grass_footsteps"] = "default:dirt",
|
|
||||||
["default:dirt_with_dry_grass"] = "default:dirt",
|
|
||||||
["default:dirt_with_rainforest_litter"] = "default:dirt",
|
|
||||||
["default:dirt_with_snow"] = "default:dirt",
|
|
||||||
["default:furnace_active"] = "default:furnace",
|
|
||||||
["farming:soil"] = "default:dirt",
|
|
||||||
["farming:soil_wet"] = "default:dirt",
|
|
||||||
["farming:desert_sand_soil"] = "default:desert_sand",
|
|
||||||
["farming:desert_sand_soil_wet"] = "default:desert_sand",
|
|
||||||
}
|
|
||||||
|
|
||||||
-- Sometimes we want builder heads to call an item's "on_place" method, other times we
|
|
||||||
-- don't want them to. There's no way to tell which situation is best programmatically
|
|
||||||
-- so we have to rely on whitelists to be on the safe side.
|
|
||||||
|
|
||||||
--first exact matches are tested, and the value given in this global table is returned
|
|
||||||
digtron.builder_on_place_items = {
|
|
||||||
["default:torch"] = true,
|
|
||||||
}
|
|
||||||
|
|
||||||
-- Then a string prefix is checked, returning this value. Useful for enabling on_placed on a mod-wide basis.
|
|
||||||
digtron.builder_on_place_prefixes = {
|
|
||||||
["farming:"] = true,
|
|
||||||
["farming_plus:"] = true,
|
|
||||||
["crops:"] = true,
|
|
||||||
}
|
|
||||||
|
|
||||||
-- Finally, items belonging to group "digtron_on_place" will have their on_place methods called.
|
|
||||||
|
|
||||||
local digtron_modpath = minetest.get_modpath( "digtron" )
|
|
||||||
|
|
||||||
dofile( digtron_modpath .. "/class_fakeplayer.lua")
|
|
||||||
|
|
||||||
digtron.fake_player = DigtronFakePlayer.create({x=0,y=0,z=0}, "fake_player") -- since we only need one fake player at a time and it doesn't retain useful state, create a global one and just update it as needed.
|
|
||||||
|
|
||||||
dofile( digtron_modpath .. "/config.lua" )
|
|
||||||
dofile( digtron_modpath .. "/util.lua" )
|
|
||||||
dofile( digtron_modpath .. "/doc.lua" )
|
|
||||||
dofile( digtron_modpath .. "/awards.lua" )
|
|
||||||
dofile( digtron_modpath .. "/class_pointset.lua" )
|
|
||||||
dofile( digtron_modpath .. "/class_layout.lua" )
|
|
||||||
dofile( digtron_modpath .. "/entities.lua" )
|
|
||||||
dofile( digtron_modpath .. "/nodes/node_misc.lua" ) -- contains structure and light nodes
|
|
||||||
dofile( digtron_modpath .. "/nodes/node_storage.lua" ) -- contains inventory and fuel storage nodes
|
|
||||||
dofile( digtron_modpath .. "/nodes/node_diggers.lua" ) -- contains all diggers
|
|
||||||
dofile( digtron_modpath .. "/nodes/node_builders.lua" ) -- contains all builders (there's just one currently)
|
|
||||||
dofile( digtron_modpath .. "/nodes/node_controllers.lua" ) -- controllers
|
|
||||||
dofile( digtron_modpath .. "/nodes/node_axle.lua" ) -- Rotation controller
|
|
||||||
dofile( digtron_modpath .. "/nodes/node_crate.lua" ) -- Digtron portability support
|
|
||||||
dofile( digtron_modpath .. "/nodes/node_item_ejector.lua" ) -- ejects non-building, non-fuel items from inventories
|
|
||||||
dofile( digtron_modpath .. "/nodes/node_duplicator.lua" ) -- constructs copies of existing Digtrons
|
|
||||||
|
|
||||||
--Technic
|
|
||||||
dofile( digtron_modpath .. "/nodes/node_battery_holder.lua" ) -- holds rechargeable batteries from the technic mod
|
|
||||||
dofile( digtron_modpath .. "/nodes/node_power_connector.lua")
|
|
||||||
|
|
||||||
dofile( digtron_modpath .. "/nodes/recipes.lua" )
|
|
||||||
|
|
||||||
dofile( digtron_modpath .. "/upgrades.lua" ) -- various LBMs for upgrading older versions of Digtron.
|
|
||||||
|
|
||||||
-- digtron group numbers:
|
|
||||||
-- 1 - generic digtron node, nothing special is done with these. They're just dragged along.
|
|
||||||
-- 2 - inventory-holding digtron, has a "main" inventory that the digtron can add to and take from.
|
|
||||||
-- 3 - digger head, has an "execute_dig" method in its definition
|
|
||||||
-- 4 - builder head, has a "test_build" and "execute_build" method in its definition
|
|
||||||
-- 5 - fuel-holding digtron, has a "fuel" invetory that the control node can draw fuel items from. Separate from general inventory, nothing gets put here automatically.
|
|
||||||
-- 6 - holds both fuel and main inventories
|
|
||||||
-- 7 - holds batteries (RE Battery from technic) to provide clean renewable power
|
|
||||||
-- 8 - connects to adjacent HV technic cable
|
|
||||||
-- 9 - connects to pipeworks, auto-ejects mined items
|
|
||||||
|
|
||||||
-- This code was added for use with FaceDeer's fork of the [catacomb] mod. Paramat's version doesn't support customized protected nodes, which causes
|
|
||||||
-- it to "eat" Digtrons sometimes.
|
|
||||||
if minetest.get_modpath("catacomb") and catacomb ~= nil and catacomb.chamber_protected_nodes ~= nil and catacomb.passage_protected_nodes ~= nil then
|
|
||||||
local digtron_nodes = {
|
|
||||||
minetest.get_content_id("digtron:inventory"),
|
|
||||||
minetest.get_content_id("digtron:fuelstore"),
|
|
||||||
minetest.get_content_id("digtron:battery_holder"),
|
|
||||||
minetest.get_content_id("digtron:combined_storage"),
|
|
||||||
minetest.get_content_id("digtron:axle"),
|
|
||||||
minetest.get_content_id("digtron:builder"),
|
|
||||||
minetest.get_content_id("digtron:controller"),
|
|
||||||
minetest.get_content_id("digtron:auto_controller"),
|
|
||||||
minetest.get_content_id("digtron:pusher"),
|
|
||||||
minetest.get_content_id("digtron:loaded_crate"),
|
|
||||||
minetest.get_content_id("digtron:digger"),
|
|
||||||
minetest.get_content_id("digtron:intermittent_digger"),
|
|
||||||
minetest.get_content_id("digtron:soft_digger"),
|
|
||||||
minetest.get_content_id("digtron:intermittent_soft_digger"),
|
|
||||||
minetest.get_content_id("digtron:dual_digger"),
|
|
||||||
minetest.get_content_id("digtron:dual_soft_digger"),
|
|
||||||
minetest.get_content_id("digtron:structure"),
|
|
||||||
minetest.get_content_id("digtron:light"),
|
|
||||||
minetest.get_content_id("digtron:panel"),
|
|
||||||
minetest.get_content_id("digtron:edge_panel"),
|
|
||||||
minetest.get_content_id("digtron:corner_panel"),
|
|
||||||
minetest.get_content_id("digtron:battery_holder"),
|
|
||||||
minetest.get_content_id("digtron:inventory_ejector"),
|
|
||||||
minetest.get_content_id("digtron:power_connector"),
|
|
||||||
}
|
|
||||||
for _, node_id in pairs(digtron_nodes) do
|
|
||||||
catacomb.chamber_protected_nodes[node_id] = true
|
|
||||||
catacomb.passage_protected_nodes[node_id] = true
|
|
||||||
end
|
|
||||||
end
|
|
1494
locale/template.pot
1494
locale/template.pot
File diff suppressed because it is too large
Load Diff
@ -1,6 +0,0 @@
|
|||||||
@echo off
|
|
||||||
setlocal ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
|
|
||||||
cd ..
|
|
||||||
set LIST=
|
|
||||||
for /r %%X in (*.lua) do set LIST=!LIST! %%X
|
|
||||||
..\intllib\tools\xgettext.bat %LIST%
|
|
7
mod.conf
7
mod.conf
@ -1,7 +0,0 @@
|
|||||||
name = digtron
|
|
||||||
title = Digtron
|
|
||||||
author = FaceDeer
|
|
||||||
description = Adds components for building modular tunnel boring machines
|
|
||||||
license = MIT, LGPL 2.1 or later
|
|
||||||
forum = https://forum.minetest.net/viewtopic.php?t=16295
|
|
||||||
version = 0.8
|
|
@ -1,69 +0,0 @@
|
|||||||
-- internationalization boilerplate
|
|
||||||
local MP = minetest.get_modpath(minetest.get_current_modname())
|
|
||||||
local S, NS = dofile(MP.."/intllib.lua")
|
|
||||||
|
|
||||||
minetest.register_node("digtron:axle", {
|
|
||||||
description = S("Digtron Rotation Axle"),
|
|
||||||
_doc_items_longdesc = digtron.doc.axle_longdesc,
|
|
||||||
_doc_items_usagehelp = digtron.doc.axle_usagehelp,
|
|
||||||
groups = {cracky = 3, oddly_breakable_by_hand=3, digtron = 1},
|
|
||||||
drop = "digtron:axle",
|
|
||||||
sounds = digtron.metal_sounds,
|
|
||||||
paramtype = "light",
|
|
||||||
paramtype2= "facedir",
|
|
||||||
is_ground_content = false,
|
|
||||||
-- Aims in the +Z direction by default
|
|
||||||
tiles = {
|
|
||||||
"digtron_plate.png^digtron_axel_top.png",
|
|
||||||
"digtron_plate.png^digtron_axel_top.png",
|
|
||||||
"digtron_plate.png^digtron_axel_side.png",
|
|
||||||
"digtron_plate.png^digtron_axel_side.png",
|
|
||||||
"digtron_plate.png^digtron_axel_side.png",
|
|
||||||
"digtron_plate.png^digtron_axel_side.png",
|
|
||||||
},
|
|
||||||
|
|
||||||
drawtype = "nodebox",
|
|
||||||
node_box = {
|
|
||||||
type = "fixed",
|
|
||||||
fixed = {
|
|
||||||
{-0.5, 0.3125, -0.3125, 0.5, 0.5, 0.3125}, -- Uppercap
|
|
||||||
{-0.5, -0.5, -0.3125, 0.5, -0.3125, 0.3125}, -- Lowercap
|
|
||||||
{-0.3125, 0.3125, -0.5, 0.3125, 0.5, -0.3125}, -- Uppercap_edge2
|
|
||||||
{-0.3125, 0.3125, 0.3125, 0.3125, 0.5, 0.5}, -- Uppercap_edge1
|
|
||||||
{-0.3125, -0.5, -0.5, 0.3125, -0.3125, -0.3125}, -- Lowercap_edge1
|
|
||||||
{-0.3125, -0.5, 0.3125, 0.3125, -0.3125, 0.5}, -- Lowercap_edge2
|
|
||||||
{-0.25, -0.3125, -0.25, 0.25, 0.3125, 0.25}, -- Axle
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
if meta:get_string("waiting") == "true" then
|
|
||||||
-- Been too soon since last time the digtron rotated.
|
|
||||||
return
|
|
||||||
end
|
|
||||||
local image = DigtronLayout.create(pos, clicker)
|
|
||||||
if image:rotate_layout_image(node.param2) == false then
|
|
||||||
-- This should be impossible, but if self-validation fails abort.
|
|
||||||
return
|
|
||||||
end
|
|
||||||
if image:can_write_layout_image() then
|
|
||||||
if image:write_layout_image(clicker) then
|
|
||||||
minetest.sound_play("whirr", {gain=1.0, pos=pos})
|
|
||||||
meta = minetest.get_meta(pos)
|
|
||||||
meta:set_string("waiting", "true")
|
|
||||||
meta:set_string("infotext", nil)
|
|
||||||
minetest.get_node_timer(pos):start(digtron.config.cycle_time*2)
|
|
||||||
else
|
|
||||||
meta:set_string("infotext", "unrecoverable write_layout_image error")
|
|
||||||
end
|
|
||||||
else
|
|
||||||
minetest.sound_play("buzzer", {gain=1.0, pos=pos})
|
|
||||||
meta:set_string("infotext", S("Digtron is obstructed."))
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
|
|
||||||
on_timer = function(pos, elapsed)
|
|
||||||
minetest.get_meta(pos):set_string("waiting", nil)
|
|
||||||
end,
|
|
||||||
})
|
|
@ -1,125 +0,0 @@
|
|||||||
-- internationalization boilerplate
|
|
||||||
local MP = minetest.get_modpath(minetest.get_current_modname())
|
|
||||||
local S, NS = dofile(MP.."/intllib.lua")
|
|
||||||
|
|
||||||
|
|
||||||
-- Battery storage. Controller node draws electrical power from here.
|
|
||||||
-- Note that batttery boxes are digtron group 7.
|
|
||||||
|
|
||||||
local battery_holder_formspec_string = "size[8,9.3]" ..
|
|
||||||
default.gui_bg ..
|
|
||||||
default.gui_bg_img ..
|
|
||||||
default.gui_slots ..
|
|
||||||
"label[0,0;" .. S("Batteries") .. "]" ..
|
|
||||||
"list[current_name;batteries;0,0.6;8,4;]" ..
|
|
||||||
"list[current_player;main;0,5.15;8,1;]" ..
|
|
||||||
"list[current_player;main;0,6.38;8,3;8]" ..
|
|
||||||
"listring[current_name;batteries]" ..
|
|
||||||
"listring[current_player;main]" ..
|
|
||||||
default.get_hotbar_bg(0,5.15)
|
|
||||||
|
|
||||||
local battery_holder_formspec = function(pos, meta)
|
|
||||||
return battery_holder_formspec_string
|
|
||||||
end
|
|
||||||
|
|
||||||
local holder_groups = {cracky = 3, oddly_breakable_by_hand = 3, digtron = 7, tubedevice = 1, tubedevice_receiver = 1}
|
|
||||||
if not minetest.get_modpath("technic") then
|
|
||||||
-- if technic isn't installed there's no point in offering battery holders.
|
|
||||||
-- leave them registered, though, in case technic is being removed from an existing server.
|
|
||||||
holder_groups.not_in_creative_inventory = 1
|
|
||||||
end
|
|
||||||
|
|
||||||
minetest.register_node("digtron:battery_holder", {
|
|
||||||
description = S("Digtron Battery Holder"),
|
|
||||||
_doc_items_longdesc = digtron.doc.battery_holder_longdesc,
|
|
||||||
_doc_items_usagehelp = digtron.doc.battery_holder_usagehelp,
|
|
||||||
_digtron_formspec = battery_holder_formspec,
|
|
||||||
groups = holder_groups,
|
|
||||||
drop = "digtron:battery_holder",
|
|
||||||
sounds = digtron.metal_sounds,
|
|
||||||
paramtype2= "facedir",
|
|
||||||
drawtype = "nodebox",
|
|
||||||
node_box = {
|
|
||||||
type = "fixed",
|
|
||||||
fixed = {
|
|
||||||
{-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
paramtype = "light",
|
|
||||||
is_ground_content = false,
|
|
||||||
tiles = {
|
|
||||||
"digtron_plate.png^digtron_crossbrace.png^digtron_battery.png",
|
|
||||||
"digtron_plate.png^digtron_crossbrace.png^digtron_battery.png",
|
|
||||||
"digtron_plate.png^digtron_crossbrace.png^digtron_battery.png^digtron_storage.png",
|
|
||||||
"digtron_plate.png^digtron_crossbrace.png^digtron_battery.png^digtron_storage.png",
|
|
||||||
"digtron_plate.png^digtron_crossbrace.png^digtron_battery.png^digtron_storage.png",
|
|
||||||
"digtron_plate.png^digtron_crossbrace.png^digtron_battery.png^digtron_storage.png",
|
|
||||||
},
|
|
||||||
|
|
||||||
on_construct = function(pos)
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
meta:set_string("formspec", battery_holder_formspec(pos, meta))
|
|
||||||
local inv = meta:get_inventory()
|
|
||||||
inv:set_size("batteries", 8*4)
|
|
||||||
end,
|
|
||||||
|
|
||||||
-- Allow all items with energy storage to be placed in the inventory
|
|
||||||
allow_metadata_inventory_put = function(pos, listname, index, stack, player)
|
|
||||||
if listname == "batteries" then
|
|
||||||
local node_name = stack:get_name()
|
|
||||||
|
|
||||||
-- Allow all items with energy storage from technic mod
|
|
||||||
if technic.power_tools[node_name] ~= nil then
|
|
||||||
local meta = stack:get_metadata()
|
|
||||||
local md = minetest.deserialize(meta)
|
|
||||||
-- And specifically if they hold any charge
|
|
||||||
-- Disregard empty batteries, the player should know better
|
|
||||||
if md and md.charge > 0 then
|
|
||||||
return stack:get_count()
|
|
||||||
else
|
|
||||||
return 0
|
|
||||||
end
|
|
||||||
|
|
||||||
else
|
|
||||||
return 0
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return 0
|
|
||||||
end,
|
|
||||||
|
|
||||||
|
|
||||||
can_dig = function(pos,player)
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
local inv = meta:get_inventory()
|
|
||||||
return inv:is_empty("batteries")
|
|
||||||
end,
|
|
||||||
|
|
||||||
-- Pipeworks compatibility
|
|
||||||
-- Because who wouldn't send batteries through pipes if he could?
|
|
||||||
-----------------------------------------------------------------
|
|
||||||
|
|
||||||
tube = (function() if minetest.get_modpath("pipeworks") then return {
|
|
||||||
insert_object = function(pos, node, stack, direction)
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
local inv = meta:get_inventory()
|
|
||||||
return inv:add_item("batteries", stack)
|
|
||||||
end,
|
|
||||||
can_insert = function(pos, node, stack, direction)
|
|
||||||
local meta = stack:get_metadata()
|
|
||||||
local md = minetest.deserialize(meta)
|
|
||||||
-- And specifically if they hold any charge
|
|
||||||
-- Disregard empty batteries, the player should know better
|
|
||||||
if md and md.charge > 0 then
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
local inv = meta:get_inventory()
|
|
||||||
return inv:room_for_item("batteries", stack)
|
|
||||||
end
|
|
||||||
return false
|
|
||||||
end,
|
|
||||||
input_inventory = "batteries",
|
|
||||||
connect_sides = {left = 1, right = 1, back = 1, front = 1, bottom = 1, top = 1}
|
|
||||||
} end end)(),
|
|
||||||
|
|
||||||
after_place_node = (function() if minetest.get_modpath("pipeworks") then return pipeworks.after_place end end)(),
|
|
||||||
after_dig_node = (function() if minetest.get_modpath("pipeworks")then return pipeworks.after_dig end end)()
|
|
||||||
})
|
|
@ -1,357 +0,0 @@
|
|||||||
-- internationalization boilerplate
|
|
||||||
local MP = minetest.get_modpath(minetest.get_current_modname())
|
|
||||||
local S, NS = dofile(MP.."/intllib.lua")
|
|
||||||
|
|
||||||
-- Note: builders go in group 4 and have both test_build and execute_build methods.
|
|
||||||
|
|
||||||
local node_inventory_table = {type="node"} -- a reusable parameter for get_inventory calls, set the pos parameter before using.
|
|
||||||
|
|
||||||
local displace_due_to_help_button = 1.0
|
|
||||||
if minetest.get_modpath("doc") then
|
|
||||||
displace_due_to_help_button = 0.0
|
|
||||||
end
|
|
||||||
|
|
||||||
local builder_formspec_string =
|
|
||||||
"size[8,5.2]" ..
|
|
||||||
default.gui_bg ..
|
|
||||||
default.gui_bg_img ..
|
|
||||||
default.gui_slots ..
|
|
||||||
"list[current_name;main;".. tostring(displace_due_to_help_button/2) ..",0;1,1;]" ..
|
|
||||||
"label[" .. tostring(displace_due_to_help_button/2).. ",0.8;" .. S("Block to build") .. "]" ..
|
|
||||||
"field[" .. tostring(displace_due_to_help_button + 1.3) ..",0.8;1,0.1;extrusion;" .. S("Extrusion") .. ";${extrusion}]" ..
|
|
||||||
"tooltip[extrusion;" .. S("Builder will extrude this many blocks in the direction it is facing.\nCan be set from 1 to @1.\nNote that Digtron won't build into unloaded map regions.", digtron.config.maximum_extrusion) .. "]" ..
|
|
||||||
"field[" .. tostring(displace_due_to_help_button + 2.3) ..",0.8;1,0.1;period;" .. S("Periodicity") .. ";${period}]" ..
|
|
||||||
"tooltip[period;" .. S("Builder will build once every n steps.\nThese steps are globally aligned, so all builders with the\nsame period and offset will build on the same location.") .. "]" ..
|
|
||||||
"field[" .. tostring(displace_due_to_help_button + 3.3) ..",0.8;1,0.1;offset;" .. S("Offset") .. ";${offset}]" ..
|
|
||||||
"tooltip[offset;" .. S("Offsets the start of periodicity counting by this amount.\nFor example, a builder with period 2 and offset 0 builds\nevery even-numbered block and one with period 2 and\noffset 1 builds every odd-numbered block.") .. "]" ..
|
|
||||||
"button_exit[" .. tostring(displace_due_to_help_button + 4.0) ..",0.5;1,0.1;set;" .. S("Save &\nShow") .. "]" ..
|
|
||||||
"tooltip[set;" .. S("Saves settings") .. "]" ..
|
|
||||||
"field[" .. tostring(displace_due_to_help_button + 5.3) .. ",0.8;1,0.1;build_facing;" .. S("Facing") .. ";${build_facing}]" ..
|
|
||||||
"tooltip[build_facing;" .. S("Value from 0-23. Not all block types make use of this.\nUse the 'Read & Save' button to copy the facing of the block\ncurrently in the builder output location.") .. "]" ..
|
|
||||||
"button_exit[" .. tostring(displace_due_to_help_button + 6.0) ..",0.5;1,0.1;read;" .. S("Read &\nSave") .. "]" ..
|
|
||||||
"tooltip[read;" .. S("Reads the facing of the block currently in the build location,\nthen saves all settings.") .. "]" ..
|
|
||||||
"list[current_player;main;0,1.3;8,1;]" ..
|
|
||||||
default.get_hotbar_bg(0,1.3) ..
|
|
||||||
"list[current_player;main;0,2.5;8,3;8]" ..
|
|
||||||
"listring[current_player;main]" ..
|
|
||||||
"listring[current_name;main]"
|
|
||||||
|
|
||||||
if minetest.get_modpath("doc") then
|
|
||||||
builder_formspec_string = builder_formspec_string ..
|
|
||||||
"button_exit[7.0,0.5;1,0.1;help;" .. S("Help") .. "]" ..
|
|
||||||
"tooltip[help;" .. S("Show documentation about this block") .. "]"
|
|
||||||
end
|
|
||||||
|
|
||||||
local builder_formspec = function(pos, meta)
|
|
||||||
local nodemeta = "nodemeta:"..pos.x .. "," .. pos.y .. "," ..pos.z
|
|
||||||
return builder_formspec_string
|
|
||||||
:gsub("${extrusion}", meta:get_int("extrusion"), 1)
|
|
||||||
:gsub("${period}", meta:get_int("period"), 1)
|
|
||||||
:gsub("${offset}", meta:get_int("offset"), 1)
|
|
||||||
:gsub("${build_facing}", meta:get_int("build_facing"), 1)
|
|
||||||
:gsub("current_name", "nodemeta:"..pos.x .. "," .. pos.y .. "," ..pos.z, 2)
|
|
||||||
end
|
|
||||||
|
|
||||||
local builder_on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
|
|
||||||
local item_def = itemstack:get_definition()
|
|
||||||
if item_def.type == "node" and minetest.get_item_group(itemstack:get_name(), "digtron") > 0 then
|
|
||||||
local returnstack, success = minetest.item_place_node(itemstack, clicker, pointed_thing)
|
|
||||||
if success and item_def.sounds and item_def.sounds.place and item_def.sounds.place.name then
|
|
||||||
minetest.sound_play(item_def.sounds.place, {pos = pos})
|
|
||||||
end
|
|
||||||
return returnstack, success
|
|
||||||
end
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
minetest.show_formspec(clicker:get_player_name(),
|
|
||||||
"digtron:builder"..minetest.pos_to_string(pos),
|
|
||||||
builder_formspec(pos, meta))
|
|
||||||
end
|
|
||||||
|
|
||||||
minetest.register_on_player_receive_fields(function(sender, formname, fields)
|
|
||||||
|
|
||||||
if formname:sub(1, 15) ~= "digtron:builder" then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
local pos = minetest.string_to_pos(formname:sub(16, -1))
|
|
||||||
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
local period = tonumber(fields.period)
|
|
||||||
local offset = tonumber(fields.offset)
|
|
||||||
local build_facing = tonumber(fields.build_facing)
|
|
||||||
local extrusion = tonumber(fields.extrusion)
|
|
||||||
|
|
||||||
if period and period > 0 then
|
|
||||||
meta:set_int("period", math.floor(tonumber(fields.period)))
|
|
||||||
else
|
|
||||||
period = meta:get_int("period")
|
|
||||||
end
|
|
||||||
if offset then
|
|
||||||
meta:set_int("offset", math.floor(tonumber(fields.offset)))
|
|
||||||
else
|
|
||||||
offset = meta:get_int("offset")
|
|
||||||
end
|
|
||||||
if build_facing and build_facing >= 0 and build_facing < 24 then
|
|
||||||
local inv = meta:get_inventory()
|
|
||||||
local target_item = inv:get_stack("main",1)
|
|
||||||
if target_item:get_definition().paramtype2 == "wallmounted" then
|
|
||||||
if build_facing < 6 then
|
|
||||||
meta:set_int("build_facing", math.floor(build_facing))
|
|
||||||
-- wallmounted facings only run from 0-5
|
|
||||||
end
|
|
||||||
else
|
|
||||||
meta:set_int("build_facing", math.floor(build_facing))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if extrusion and extrusion > 0 and extrusion <= digtron.config.maximum_extrusion then
|
|
||||||
meta:set_int("extrusion", math.floor(tonumber(fields.extrusion)))
|
|
||||||
else
|
|
||||||
extrusion = meta:get_int("extrusion")
|
|
||||||
end
|
|
||||||
|
|
||||||
if fields.set then
|
|
||||||
digtron.show_offset_markers(pos, offset, period)
|
|
||||||
|
|
||||||
elseif fields.read then
|
|
||||||
local facing = minetest.get_node(pos).param2
|
|
||||||
local buildpos = digtron.find_new_pos(pos, facing)
|
|
||||||
local target_node = minetest.get_node(buildpos)
|
|
||||||
if target_node.name ~= "air" and minetest.get_item_group(target_node.name, "digtron") == 0 then
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
local inv = meta:get_inventory()
|
|
||||||
local target_name = digtron.builder_read_item_substitutions[target_node.name] or target_node.name
|
|
||||||
inv:set_stack("main", 1, target_name)
|
|
||||||
meta:set_int("build_facing", target_node.param2)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if fields.help and minetest.get_modpath("doc") then --check for mod in case someone disabled it after this digger was built
|
|
||||||
minetest.after(0.5, doc.show_entry, sender:get_player_name(), "nodes", "digtron:builder", true)
|
|
||||||
end
|
|
||||||
|
|
||||||
digtron.update_builder_item(pos)
|
|
||||||
end)
|
|
||||||
|
|
||||||
|
|
||||||
-- Builds objects in the targeted node. This is a complicated beastie.
|
|
||||||
minetest.register_node("digtron:builder", {
|
|
||||||
description = S("Digtron Builder Module"),
|
|
||||||
_doc_items_longdesc = digtron.doc.builder_longdesc,
|
|
||||||
_doc_items_usagehelp = digtron.doc.builder_usagehelp,
|
|
||||||
groups = {cracky = 3, oddly_breakable_by_hand=3, digtron = 4},
|
|
||||||
drop = "digtron:builder",
|
|
||||||
sounds = digtron.metal_sounds,
|
|
||||||
paramtype = "light",
|
|
||||||
paramtype2= "facedir",
|
|
||||||
is_ground_content = false,
|
|
||||||
tiles = {
|
|
||||||
"digtron_plate.png^[transformR90",
|
|
||||||
"digtron_plate.png^[transformR270",
|
|
||||||
"digtron_plate.png",
|
|
||||||
"digtron_plate.png^[transformR180",
|
|
||||||
"digtron_plate.png^digtron_builder.png",
|
|
||||||
"digtron_plate.png",
|
|
||||||
},
|
|
||||||
|
|
||||||
drawtype = "nodebox",
|
|
||||||
node_box = {
|
|
||||||
type = "fixed",
|
|
||||||
fixed = {
|
|
||||||
{-0.25, 0.3125, 0.3125, 0.25, 0.5, 0.5}, -- FrontFrame_top
|
|
||||||
{-0.25, -0.5, 0.3125, 0.25, -0.3125, 0.5}, -- FrontFrame_bottom
|
|
||||||
{0.3125, -0.25, 0.3125, 0.5, 0.25, 0.5}, -- FrontFrame_right
|
|
||||||
{-0.5, -0.25, 0.3125, -0.3125, 0.25, 0.5}, -- FrontFrame_left
|
|
||||||
{-0.5, 0.25, -0.5, -0.25, 0.5, 0.5}, -- edge_topright
|
|
||||||
{-0.5, -0.5, -0.5, -0.25, -0.25, 0.5}, -- edge_bottomright
|
|
||||||
{0.25, 0.25, -0.5, 0.5, 0.5, 0.5}, -- edge_topleft
|
|
||||||
{0.25, -0.5, -0.5, 0.5, -0.25, 0.5}, -- edge_bottomleft
|
|
||||||
{-0.25, 0.4375, -0.5, 0.25, 0.5, -0.4375}, -- backframe_top
|
|
||||||
{-0.25, -0.5, -0.5, 0.25, -0.4375, -0.4375}, -- backframe_bottom
|
|
||||||
{-0.5, -0.25, -0.5, -0.4375, 0.25, -0.4375}, -- backframe_left
|
|
||||||
{0.4375, -0.25, -0.5, 0.5, 0.25, -0.4375}, -- Backframe_right
|
|
||||||
{-0.0625, -0.3125, 0.3125, 0.0625, 0.3125, 0.375}, -- frontcross_vertical
|
|
||||||
{-0.3125, -0.0625, 0.3125, 0.3125, 0.0625, 0.375}, -- frontcross_horizontal
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
on_construct = function(pos)
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
meta:set_int("period", 1)
|
|
||||||
meta:set_int("offset", 0)
|
|
||||||
meta:set_int("build_facing", 0)
|
|
||||||
meta:set_int("extrusion", 1)
|
|
||||||
|
|
||||||
local inv = meta:get_inventory()
|
|
||||||
inv:set_size("main", 1)
|
|
||||||
end,
|
|
||||||
|
|
||||||
on_rightclick = builder_on_rightclick,
|
|
||||||
|
|
||||||
on_destruct = function(pos)
|
|
||||||
digtron.remove_builder_item(pos)
|
|
||||||
end,
|
|
||||||
|
|
||||||
after_place_node = function(pos)
|
|
||||||
digtron.update_builder_item(pos)
|
|
||||||
end,
|
|
||||||
|
|
||||||
allow_metadata_inventory_put = function(pos, listname, index, stack, player)
|
|
||||||
local stack_name = stack:get_name()
|
|
||||||
|
|
||||||
if minetest.get_item_group(stack_name, "digtron") ~= 0 then
|
|
||||||
return 0 -- don't allow builders to be set to build Digtron nodes, they'll just clog the output.
|
|
||||||
end
|
|
||||||
|
|
||||||
local stack_def = minetest.registered_nodes[stack_name]
|
|
||||||
if not stack_def and not digtron.whitelisted_on_place(stack_name) then
|
|
||||||
return 0 -- don't allow craft items unless their on_place is whitelisted.
|
|
||||||
end
|
|
||||||
|
|
||||||
node_inventory_table.pos = pos
|
|
||||||
local inv = minetest.get_inventory(node_inventory_table)
|
|
||||||
inv:set_stack(listname, index, stack:take_item(1))
|
|
||||||
|
|
||||||
-- If we're adding a wallmounted item and the build facing is greater than 5, reset it to 0
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
if stack_def ~= nil and stack_def.paramtype2 == "wallmounted" and tonumber(meta:get_int("build_facing")) > 5 then
|
|
||||||
meta:set_int("build_facing", 0)
|
|
||||||
end
|
|
||||||
|
|
||||||
return 0
|
|
||||||
end,
|
|
||||||
|
|
||||||
allow_metadata_inventory_take = function(pos, listname, index, stack, player)
|
|
||||||
node_inventory_table.pos = pos
|
|
||||||
local inv = minetest.get_inventory(node_inventory_table)
|
|
||||||
inv:set_stack(listname, index, ItemStack(""))
|
|
||||||
return 0
|
|
||||||
end,
|
|
||||||
|
|
||||||
-- "builder at pos, imagine that you're in test_pos. If you're willing and able to build from there, take the item you need from inventory.
|
|
||||||
-- return the item you took and the inventory location you took it from so it can be put back after all the other builders have been tested.
|
|
||||||
-- If you couldn't get the item from inventory, return an error code so we can abort the cycle.
|
|
||||||
-- If you're not supposed to build at all, or the location is obstructed, return 0 to let us know you're okay and we shouldn't abort."
|
|
||||||
|
|
||||||
--return code and accompanying value:
|
|
||||||
-- 0, {} -- not supposed to build, no error
|
|
||||||
-- 1, {{itemstack, source inventory pos}, ...} -- can build, took items from inventory
|
|
||||||
-- 2, {{itemstack, source inventory pos}, ...}, itemstack -- was supposed to build, but couldn't get the item from inventory
|
|
||||||
-- 3, {} -- builder configuration error
|
|
||||||
test_build = function(pos, test_pos, inventory_positions, protected_nodes, nodes_dug, controlling_coordinate, controller_pos)
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
local facing = minetest.get_node(pos).param2
|
|
||||||
local buildpos = digtron.find_new_pos(test_pos, facing)
|
|
||||||
|
|
||||||
if (buildpos[controlling_coordinate] + meta:get_int("offset")) % meta:get_int("period") ~= 0 then
|
|
||||||
--It's not the builder's turn to build right now.
|
|
||||||
return 0, {}
|
|
||||||
end
|
|
||||||
|
|
||||||
local extrusion_count = 0
|
|
||||||
local extrusion_target = meta:get_int("extrusion")
|
|
||||||
if extrusion_target == nil or extrusion_target < 1 or extrusion_target > 100 then
|
|
||||||
extrusion_target = 1 -- failsafe
|
|
||||||
end
|
|
||||||
|
|
||||||
local return_items = {}
|
|
||||||
|
|
||||||
node_inventory_table.pos = pos
|
|
||||||
local inv = minetest.get_inventory(node_inventory_table)
|
|
||||||
local item_stack = inv:get_stack("main", 1)
|
|
||||||
|
|
||||||
if item_stack:is_empty() then
|
|
||||||
return 3, {} -- error code for "this builder's item slot is unset"
|
|
||||||
end
|
|
||||||
|
|
||||||
while extrusion_count < extrusion_target do
|
|
||||||
if not digtron.can_move_to(buildpos, protected_nodes, nodes_dug) then
|
|
||||||
--using "can_move_to" instead of "can_build_to" test case in case the builder is pointed "backward", and will thus
|
|
||||||
--be building into the space that it's currently in and will be vacating after moving, or in case the builder is aimed
|
|
||||||
--sideways and a fellow digtron node was ahead of it (will also be moving out of the way).
|
|
||||||
|
|
||||||
--If the player has built his digtron stupid (eg has another digtron node in the place the builder wants to build) this
|
|
||||||
--assumption is wrong, but I can't hold the player's hand through *every* possible bad design decision. Worst case,
|
|
||||||
--the digtron will think its inventory can't handle the next build step and abort the build when it actually could have
|
|
||||||
--managed one more cycle. That's not a bad outcome for a digtron array that was built stupidly to begin with.
|
|
||||||
return 1, return_items
|
|
||||||
end
|
|
||||||
|
|
||||||
local source_location = digtron.take_from_inventory(item_stack:get_name(), inventory_positions)
|
|
||||||
if source_location ~= nil then
|
|
||||||
table.insert(return_items, {item=item_stack, location=source_location})
|
|
||||||
else
|
|
||||||
return 2, return_items, item_stack -- error code for "needed an item but couldn't get it from inventory"
|
|
||||||
end
|
|
||||||
extrusion_count = extrusion_count + 1
|
|
||||||
buildpos = digtron.find_new_pos(buildpos, facing)
|
|
||||||
end
|
|
||||||
|
|
||||||
return 1, return_items
|
|
||||||
end,
|
|
||||||
|
|
||||||
execute_build = function(pos, player, inventory_positions, protected_nodes, nodes_dug, controlling_coordinate, controller_pos)
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
local build_facing = tonumber(meta:get_int("build_facing"))
|
|
||||||
local facing = minetest.get_node(pos).param2
|
|
||||||
local buildpos = digtron.find_new_pos(pos, facing)
|
|
||||||
|
|
||||||
if (buildpos[controlling_coordinate] + meta:get_int("offset")) % meta:get_int("period") ~= 0 then
|
|
||||||
return 0
|
|
||||||
end
|
|
||||||
|
|
||||||
local extrusion_count = 0
|
|
||||||
local extrusion_target = meta:get_int("extrusion")
|
|
||||||
if extrusion_target == nil or extrusion_target < 1 or extrusion_target > 100 then
|
|
||||||
extrusion_target = 1 -- failsafe
|
|
||||||
end
|
|
||||||
local built_count = 0
|
|
||||||
|
|
||||||
node_inventory_table.pos = pos
|
|
||||||
local inv = minetest.get_inventory(node_inventory_table)
|
|
||||||
local item_stack = inv:get_stack("main", 1)
|
|
||||||
if item_stack:is_empty() then
|
|
||||||
return built_count
|
|
||||||
end
|
|
||||||
|
|
||||||
while extrusion_count < extrusion_target do
|
|
||||||
if not digtron.can_build_to(buildpos, protected_nodes, nodes_dug) then
|
|
||||||
return built_count
|
|
||||||
end
|
|
||||||
|
|
||||||
local oldnode = minetest.get_node(buildpos)
|
|
||||||
|
|
||||||
if not digtron.config.uses_resources then
|
|
||||||
local returned_stack, success = digtron.item_place_node(item_stack, player, buildpos, build_facing)
|
|
||||||
if success == true then
|
|
||||||
minetest.log("action", string.format("%s uses Digtron to build %s at (%d, %d, %d), displacing %s", player:get_player_name(), item_stack:get_name(), buildpos.x, buildpos.y, buildpos.z, oldnode.name))
|
|
||||||
nodes_dug:set(buildpos.x, buildpos.y, buildpos.z, false)
|
|
||||||
built_count = built_count + 1
|
|
||||||
else
|
|
||||||
return built_count
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local sourcepos = digtron.take_from_inventory(item_stack:get_name(), inventory_positions)
|
|
||||||
if sourcepos == nil then
|
|
||||||
-- item not in inventory! Need to sound the angry buzzer to let the player know, so return a negative number.
|
|
||||||
return (built_count + 1) * -1
|
|
||||||
end
|
|
||||||
local returned_stack, success = digtron.item_place_node(ItemStack(item_stack), player, buildpos, build_facing)
|
|
||||||
if success == true then
|
|
||||||
minetest.log("action", string.format("%s uses Digtron to build %s at (%d, %d, %d), displacing %s", player:get_player_name(), item_stack:get_name(), buildpos.x, buildpos.y, buildpos.z, oldnode.name))
|
|
||||||
--flag this node as *not* to be dug.
|
|
||||||
nodes_dug:set(buildpos.x, buildpos.y, buildpos.z, false)
|
|
||||||
digtron.award_item_built(item_stack:get_name(), player)
|
|
||||||
built_count = built_count + 1
|
|
||||||
else
|
|
||||||
--failed to build, target node probably obstructed. Put the item back in inventory.
|
|
||||||
--Should probably never reach this since we're guarding against can_build_to, above, but this makes things safe if we somehow do.
|
|
||||||
digtron.place_in_specific_inventory(item_stack, sourcepos, inventory_positions, controller_pos)
|
|
||||||
return built_count
|
|
||||||
end
|
|
||||||
|
|
||||||
extrusion_count = extrusion_count + 1
|
|
||||||
buildpos = digtron.find_new_pos(buildpos, facing)
|
|
||||||
end
|
|
||||||
return built_count
|
|
||||||
end,
|
|
||||||
})
|
|
@ -1,350 +0,0 @@
|
|||||||
-- internationalization boilerplate
|
|
||||||
local MP = minetest.get_modpath(minetest.get_current_modname())
|
|
||||||
local S, NS = dofile(MP.."/intllib.lua")
|
|
||||||
|
|
||||||
local controller_nodebox ={
|
|
||||||
{-0.3125, -0.3125, -0.3125, 0.3125, 0.3125, 0.3125}, -- Core
|
|
||||||
{-0.1875, 0.3125, -0.1875, 0.1875, 0.5, 0.1875}, -- +y_connector
|
|
||||||
{-0.1875, -0.5, -0.1875, 0.1875, -0.3125, 0.1875}, -- -y_Connector
|
|
||||||
{0.3125, -0.1875, -0.1875, 0.5, 0.1875, 0.1875}, -- +x_connector
|
|
||||||
{-0.5, -0.1875, -0.1875, -0.3125, 0.1875, 0.1875}, -- -x_connector
|
|
||||||
{-0.1875, -0.1875, 0.3125, 0.1875, 0.1875, 0.5}, -- +z_connector
|
|
||||||
{-0.5, 0.125, -0.5, -0.125, 0.5, -0.3125}, -- back_connector_3
|
|
||||||
{0.125, 0.125, -0.5, 0.5, 0.5, -0.3125}, -- back_connector_1
|
|
||||||
{0.125, -0.5, -0.5, 0.5, -0.125, -0.3125}, -- back_connector_2
|
|
||||||
{-0.5, -0.5, -0.5, -0.125, -0.125, -0.3125}, -- back_connector_4
|
|
||||||
}
|
|
||||||
|
|
||||||
local node_inventory_table = {type="node"} -- a reusable parameter for get_inventory calls, set the pos parameter before using.
|
|
||||||
|
|
||||||
-- Master controller. Most complicated part of the whole system. Determines which direction a digtron moves and triggers all of its component parts.
|
|
||||||
minetest.register_node("digtron:controller", {
|
|
||||||
description = S("Digtron Control Module"),
|
|
||||||
_doc_items_longdesc = digtron.doc.controller_longdesc,
|
|
||||||
_doc_items_usagehelp = digtron.doc.controller_usagehelp,
|
|
||||||
groups = {cracky = 3, oddly_breakable_by_hand = 3, digtron = 1},
|
|
||||||
drop = "digtron:controller",
|
|
||||||
sounds = digtron.metal_sounds,
|
|
||||||
paramtype = "light",
|
|
||||||
paramtype2= "facedir",
|
|
||||||
is_ground_content = false,
|
|
||||||
-- Aims in the +Z direction by default
|
|
||||||
tiles = {
|
|
||||||
"digtron_plate.png^[transformR90",
|
|
||||||
"digtron_plate.png^[transformR270",
|
|
||||||
"digtron_plate.png",
|
|
||||||
"digtron_plate.png^[transformR180",
|
|
||||||
"digtron_plate.png",
|
|
||||||
"digtron_plate.png^digtron_control.png",
|
|
||||||
},
|
|
||||||
|
|
||||||
drawtype = "nodebox",
|
|
||||||
node_box = {
|
|
||||||
type = "fixed",
|
|
||||||
fixed = controller_nodebox,
|
|
||||||
},
|
|
||||||
|
|
||||||
on_construct = function(pos)
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
meta:set_float("fuel_burning", 0.0)
|
|
||||||
meta:set_string("infotext", S("Heat remaining in controller furnace: @1", 0))
|
|
||||||
end,
|
|
||||||
|
|
||||||
on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
if meta:get_string("waiting") == "true" then
|
|
||||||
-- Been too soon since last time the digtron did a cycle.
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local newpos, status, return_code = digtron.execute_dig_cycle(pos, clicker)
|
|
||||||
|
|
||||||
meta = minetest.get_meta(newpos)
|
|
||||||
if status ~= nil then
|
|
||||||
meta:set_string("infotext", status)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Start the delay before digtron can run again.
|
|
||||||
minetest.get_meta(newpos):set_string("waiting", "true")
|
|
||||||
minetest.get_node_timer(newpos):start(digtron.config.cycle_time)
|
|
||||||
end,
|
|
||||||
|
|
||||||
on_timer = function(pos, elapsed)
|
|
||||||
minetest.get_meta(pos):set_string("waiting", nil)
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Auto-controller
|
|
||||||
---------------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
local auto_formspec = "size[8,6.2]" ..
|
|
||||||
default.gui_bg ..
|
|
||||||
default.gui_bg_img ..
|
|
||||||
default.gui_slots ..
|
|
||||||
"container[2.0,0]" ..
|
|
||||||
"field[0.0,0.8;1,0.1;cycles;" .. S("Cycles").. ";${cycles}]" ..
|
|
||||||
"tooltip[cycles;" .. S("When triggered, this controller will try to run for the given number of cycles.\nThe cycle count will decrement as it runs, so if it gets halted by a problem\nyou can fix the problem and restart.").. "]" ..
|
|
||||||
"button_exit[0.7,0.5;1,0.1;set;" .. S("Set").. "]" ..
|
|
||||||
"tooltip[set;" .. S("Saves the cycle setting without starting the controller running").. "]" ..
|
|
||||||
"button_exit[1.7,0.5;1,0.1;execute;" .. S("Set &\nExecute").. "]" ..
|
|
||||||
"tooltip[execute;" .. S("Begins executing the given number of cycles").. "]" ..
|
|
||||||
"field[0.0,2.0;1,0.1;slope;" .. S("Slope").. ";${slope}]" ..
|
|
||||||
"tooltip[slope;" .. S("For diagonal digging. After moving forward this number of nodes the auto controller\nwill add an additional cycle moving the digtron laterally in the\ndirection of the arrows on the side of this controller.\nSet to 0 for no lateral digging.").. "]" ..
|
|
||||||
"field[1.0,2.0;1,0.1;offset;" .. S("Offset").. ";${offset}]" ..
|
|
||||||
"tooltip[offset;" .. S("Sets the offset of the lateral motion defined in the Slope field.\nNote: this offset is relative to the controller's location.\nThe controller will move laterally when it reaches the indicated point.").. "]" ..
|
|
||||||
"field[2.0,2.0;1,0.1;period;" .. S("Delay").. ";${period}]" ..
|
|
||||||
"tooltip[period;" .. S("Number of seconds to wait between each cycle").. "]" ..
|
|
||||||
"list[current_name;stop;3.0,0.7;1,1;]" ..
|
|
||||||
"label[3.0,1.5;" .. S("Stop block").. "]" ..
|
|
||||||
"container_end[]" ..
|
|
||||||
"list[current_player;main;0,2.3;8,1;]" ..
|
|
||||||
default.get_hotbar_bg(0,2.3) ..
|
|
||||||
"list[current_player;main;0,3.5;8,3;8]" ..
|
|
||||||
"listring[current_player;main]" ..
|
|
||||||
"listring[current_name;stop]"
|
|
||||||
|
|
||||||
if minetest.get_modpath("doc") then
|
|
||||||
auto_formspec = auto_formspec ..
|
|
||||||
"button_exit[7.0,0.5;1,0.1;help;" .. S("Help") .. "]" ..
|
|
||||||
"tooltip[help;" .. S("Show documentation about this block").. "]"
|
|
||||||
end
|
|
||||||
|
|
||||||
local function auto_cycle(pos)
|
|
||||||
local node = minetest.get_node(pos)
|
|
||||||
local controlling_coordinate = digtron.get_controlling_coordinate(pos, node.param2)
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
local player = minetest.get_player_by_name(meta:get_string("triggering_player"))
|
|
||||||
if player == nil or meta:get_string("waiting") == "true" then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local cycle = meta:get_int("cycles")
|
|
||||||
local slope = meta:get_int("slope")
|
|
||||||
|
|
||||||
if meta:get_string("lateral_done") ~= "true" and slope ~= 0 and (pos[controlling_coordinate] + meta:get_int("offset")) % slope == 0 then
|
|
||||||
--Do a downward dig cycle. Don't update the "cycles" count, these don't count towards that.
|
|
||||||
local newpos, status, return_code = digtron.execute_downward_dig_cycle(pos, player)
|
|
||||||
|
|
||||||
if vector.equals(pos, newpos) then
|
|
||||||
status = status .. "\n" .. S("Cycles remaining: @1", cycle) .. "\n" .. S("Halted!")
|
|
||||||
meta:set_string("infotext", status)
|
|
||||||
if return_code == 1 then --return code 1 happens when there's unloaded nodes adjacent, just keep trying.
|
|
||||||
if digtron.config.emerge_unloaded_mapblocks then
|
|
||||||
minetest.emerge_area(vector.add(pos, -80), vector.add(pos, 80))
|
|
||||||
end
|
|
||||||
minetest.after(meta:get_int("period"), auto_cycle, newpos)
|
|
||||||
else
|
|
||||||
meta:set_string("formspec", auto_formspec)
|
|
||||||
end
|
|
||||||
else
|
|
||||||
meta = minetest.get_meta(newpos)
|
|
||||||
minetest.after(meta:get_int("period"), auto_cycle, newpos)
|
|
||||||
meta:set_string("infotext", status)
|
|
||||||
meta:set_string("lateral_done", "true")
|
|
||||||
end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local newpos, status, return_code = digtron.execute_dig_cycle(pos, player)
|
|
||||||
|
|
||||||
if vector.equals(pos, newpos) then
|
|
||||||
status = status .. "\n" .. S("Cycles remaining: @1", cycle) .. "\n" .. S("Halted!")
|
|
||||||
meta:set_string("infotext", status)
|
|
||||||
if return_code == 1 then --return code 1 happens when there's unloaded nodes adjacent, call emerge and keep trying.
|
|
||||||
if digtron.config.emerge_unloaded_mapblocks then
|
|
||||||
minetest.emerge_area(vector.add(pos, -80), vector.add(pos, 80))
|
|
||||||
end
|
|
||||||
minetest.after(meta:get_int("period"), auto_cycle, newpos)
|
|
||||||
else
|
|
||||||
meta:set_string("formspec", auto_formspec)
|
|
||||||
end
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
meta = minetest.get_meta(newpos)
|
|
||||||
cycle = meta:get_int("cycles") - 1
|
|
||||||
meta:set_int("cycles", cycle)
|
|
||||||
status = status .. "\n" .. S("Cycles remaining: @1", cycle)
|
|
||||||
meta:set_string("infotext", status)
|
|
||||||
meta:set_string("lateral_done", nil)
|
|
||||||
|
|
||||||
if cycle > 0 then
|
|
||||||
minetest.after(meta:get_int("period"), auto_cycle, newpos)
|
|
||||||
else
|
|
||||||
meta:set_string("formspec", auto_formspec)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
minetest.register_node("digtron:auto_controller", {
|
|
||||||
description = S("Digtron Automatic Control Module"),
|
|
||||||
_doc_items_longdesc = digtron.doc.auto_controller_longdesc,
|
|
||||||
_doc_items_usagehelp = digtron.doc.auto_controller_usagehelp,
|
|
||||||
--Don't set a _digtron_formspec for this node_def.
|
|
||||||
--Auto-controller has special formspec handling, while active it has no formspec and right-clicking interrupts it.
|
|
||||||
groups = {cracky = 3, oddly_breakable_by_hand = 3, digtron = 1},
|
|
||||||
drop = "digtron:auto_controller",
|
|
||||||
sounds = digtron.metal_sounds,
|
|
||||||
paramtype = "light",
|
|
||||||
paramtype2= "facedir",
|
|
||||||
is_ground_content = false,
|
|
||||||
-- Aims in the +Z direction by default
|
|
||||||
tiles = {
|
|
||||||
"digtron_plate.png^[transformR90^[colorize:" .. digtron.auto_controller_colorize,
|
|
||||||
"digtron_plate.png^[transformR270^[colorize:" .. digtron.auto_controller_colorize,
|
|
||||||
"digtron_plate.png^digtron_axel_side.png^[transformR270^[colorize:" .. digtron.auto_controller_colorize,
|
|
||||||
"digtron_plate.png^digtron_axel_side.png^[transformR270^[colorize:" .. digtron.auto_controller_colorize,
|
|
||||||
"digtron_plate.png^[colorize:" .. digtron.auto_controller_colorize,
|
|
||||||
"digtron_plate.png^digtron_control.png^[colorize:" .. digtron.auto_controller_colorize,
|
|
||||||
},
|
|
||||||
|
|
||||||
drawtype = "nodebox",
|
|
||||||
node_box = {
|
|
||||||
type = "fixed",
|
|
||||||
fixed = controller_nodebox,
|
|
||||||
},
|
|
||||||
|
|
||||||
on_construct = function(pos)
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
meta:set_float("fuel_burning", 0.0)
|
|
||||||
meta:set_string("infotext", S("Heat remaining in controller furnace: @1", 0))
|
|
||||||
meta:set_string("formspec", auto_formspec)
|
|
||||||
-- Reusing offset and period to keep the digtron node-moving code simple, and the names still fit well
|
|
||||||
meta:set_int("period", digtron.config.cycle_time)
|
|
||||||
meta:set_int("offset", 0)
|
|
||||||
meta:set_int("cycles", 0)
|
|
||||||
meta:set_int("slope", 0)
|
|
||||||
|
|
||||||
local inv = meta:get_inventory()
|
|
||||||
inv:set_size("stop", 1)
|
|
||||||
end,
|
|
||||||
|
|
||||||
allow_metadata_inventory_put = function(pos, listname, index, stack, player)
|
|
||||||
if minetest.get_item_group(stack:get_name(), "digtron") ~= 0 then
|
|
||||||
return 0 -- pointless setting a Digtron node as a stop block
|
|
||||||
end
|
|
||||||
node_inventory_table.pos = pos
|
|
||||||
local inv = minetest.get_inventory(node_inventory_table)
|
|
||||||
inv:set_stack(listname, index, stack:take_item(1))
|
|
||||||
return 0
|
|
||||||
end,
|
|
||||||
|
|
||||||
allow_metadata_inventory_take = function(pos, listname, index, stack, player)
|
|
||||||
node_inventory_table.pos = pos
|
|
||||||
local inv = minetest.get_inventory(node_inventory_table)
|
|
||||||
inv:set_stack(listname, index, ItemStack(""))
|
|
||||||
return 0
|
|
||||||
end,
|
|
||||||
|
|
||||||
on_receive_fields = function(pos, formname, fields, sender)
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
local offset = tonumber(fields.offset)
|
|
||||||
local period = tonumber(fields.period)
|
|
||||||
local slope = tonumber(fields.slope)
|
|
||||||
local cycles = tonumber(fields.cycles)
|
|
||||||
|
|
||||||
if period and period > 0 then
|
|
||||||
meta:set_int("period", math.max(digtron.config.cycle_time, math.floor(period)))
|
|
||||||
end
|
|
||||||
|
|
||||||
if offset then
|
|
||||||
meta:set_int("offset", offset)
|
|
||||||
end
|
|
||||||
|
|
||||||
if slope and slope >= 0 then
|
|
||||||
meta:set_int("slope", slope)
|
|
||||||
end
|
|
||||||
|
|
||||||
if cycles and cycles >= 0 then
|
|
||||||
meta:set_int("cycles", math.floor(cycles))
|
|
||||||
if sender:is_player() and cycles > 0 then
|
|
||||||
meta:set_string("triggering_player", sender:get_player_name())
|
|
||||||
if fields.execute then
|
|
||||||
meta:set_string("waiting", nil)
|
|
||||||
meta:set_string("formspec", nil)
|
|
||||||
auto_cycle(pos)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if fields.set and slope and slope > 0 then
|
|
||||||
local node = minetest.get_node(pos)
|
|
||||||
local controlling_coordinate = digtron.get_controlling_coordinate(pos, node.param2)
|
|
||||||
|
|
||||||
local newpos = pos
|
|
||||||
local markerpos = {x=newpos.x, y=newpos.y, z=newpos.z}
|
|
||||||
local x_pos = math.floor((newpos[controlling_coordinate]+offset)/slope)*slope - offset
|
|
||||||
markerpos[controlling_coordinate] = x_pos
|
|
||||||
minetest.add_entity(markerpos, "digtron:marker_vertical")
|
|
||||||
if x_pos >= newpos[controlling_coordinate] then
|
|
||||||
markerpos[controlling_coordinate] = x_pos - slope
|
|
||||||
minetest.add_entity(markerpos, "digtron:marker_vertical")
|
|
||||||
end
|
|
||||||
if x_pos <= newpos[controlling_coordinate] then
|
|
||||||
markerpos[controlling_coordinate] = x_pos + slope
|
|
||||||
minetest.add_entity(markerpos, "digtron:marker_vertical")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if fields.help and minetest.get_modpath("doc") then --check for mod in case someone disabled it after this digger was built
|
|
||||||
minetest.after(0.5, doc.show_entry, sender:get_player_name(), "nodes", "digtron:auto_controller", true)
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
|
|
||||||
on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
meta:set_string("infotext", meta:get_string("infotext") .. "\n" .. S("Interrupted!"))
|
|
||||||
meta:set_string("waiting", "true")
|
|
||||||
meta:set_string("formspec", auto_formspec)
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
|
|
||||||
---------------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
-- A much simplified control unit that only moves the digtron, and doesn't trigger the diggers or builders.
|
|
||||||
-- Handy for shoving a digtron to the side if it's been built a bit off.
|
|
||||||
minetest.register_node("digtron:pusher", {
|
|
||||||
description = S("Digtron Pusher Module"),
|
|
||||||
_doc_items_longdesc = digtron.doc.pusher_longdesc,
|
|
||||||
_doc_items_usagehelp = digtron.doc.pusher_usagehelp,
|
|
||||||
groups = {cracky = 3, oddly_breakable_by_hand=3, digtron = 1},
|
|
||||||
drop = "digtron:pusher",
|
|
||||||
sounds = digtron.metal_sounds,
|
|
||||||
paramtype = "light",
|
|
||||||
paramtype2= "facedir",
|
|
||||||
is_ground_content = false,
|
|
||||||
-- Aims in the +Z direction by default
|
|
||||||
tiles = {
|
|
||||||
"digtron_plate.png^[transformR90^[colorize:" .. digtron.pusher_controller_colorize,
|
|
||||||
"digtron_plate.png^[transformR270^[colorize:" .. digtron.pusher_controller_colorize,
|
|
||||||
"digtron_plate.png^[colorize:" .. digtron.pusher_controller_colorize,
|
|
||||||
"digtron_plate.png^[transformR180^[colorize:" .. digtron.pusher_controller_colorize,
|
|
||||||
"digtron_plate.png^[colorize:" .. digtron.pusher_controller_colorize,
|
|
||||||
"digtron_plate.png^digtron_control.png^[colorize:" .. digtron.pusher_controller_colorize,
|
|
||||||
},
|
|
||||||
|
|
||||||
drawtype = "nodebox",
|
|
||||||
node_box = {
|
|
||||||
type = "fixed",
|
|
||||||
fixed = controller_nodebox,
|
|
||||||
},
|
|
||||||
|
|
||||||
on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
if meta:get_string("waiting") == "true" then
|
|
||||||
-- Been too soon since last time the digtron did a cycle.
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local newpos, status_text, return_code = digtron.execute_move_cycle(pos, clicker)
|
|
||||||
meta = minetest.get_meta(newpos)
|
|
||||||
meta:set_string("infotext", status_text)
|
|
||||||
|
|
||||||
-- Start the delay before digtron can run again.
|
|
||||||
minetest.get_meta(newpos):set_string("waiting", "true")
|
|
||||||
minetest.get_node_timer(newpos):start(digtron.config.cycle_time)
|
|
||||||
end,
|
|
||||||
|
|
||||||
on_timer = function(pos, elapsed)
|
|
||||||
minetest.get_meta(pos):set_string("waiting", nil)
|
|
||||||
end,
|
|
||||||
})
|
|
@ -1,385 +0,0 @@
|
|||||||
-- internationalization boilerplate
|
|
||||||
local MP = minetest.get_modpath(minetest.get_current_modname())
|
|
||||||
local S, NS = dofile(MP.."/intllib.lua")
|
|
||||||
|
|
||||||
local modpath_awards = minetest.get_modpath("awards")
|
|
||||||
|
|
||||||
|
|
||||||
local player_permitted = function(pos, player)
|
|
||||||
if player then
|
|
||||||
if minetest.check_player_privs(player, "protection_bypass") then
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
else
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
local owner = meta:get_string("owner")
|
|
||||||
|
|
||||||
if not owner or owner == "" or owner == player:get_player_name() then
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local store_digtron = function(pos, clicker, loaded_node_name, protected)
|
|
||||||
local layout = DigtronLayout.create(pos, clicker)
|
|
||||||
local protection_prefix = ""
|
|
||||||
local protection_suffix = ""
|
|
||||||
if protected then
|
|
||||||
protection_prefix = S("Digtron Crate") .. "\n" .. S("Owned by @1", clicker:get_player_name() or "")
|
|
||||||
protection_suffix = S("Owned by @1", clicker:get_player_name() or "")
|
|
||||||
end
|
|
||||||
|
|
||||||
if layout.contains_protected_node then
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
minetest.sound_play("buzzer", {gain=0.5, pos=pos})
|
|
||||||
meta:set_string("infotext", protection_prefix .. "\n" .. S("Digtron can't be packaged, it contains protected blocks"))
|
|
||||||
-- no stealing other peoples' digtrons
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
if #layout.all == 1 then
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
minetest.sound_play("buzzer", {gain=0.5, pos=pos})
|
|
||||||
meta:set_string("infotext", protection_prefix .. "\n" .. S("No Digtron components adjacent to package"))
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
digtron.award_crate(layout, clicker:get_player_name())
|
|
||||||
|
|
||||||
local layout_string = layout:serialize()
|
|
||||||
|
|
||||||
-- destroy everything. Note that this includes the empty crate, which will be bundled up with the layout.
|
|
||||||
for _, node_image in pairs(layout.all) do
|
|
||||||
local old_pos = node_image.pos
|
|
||||||
local old_node = node_image.node
|
|
||||||
minetest.remove_node(old_pos)
|
|
||||||
|
|
||||||
if modpath_awards then
|
|
||||||
-- We're about to tell the awards mod that we're digging a node, but we
|
|
||||||
-- don't want it to count toward any actual awards. Pre-decrement.
|
|
||||||
local data = awards.player(clicker:get_player_name())
|
|
||||||
awards.increment_item_counter(data, "dig", old_node.name, -1)
|
|
||||||
end
|
|
||||||
|
|
||||||
for _, callback in ipairs(minetest.registered_on_dignodes) do
|
|
||||||
-- Copy pos and node because callback can modify them
|
|
||||||
local pos_copy = {x=old_pos.x, y=old_pos.y, z=old_pos.z}
|
|
||||||
local oldnode_copy = {name=old_node.name, param1=old_node.param1, param2=old_node.param2}
|
|
||||||
callback(pos_copy, oldnode_copy, clicker)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Create the loaded crate node
|
|
||||||
minetest.set_node(pos, {name=loaded_node_name})
|
|
||||||
minetest.sound_play("machine1", {gain=1.0, pos=pos})
|
|
||||||
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
meta:set_string("crated_layout", layout_string)
|
|
||||||
|
|
||||||
if protected then
|
|
||||||
-- only set owner if protected
|
|
||||||
meta:set_string("owner", clicker:get_player_name() or "")
|
|
||||||
end
|
|
||||||
|
|
||||||
local titlestring = S("Crated @1-block Digtron", tostring(#layout.all-1))
|
|
||||||
meta:set_string("title", titlestring )
|
|
||||||
meta:set_string("infotext", titlestring .. "\n" .. protection_suffix)
|
|
||||||
end
|
|
||||||
|
|
||||||
minetest.register_node("digtron:empty_crate", {
|
|
||||||
description = S("Digtron Crate (Empty)"),
|
|
||||||
_doc_items_longdesc = digtron.doc.empty_crate_longdesc,
|
|
||||||
_doc_items_usagehelp = digtron.doc.empty_crate_usagehelp,
|
|
||||||
groups = {cracky = 3, oddly_breakable_by_hand=3},
|
|
||||||
sounds = default.node_sound_wood_defaults(),
|
|
||||||
tiles = {"digtron_crate.png"},
|
|
||||||
is_ground_content = false,
|
|
||||||
drawtype = "nodebox",
|
|
||||||
node_box = {
|
|
||||||
type = "fixed",
|
|
||||||
fixed = {
|
|
||||||
{-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
paramtype = "light",
|
|
||||||
|
|
||||||
can_dig = function(pos, player)
|
|
||||||
return player and not minetest.is_protected(pos, player:get_player_name())
|
|
||||||
end,
|
|
||||||
|
|
||||||
on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
|
|
||||||
store_digtron(pos, clicker, "digtron:loaded_crate")
|
|
||||||
end
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_node("digtron:empty_locked_crate", {
|
|
||||||
description = S("Digtron Locked Crate (Empty)"),
|
|
||||||
_doc_items_longdesc = digtron.doc.empty_locked_crate_longdesc,
|
|
||||||
_doc_items_usagehelp = digtron.doc.empty_locked_crate_usagehelp,
|
|
||||||
groups = {cracky = 3, oddly_breakable_by_hand=3},
|
|
||||||
sounds = default.node_sound_wood_defaults(),
|
|
||||||
tiles = {"digtron_crate.png","digtron_crate.png","digtron_crate.png^digtron_lock.png","digtron_crate.png^digtron_lock.png","digtron_crate.png^digtron_lock.png","digtron_crate.png^digtron_lock.png"},
|
|
||||||
is_ground_content = false,
|
|
||||||
drawtype = "nodebox",
|
|
||||||
node_box = {
|
|
||||||
type = "fixed",
|
|
||||||
fixed = {
|
|
||||||
{-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
paramtype = "light",
|
|
||||||
on_construct = function(pos)
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
meta:set_string("owner", "")
|
|
||||||
meta:set_string("infotext", "")
|
|
||||||
end,
|
|
||||||
after_place_node = function(pos, placer)
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
meta:set_string("owner", placer:get_player_name() or "")
|
|
||||||
meta:set_string("infotext", S("Digtron Crate") .. "\n" .. S("Owned by @1", placer:get_player_name() or ""))
|
|
||||||
end,
|
|
||||||
can_dig = function(pos,player)
|
|
||||||
return player and not minetest.is_protected(pos, player:get_player_name()) and player_permitted(pos, player)
|
|
||||||
end,
|
|
||||||
on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
|
|
||||||
if player_permitted(pos,clicker) then
|
|
||||||
store_digtron(pos, clicker, "digtron:loaded_locked_crate", true)
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
|
|
||||||
local modpath_doc = minetest.get_modpath("doc")
|
|
||||||
local loaded_formspec_string
|
|
||||||
if modpath_doc then
|
|
||||||
loaded_formspec_string =
|
|
||||||
"size[4.1,1.5]" ..
|
|
||||||
default.gui_bg ..
|
|
||||||
default.gui_bg_img ..
|
|
||||||
default.gui_slots ..
|
|
||||||
"field[0.3,0.5;4,0.5;title;" .. S("Digtron Name") .. ";${title}]" ..
|
|
||||||
"button_exit[0.0,1.2;1,0.1;save;" .. S("Save\nTitle") .. "]" ..
|
|
||||||
"tooltip[save;" .. S("Saves the title of this Digtron") .. "]" ..
|
|
||||||
"button_exit[1.0,1.2;1,0.1;show;" .. S("Show\nBlocks") .. "]" ..
|
|
||||||
"tooltip[show;" .. S("Shows which blocks the packed Digtron will occupy if unpacked") .. "]" ..
|
|
||||||
"button_exit[2.0,1.2;1,0.1;unpack;" .. S("Unpack") .. "]" ..
|
|
||||||
"tooltip[unpack;" .. S("Attempts to unpack the Digtron on this location") .. "]" ..
|
|
||||||
"button_exit[3.0,1.2;1,0.1;help;" .. S("Help") .. "]" ..
|
|
||||||
"tooltip[help;" .. S("Show documentation about this block") .. "]"
|
|
||||||
else
|
|
||||||
loaded_formspec_string =
|
|
||||||
"size[4,1.5]" ..
|
|
||||||
default.gui_bg ..
|
|
||||||
default.gui_bg_img ..
|
|
||||||
default.gui_slots ..
|
|
||||||
"field[0.3,0.5;4,0.5;title;" .. S("Digtron Name") .. ";${title}]" ..
|
|
||||||
"button_exit[0.5,1.2;1,0.1;save;" .. S("Save\nTitle") .. "]" ..
|
|
||||||
"tooltip[show;" .. S("Saves the title of this Digtron") .. "]" ..
|
|
||||||
"button_exit[1.5,1.2;1,0.1;show;" .. S("Show\nBlocks") .. "]" ..
|
|
||||||
"tooltip[save;" .. S("Shows which blocks the packed Digtron will occupy if unpacked") .. "]" ..
|
|
||||||
"button_exit[2.5,1.2;1,0.1;unpack;" .. S("Unpack") .. "]" ..
|
|
||||||
"tooltip[unpack;" .. S("Attempts to unpack the Digtron on this location") .. "]"
|
|
||||||
end
|
|
||||||
|
|
||||||
local loaded_formspec = function(pos, meta)
|
|
||||||
return loaded_formspec_string
|
|
||||||
end
|
|
||||||
|
|
||||||
local loaded_on_recieve = function(pos, fields, sender, protected)
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
|
|
||||||
if fields.unpack or fields.save or fields.show or fields.key_enter then
|
|
||||||
meta:set_string("title", minetest.formspec_escape(fields.title))
|
|
||||||
end
|
|
||||||
local title = meta:get_string("title")
|
|
||||||
local infotext
|
|
||||||
|
|
||||||
if protected then
|
|
||||||
infotext = title .. "\n" .. S("Owned by @1", sender:get_player_name())
|
|
||||||
else
|
|
||||||
infotext = title
|
|
||||||
end
|
|
||||||
meta:set_string("infotext", infotext)
|
|
||||||
|
|
||||||
if fields.help and minetest.get_modpath("doc") then --check for mod in case someone disabled it after this digger was built
|
|
||||||
minetest.after(0.5, doc.show_entry, sender:get_player_name(), "nodes", "digtron:loaded_crate", true)
|
|
||||||
end
|
|
||||||
|
|
||||||
if not (fields.unpack or fields.show) then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local layout_string = meta:get_string("crated_layout")
|
|
||||||
local layout = DigtronLayout.deserialize(layout_string)
|
|
||||||
|
|
||||||
if layout == nil then
|
|
||||||
meta:set_string("infotext", infotext .. "\n" .. S("Unable to read layout from crate metadata, regrettably this Digtron may be corrupted."))
|
|
||||||
minetest.sound_play("buzzer", {gain=0.5, pos=pos})
|
|
||||||
-- Something went horribly wrong
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local protected_node = false
|
|
||||||
local obstructed_node = false
|
|
||||||
|
|
||||||
local pos_diff = vector.subtract(pos, layout.controller)
|
|
||||||
layout.controller = pos
|
|
||||||
for _, node_image in pairs(layout.all) do
|
|
||||||
node_image.pos = vector.add(pos_diff, node_image.pos)
|
|
||||||
if not vector.equals(pos, node_image.pos) then
|
|
||||||
if minetest.is_protected(node_image.pos, sender:get_player_name()) and not minetest.check_player_privs(sender, "protection_bypass") then
|
|
||||||
protected_node = true
|
|
||||||
minetest.add_entity(node_image.pos, "digtron:marker_crate_bad")
|
|
||||||
elseif not minetest.registered_nodes[minetest.get_node(node_image.pos).name].buildable_to then
|
|
||||||
obstructed_node = true
|
|
||||||
minetest.add_entity(node_image.pos, "digtron:marker_crate_bad")
|
|
||||||
else
|
|
||||||
minetest.add_entity(node_image.pos, "digtron:marker_crate_good")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if not fields.unpack then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
if protected_node then
|
|
||||||
meta:set_string("infotext", infotext .. "\n" .. S("Unable to deploy Digtron due to protected blocks in target area"))
|
|
||||||
minetest.sound_play("buzzer", {gain=0.5, pos=pos})
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
if obstructed_node then
|
|
||||||
meta:set_string("infotext", infotext .. "\n" .. S("Unable to deploy Digtron due to obstruction in target area"))
|
|
||||||
minetest.sound_play("buzzer", {gain=0.5, pos=pos})
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
-- build digtron. Since the empty crate was included in the layout, that will overwrite this loaded crate and destroy it.
|
|
||||||
minetest.sound_play("machine2", {gain=1.0, pos=pos})
|
|
||||||
layout:write_layout_image(sender)
|
|
||||||
end
|
|
||||||
|
|
||||||
local loaded_on_dig = function(pos, player, loaded_node_name)
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
|
|
||||||
local stack = ItemStack({name=loaded_node_name, count=1, wear=0})
|
|
||||||
local stack_meta = stack:get_meta()
|
|
||||||
stack_meta:set_string("crated_layout", meta:get_string("crated_layout"))
|
|
||||||
stack_meta:set_string("description", meta:get_string("title"))
|
|
||||||
local inv = player:get_inventory()
|
|
||||||
local stack = inv:add_item("main", stack)
|
|
||||||
if stack:get_count() > 0 then
|
|
||||||
minetest.add_item(pos, stack)
|
|
||||||
end
|
|
||||||
-- call on_dignodes callback
|
|
||||||
minetest.remove_node(pos)
|
|
||||||
end
|
|
||||||
|
|
||||||
local loaded_after_place = function(pos, itemstack)
|
|
||||||
|
|
||||||
-- Older versions of Digtron used this deprecated method for saving layout data on items.
|
|
||||||
-- Maintain backward compatibility here.
|
|
||||||
local deprecated_metadata = itemstack:get_metadata()
|
|
||||||
if deprecated_metadata ~= "" then
|
|
||||||
deprecated_metadata = minetest.deserialize(deprecated_metadata)
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
meta:set_string("crated_layout", deprecated_metadata.layout)
|
|
||||||
meta:set_string("title", deprecated_metadata.title)
|
|
||||||
meta:set_string("infotext", deprecated_metadata.title)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local stack_meta = itemstack:get_meta()
|
|
||||||
local layout = stack_meta:get_string("crated_layout")
|
|
||||||
local title = stack_meta:get_string("description")
|
|
||||||
if layout ~= "" then
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
|
|
||||||
meta:set_string("crated_layout", layout)
|
|
||||||
meta:set_string("title", title)
|
|
||||||
meta:set_string("infotext", title)
|
|
||||||
--meta:set_string("formspec", loaded_formspec(pos, meta)) -- not needed, on_construct handles this
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
minetest.register_node("digtron:loaded_crate", {
|
|
||||||
description = S("Digtron Crate (Loaded)"),
|
|
||||||
_doc_items_longdesc = digtron.doc.loaded_crate_longdesc,
|
|
||||||
_doc_items_usagehelp = digtron.doc.loaded_crate_usagehelp,
|
|
||||||
_digtron_formspec = loaded_formspec,
|
|
||||||
groups = {cracky = 3, oddly_breakable_by_hand=3, not_in_creative_inventory=1, digtron_protected=1},
|
|
||||||
stack_max = 1,
|
|
||||||
sounds = default.node_sound_wood_defaults(),
|
|
||||||
tiles = {"digtron_plate.png^digtron_crate.png"},
|
|
||||||
is_ground_content = false,
|
|
||||||
|
|
||||||
on_construct = function(pos)
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
meta:set_string("formspec", loaded_formspec(pos, meta))
|
|
||||||
end,
|
|
||||||
|
|
||||||
on_receive_fields = function(pos, formname, fields, sender)
|
|
||||||
return loaded_on_recieve(pos, fields, sender)
|
|
||||||
end,
|
|
||||||
|
|
||||||
on_dig = function(pos, node, player)
|
|
||||||
if player and not minetest.is_protected(pos, player:get_player_name()) then
|
|
||||||
return loaded_on_dig(pos, player, "digtron:loaded_crate")
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
|
|
||||||
after_place_node = function(pos, placer, itemstack, pointed_thing)
|
|
||||||
loaded_after_place(pos, itemstack)
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_node("digtron:loaded_locked_crate", {
|
|
||||||
description = S("Digtron Locked Crate (Loaded)"),
|
|
||||||
_doc_items_longdesc = digtron.doc.loaded_locked_crate_longdesc,
|
|
||||||
_doc_items_usagehelp = digtron.doc.loaded_locked_crate_usagehelp,
|
|
||||||
groups = {cracky = 3, oddly_breakable_by_hand=3, not_in_creative_inventory=1, digtron_protected=1},
|
|
||||||
stack_max = 1,
|
|
||||||
sounds = default.node_sound_wood_defaults(),
|
|
||||||
tiles = {"digtron_plate.png^digtron_crate.png","digtron_plate.png^digtron_crate.png","digtron_plate.png^digtron_crate.png^digtron_lock.png","digtron_plate.png^digtron_crate.png^digtron_lock.png","digtron_plate.png^digtron_crate.png^digtron_lock.png","digtron_plate.png^digtron_crate.png^digtron_lock.png"},
|
|
||||||
is_ground_content = false,
|
|
||||||
|
|
||||||
on_construct = function(pos)
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
meta:set_string("owner", "")
|
|
||||||
end,
|
|
||||||
|
|
||||||
on_dig = function(pos, node, player)
|
|
||||||
if player and not minetest.is_protected(pos, player:get_player_name()) and player_permitted(pos,player) then
|
|
||||||
return loaded_on_dig(pos, player, "digtron:loaded_locked_crate")
|
|
||||||
else
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
|
|
||||||
after_place_node = function(pos, placer, itemstack, pointed_thing)
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
meta:set_string("owner", placer:get_player_name() or "")
|
|
||||||
loaded_after_place(pos, itemstack)
|
|
||||||
meta:set_string("infotext", meta:get_string("infotext") .. "\n" .. S("Owned by @1", meta:get_string("owner")))
|
|
||||||
end,
|
|
||||||
|
|
||||||
on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
|
|
||||||
if player_permitted(pos,clicker) then
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
minetest.show_formspec(
|
|
||||||
clicker:get_player_name(),
|
|
||||||
"digtron:loaded_locked_crate"..minetest.pos_to_string(pos),
|
|
||||||
loaded_formspec_string:gsub("${title}", meta:get_string("title"), 1))
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|
||||||
if formname:sub(1, 27) == "digtron:loaded_locked_crate" then
|
|
||||||
local pos = minetest.string_to_pos(formname:sub(28, -1))
|
|
||||||
loaded_on_recieve(pos, fields, player, true)
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
end)
|
|
@ -1,515 +0,0 @@
|
|||||||
-- internationalization boilerplate
|
|
||||||
local MP = minetest.get_modpath(minetest.get_current_modname())
|
|
||||||
local S, NS = dofile(MP.."/intllib.lua")
|
|
||||||
|
|
||||||
-- Note: diggers go in group 3 and have an execute_dig method.
|
|
||||||
|
|
||||||
local damage_hp = digtron.config.damage_hp
|
|
||||||
local damage_hp_half = damage_hp/2
|
|
||||||
|
|
||||||
local digger_nodebox = {
|
|
||||||
{-0.5, -0.5, 0, 0.5, 0.5, 0.4375}, -- Block
|
|
||||||
{-0.4375, -0.3125, 0.4375, 0.4375, 0.3125, 0.5}, -- Cutter1
|
|
||||||
{-0.3125, -0.4375, 0.4375, 0.3125, 0.4375, 0.5}, -- Cutter2
|
|
||||||
{-0.5, -0.125, -0.125, 0.5, 0.125, 0}, -- BackFrame1
|
|
||||||
{-0.125, -0.5, -0.125, 0.125, 0.5, 0}, -- BackFrame2
|
|
||||||
{-0.25, -0.25, -0.5, 0.25, 0.25, 0}, -- Drive
|
|
||||||
}
|
|
||||||
|
|
||||||
local dual_digger_nodebox = {
|
|
||||||
{-0.5, -0.4375, 0, 0.5, 0.5, 0.4375}, -- Block
|
|
||||||
{-0.4375, -0.3125, 0.4375, 0.4375, 0.3125, 0.5}, -- Cutter1
|
|
||||||
{-0.3125, -0.4375, 0.4375, 0.3125, 0.4375, 0.5}, -- Cutter2
|
|
||||||
{-0.5, 0, -0.125, 0.5, 0.125, 0}, -- BackFrame1
|
|
||||||
{-0.25, 0, -0.5, 0.25, 0.25, 0}, -- Drive
|
|
||||||
{-0.25, 0.25, -0.25, 0.25, 0.5, 0}, -- Upper_Drive
|
|
||||||
{-0.5, -0.4375, -0.5, 0.5, 0, 0.4375}, -- Lower_Block
|
|
||||||
{-0.3125, -0.5, -0.4375, 0.3125, -0.4375, 0.4375}, -- Lower_Cutter_1
|
|
||||||
{-0.4375, -0.5, -0.3125, 0.4375, -0.4375, 0.3125}, -- Lower_Cutter_2
|
|
||||||
}
|
|
||||||
|
|
||||||
local modpath_doc = minetest.get_modpath("doc")
|
|
||||||
|
|
||||||
local intermittent_formspec_string = default.gui_bg ..
|
|
||||||
default.gui_bg_img ..
|
|
||||||
default.gui_slots ..
|
|
||||||
"field[0.5,0.8;1,0.1;period;" .. S("Periodicity") .. ";${period}]" ..
|
|
||||||
"tooltip[period;" .. S("Digger will dig once every n steps.\nThese steps are globally aligned, all diggers with\nthe same period and offset will dig on the same location.") .. "]" ..
|
|
||||||
"field[1.5,0.8;1,0.1;offset;" .. S("Offset") .. ";${offset}]" ..
|
|
||||||
"tooltip[offset;" .. S("Offsets the start of periodicity counting by this amount.\nFor example, a digger with period 2 and offset 0 digs\nevery even-numbered block and one with period 2 and\noffset 1 digs every odd-numbered block.") .. "]" ..
|
|
||||||
"button_exit[2.2,0.5;1,0.1;set;" .. S("Save &\nShow") .. "]" ..
|
|
||||||
"tooltip[set;" .. S("Saves settings") .. "]"
|
|
||||||
|
|
||||||
if modpath_doc then
|
|
||||||
intermittent_formspec_string = "size[4.5,1]" .. intermittent_formspec_string ..
|
|
||||||
"button_exit[3.2,0.5;1,0.1;help;" .. S("Help") .. "]" ..
|
|
||||||
"tooltip[help;" .. S("Show documentation about this block") .. "]"
|
|
||||||
else
|
|
||||||
intermittent_formspec_string = "size[3.5,1]" .. intermittent_formspec_string
|
|
||||||
end
|
|
||||||
|
|
||||||
local intermittent_formspec = function(pos, meta)
|
|
||||||
return intermittent_formspec_string
|
|
||||||
:gsub("${period}", meta:get_int("period"), 1)
|
|
||||||
:gsub("${offset}", meta:get_int("offset"), 1)
|
|
||||||
end
|
|
||||||
|
|
||||||
local intermittent_on_construct = function(pos)
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
meta:set_int("period", 1)
|
|
||||||
meta:set_int("offset", 0)
|
|
||||||
end
|
|
||||||
|
|
||||||
local intermittent_on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
|
|
||||||
local item_def = itemstack:get_definition()
|
|
||||||
if item_def.type == "node" and minetest.get_item_group(itemstack:get_name(), "digtron") > 0 then
|
|
||||||
local returnstack, success = minetest.item_place_node(itemstack, clicker, pointed_thing)
|
|
||||||
if success and item_def.sounds and item_def.sounds.place and item_def.sounds.place.name then
|
|
||||||
minetest.sound_play(item_def.sounds.place, {pos = pos})
|
|
||||||
end
|
|
||||||
return returnstack, success
|
|
||||||
end
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
minetest.show_formspec(clicker:get_player_name(),
|
|
||||||
"digtron:intermittent_digger"..minetest.pos_to_string(pos),
|
|
||||||
intermittent_formspec(pos, meta))
|
|
||||||
end
|
|
||||||
|
|
||||||
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|
||||||
if formname:sub(1, 27) == "digtron:intermittent_digger" then
|
|
||||||
local pos = minetest.string_to_pos(formname:sub(28, -1))
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
local period = tonumber(fields.period)
|
|
||||||
local offset = tonumber(fields.offset)
|
|
||||||
if period and period > 0 then
|
|
||||||
meta:set_int("period", math.floor(period))
|
|
||||||
end
|
|
||||||
if offset then
|
|
||||||
meta:set_int("offset", math.floor(offset))
|
|
||||||
end
|
|
||||||
if fields.help and minetest.get_modpath("doc") then --check for mod in case someone disabled it after this digger was built
|
|
||||||
local node_name = minetest.get_node(pos).name
|
|
||||||
minetest.after(0.5, doc.show_entry, player:get_player_name(), "nodes", node_name, true)
|
|
||||||
end
|
|
||||||
if fields.set then
|
|
||||||
digtron.show_offset_markers(pos, offset, period)
|
|
||||||
end
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
|
|
||||||
-- Digs out nodes that are "in front" of the digger head.
|
|
||||||
minetest.register_node("digtron:digger", {
|
|
||||||
description = S("Digtron Digger Head"),
|
|
||||||
_doc_items_longdesc = digtron.doc.digger_longdesc,
|
|
||||||
_doc_items_usagehelp = digtron.doc.digger_usagehelp,
|
|
||||||
groups = {cracky = 3, oddly_breakable_by_hand=3, digtron = 3},
|
|
||||||
drop = "digtron:digger",
|
|
||||||
sounds = digtron.metal_sounds,
|
|
||||||
paramtype = "light",
|
|
||||||
paramtype2= "facedir",
|
|
||||||
is_ground_content = false,
|
|
||||||
drawtype="nodebox",
|
|
||||||
node_box = {
|
|
||||||
type = "fixed",
|
|
||||||
fixed = digger_nodebox,
|
|
||||||
},
|
|
||||||
|
|
||||||
-- Aims in the +Z direction by default
|
|
||||||
tiles = {
|
|
||||||
"digtron_plate.png^[transformR90",
|
|
||||||
"digtron_plate.png^[transformR270",
|
|
||||||
"digtron_plate.png",
|
|
||||||
"digtron_plate.png^[transformR180",
|
|
||||||
{
|
|
||||||
name = "digtron_digger_yb.png",
|
|
||||||
animation = {
|
|
||||||
type = "vertical_frames",
|
|
||||||
aspect_w = 16,
|
|
||||||
aspect_h = 16,
|
|
||||||
length = 1.0,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"digtron_plate.png^digtron_motor.png",
|
|
||||||
},
|
|
||||||
|
|
||||||
-- returns fuel_cost, item_produced
|
|
||||||
execute_dig = function(pos, protected_nodes, nodes_dug, controlling_coordinate, lateral_dig, player)
|
|
||||||
local facing = minetest.get_node(pos).param2
|
|
||||||
local digpos = digtron.find_new_pos(pos, facing)
|
|
||||||
|
|
||||||
if protected_nodes:get(digpos.x, digpos.y, digpos.z) then
|
|
||||||
return 0
|
|
||||||
end
|
|
||||||
|
|
||||||
return digtron.mark_diggable(digpos, nodes_dug, player)
|
|
||||||
end,
|
|
||||||
|
|
||||||
damage_creatures = function(player, pos, controlling_coordinate, items_dropped)
|
|
||||||
local facing = minetest.get_node(pos).param2
|
|
||||||
digtron.damage_creatures(player, pos, digtron.find_new_pos(pos, facing), damage_hp, items_dropped)
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Digs out nodes that are "in front" of the digger head.
|
|
||||||
minetest.register_node("digtron:intermittent_digger", {
|
|
||||||
description = S("Digtron Intermittent Digger Head"),
|
|
||||||
_doc_items_longdesc = digtron.doc.intermittent_digger_longdesc,
|
|
||||||
_doc_items_usagehelp = digtron.doc.intermittent_digger_usagehelp,
|
|
||||||
_digtron_formspec = intermittent_formspec,
|
|
||||||
groups = {cracky = 3, oddly_breakable_by_hand=3, digtron = 3},
|
|
||||||
drop = "digtron:intermittent_digger",
|
|
||||||
sounds = digtron.metal_sounds,
|
|
||||||
paramtype = "light",
|
|
||||||
paramtype2= "facedir",
|
|
||||||
is_ground_content = false,
|
|
||||||
drawtype="nodebox",
|
|
||||||
node_box = {
|
|
||||||
type = "fixed",
|
|
||||||
fixed = digger_nodebox,
|
|
||||||
},
|
|
||||||
|
|
||||||
-- Aims in the +Z direction by default
|
|
||||||
tiles = {
|
|
||||||
"digtron_plate.png^[transformR90",
|
|
||||||
"digtron_plate.png^[transformR270",
|
|
||||||
"digtron_plate.png",
|
|
||||||
"digtron_plate.png^[transformR180",
|
|
||||||
{
|
|
||||||
name = "digtron_digger_yb.png",
|
|
||||||
animation = {
|
|
||||||
type = "vertical_frames",
|
|
||||||
aspect_w = 16,
|
|
||||||
aspect_h = 16,
|
|
||||||
length = 1.0,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"digtron_plate.png^digtron_intermittent.png^digtron_motor.png",
|
|
||||||
},
|
|
||||||
|
|
||||||
on_construct = intermittent_on_construct,
|
|
||||||
|
|
||||||
on_rightclick = intermittent_on_rightclick,
|
|
||||||
|
|
||||||
-- returns fuel_cost, item_produced (a table or nil)
|
|
||||||
execute_dig = function(pos, protected_nodes, nodes_dug, controlling_coordinate, lateral_dig, player)
|
|
||||||
if lateral_dig == true then
|
|
||||||
return 0
|
|
||||||
end
|
|
||||||
|
|
||||||
local facing = minetest.get_node(pos).param2
|
|
||||||
local digpos = digtron.find_new_pos(pos, facing)
|
|
||||||
|
|
||||||
if protected_nodes:get(digpos.x, digpos.y, digpos.z) then
|
|
||||||
return 0
|
|
||||||
end
|
|
||||||
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
if (digpos[controlling_coordinate] + meta:get_int("offset")) % meta:get_int("period") ~= 0 then
|
|
||||||
return 0
|
|
||||||
end
|
|
||||||
|
|
||||||
return digtron.mark_diggable(digpos, nodes_dug, player)
|
|
||||||
end,
|
|
||||||
|
|
||||||
damage_creatures = function(player, pos, controlling_coordinate, items_dropped)
|
|
||||||
local facing = minetest.get_node(pos).param2
|
|
||||||
local targetpos = digtron.find_new_pos(pos, facing)
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
if (targetpos[controlling_coordinate] + meta:get_int("offset")) % meta:get_int("period") == 0 then
|
|
||||||
digtron.damage_creatures(player, pos, targetpos, damage_hp, items_dropped)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
})
|
|
||||||
|
|
||||||
-- A special-purpose digger to deal with stuff like sand and gravel in the ceiling. It always digs (no periodicity or offset), but it only digs falling_block nodes
|
|
||||||
minetest.register_node("digtron:soft_digger", {
|
|
||||||
description = S("Digtron Soft Material Digger Head"),
|
|
||||||
_doc_items_longdesc = digtron.doc.soft_digger_longdesc,
|
|
||||||
_doc_items_usagehelp = digtron.doc.soft_digger_usagehelp,
|
|
||||||
groups = {cracky = 3, oddly_breakable_by_hand=3, digtron = 3},
|
|
||||||
drop = "digtron:soft_digger",
|
|
||||||
sounds = digtron.metal_sounds,
|
|
||||||
paramtype = "light",
|
|
||||||
paramtype2= "facedir",
|
|
||||||
is_ground_content = false,
|
|
||||||
drawtype="nodebox",
|
|
||||||
node_box = {
|
|
||||||
type = "fixed",
|
|
||||||
fixed = digger_nodebox,
|
|
||||||
},
|
|
||||||
|
|
||||||
-- Aims in the +Z direction by default
|
|
||||||
tiles = {
|
|
||||||
"digtron_plate.png^[transformR90^[colorize:" .. digtron.soft_digger_colorize,
|
|
||||||
"digtron_plate.png^[transformR270^[colorize:" .. digtron.soft_digger_colorize,
|
|
||||||
"digtron_plate.png^[colorize:" .. digtron.soft_digger_colorize,
|
|
||||||
"digtron_plate.png^[transformR180^[colorize:" .. digtron.soft_digger_colorize,
|
|
||||||
{
|
|
||||||
name = "digtron_digger_yb.png^[colorize:" .. digtron.soft_digger_colorize,
|
|
||||||
animation = {
|
|
||||||
type = "vertical_frames",
|
|
||||||
aspect_w = 16,
|
|
||||||
aspect_h = 16,
|
|
||||||
length = 1.0,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"digtron_plate.png^digtron_motor.png^[colorize:" .. digtron.soft_digger_colorize,
|
|
||||||
},
|
|
||||||
|
|
||||||
execute_dig = function(pos, protected_nodes, nodes_dug, controlling_coordinate, lateral_dig, player)
|
|
||||||
local facing = minetest.get_node(pos).param2
|
|
||||||
local digpos = digtron.find_new_pos(pos, facing)
|
|
||||||
|
|
||||||
if protected_nodes:get(digpos.x, digpos.y, digpos.z) then
|
|
||||||
return 0
|
|
||||||
end
|
|
||||||
|
|
||||||
if digtron.is_soft_material(digpos) then
|
|
||||||
return digtron.mark_diggable(digpos, nodes_dug, player)
|
|
||||||
end
|
|
||||||
|
|
||||||
return 0
|
|
||||||
end,
|
|
||||||
|
|
||||||
damage_creatures = function(player, pos, controlling_coordinate, items_dropped)
|
|
||||||
local facing = minetest.get_node(pos).param2
|
|
||||||
digtron.damage_creatures(player, pos, digtron.find_new_pos(pos, facing), damage_hp_half, items_dropped)
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_node("digtron:intermittent_soft_digger", {
|
|
||||||
description = S("Digtron Intermittent Soft Material Digger Head"),
|
|
||||||
_doc_items_longdesc = digtron.doc.intermittent_soft_digger_longdesc,
|
|
||||||
_doc_items_usagehelp = digtron.doc.intermittent_soft_digger_usagehelp,
|
|
||||||
_digtron_formspec = intermittent_formspec,
|
|
||||||
groups = {cracky = 3, oddly_breakable_by_hand=3, digtron = 3},
|
|
||||||
drop = "digtron:intermittent_soft_digger",
|
|
||||||
sounds = digtron.metal_sounds,
|
|
||||||
paramtype = "light",
|
|
||||||
paramtype2= "facedir",
|
|
||||||
is_ground_content = false,
|
|
||||||
drawtype="nodebox",
|
|
||||||
node_box = {
|
|
||||||
type = "fixed",
|
|
||||||
fixed = digger_nodebox,
|
|
||||||
},
|
|
||||||
|
|
||||||
-- Aims in the +Z direction by default
|
|
||||||
tiles = {
|
|
||||||
"digtron_plate.png^[transformR90^[colorize:" .. digtron.soft_digger_colorize,
|
|
||||||
"digtron_plate.png^[transformR270^[colorize:" .. digtron.soft_digger_colorize,
|
|
||||||
"digtron_plate.png^[colorize:" .. digtron.soft_digger_colorize,
|
|
||||||
"digtron_plate.png^[transformR180^[colorize:" .. digtron.soft_digger_colorize,
|
|
||||||
{
|
|
||||||
name = "digtron_digger_yb.png^[colorize:" .. digtron.soft_digger_colorize,
|
|
||||||
animation = {
|
|
||||||
type = "vertical_frames",
|
|
||||||
aspect_w = 16,
|
|
||||||
aspect_h = 16,
|
|
||||||
length = 1.0,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"digtron_plate.png^digtron_intermittent.png^digtron_motor.png^[colorize:" .. digtron.soft_digger_colorize,
|
|
||||||
},
|
|
||||||
|
|
||||||
on_construct = intermittent_on_construct,
|
|
||||||
|
|
||||||
on_rightclick = intermittent_on_rightclick,
|
|
||||||
|
|
||||||
execute_dig = function(pos, protected_nodes, nodes_dug, controlling_coordinate, lateral_dig, player)
|
|
||||||
if lateral_dig == true then
|
|
||||||
return 0
|
|
||||||
end
|
|
||||||
|
|
||||||
local facing = minetest.get_node(pos).param2
|
|
||||||
local digpos = digtron.find_new_pos(pos, facing)
|
|
||||||
|
|
||||||
if protected_nodes:get(digpos.x, digpos.y, digpos.z) then
|
|
||||||
return 0
|
|
||||||
end
|
|
||||||
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
if (digpos[controlling_coordinate] + meta:get_int("offset")) % meta:get_int("period") ~= 0 then
|
|
||||||
return 0
|
|
||||||
end
|
|
||||||
|
|
||||||
if digtron.is_soft_material(digpos) then
|
|
||||||
return digtron.mark_diggable(digpos, nodes_dug, player)
|
|
||||||
end
|
|
||||||
|
|
||||||
return 0
|
|
||||||
end,
|
|
||||||
|
|
||||||
damage_creatures = function(player, pos, controlling_coordinate, items_dropped)
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
local facing = minetest.get_node(pos).param2
|
|
||||||
local targetpos = digtron.find_new_pos(pos, facing)
|
|
||||||
if (targetpos[controlling_coordinate] + meta:get_int("offset")) % meta:get_int("period") == 0 then
|
|
||||||
digtron.damage_creatures(player, pos, targetpos, damage_hp_half, items_dropped)
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Digs out nodes that are "in front" of the digger head and "below" the digger head (can be rotated).
|
|
||||||
minetest.register_node("digtron:dual_digger", {
|
|
||||||
description = S("Digtron Dual Digger Head"),
|
|
||||||
_doc_items_longdesc = digtron.doc.dual_digger_longdesc,
|
|
||||||
_doc_items_usagehelp = digtron.doc.dual_digger_usagehelp,
|
|
||||||
groups = {cracky = 3, oddly_breakable_by_hand=3, digtron = 3},
|
|
||||||
drop = "digtron:dual_digger",
|
|
||||||
sounds = digtron.metal_sounds,
|
|
||||||
paramtype = "light",
|
|
||||||
paramtype2= "facedir",
|
|
||||||
is_ground_content = false,
|
|
||||||
drawtype="nodebox",
|
|
||||||
node_box = {
|
|
||||||
type = "fixed",
|
|
||||||
fixed = dual_digger_nodebox,
|
|
||||||
},
|
|
||||||
|
|
||||||
-- Aims in the +Z and -Y direction by default
|
|
||||||
tiles = {
|
|
||||||
"digtron_plate.png^digtron_motor.png",
|
|
||||||
{
|
|
||||||
name = "digtron_digger_yb.png",
|
|
||||||
animation = {
|
|
||||||
type = "vertical_frames",
|
|
||||||
aspect_w = 16,
|
|
||||||
aspect_h = 16,
|
|
||||||
length = 1.0,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"digtron_plate.png",
|
|
||||||
"digtron_plate.png^[transformR180",
|
|
||||||
{
|
|
||||||
name = "digtron_digger_yb.png",
|
|
||||||
animation = {
|
|
||||||
type = "vertical_frames",
|
|
||||||
aspect_w = 16,
|
|
||||||
aspect_h = 16,
|
|
||||||
length = 1.0,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"digtron_plate.png^digtron_motor.png",
|
|
||||||
},
|
|
||||||
|
|
||||||
-- returns fuel_cost, items_produced
|
|
||||||
execute_dig = function(pos, protected_nodes, nodes_dug, controlling_coordinate, lateral_dig, player)
|
|
||||||
local facing = minetest.get_node(pos).param2
|
|
||||||
local digpos = digtron.find_new_pos(pos, facing)
|
|
||||||
local digdown = digtron.find_new_pos_downward(pos, facing)
|
|
||||||
|
|
||||||
local items = {}
|
|
||||||
local cost = 0
|
|
||||||
|
|
||||||
if protected_nodes:get(digpos.x, digpos.y, digpos.z) ~= true then
|
|
||||||
local forward_cost, forward_items = digtron.mark_diggable(digpos, nodes_dug, player)
|
|
||||||
if forward_items ~= nil then
|
|
||||||
for _, item in pairs(forward_items) do
|
|
||||||
table.insert(items, item)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
cost = cost + forward_cost
|
|
||||||
end
|
|
||||||
if protected_nodes:get(digdown.x, digdown.y, digdown.z) ~= true then
|
|
||||||
local down_cost, down_items = digtron.mark_diggable(digdown, nodes_dug, player)
|
|
||||||
if down_items ~= nil then
|
|
||||||
for _, item in pairs(down_items) do
|
|
||||||
table.insert(items, item)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
cost = cost + down_cost
|
|
||||||
end
|
|
||||||
|
|
||||||
return cost, items
|
|
||||||
end,
|
|
||||||
|
|
||||||
damage_creatures = function(player, pos, controlling_coordinate, items_dropped)
|
|
||||||
local facing = minetest.get_node(pos).param2
|
|
||||||
digtron.damage_creatures(player, pos, digtron.find_new_pos(pos, facing), damage_hp, items_dropped)
|
|
||||||
digtron.damage_creatures(player, pos, digtron.find_new_pos_downward(pos, facing), damage_hp, items_dropped)
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Digs out soft nodes that are "in front" of the digger head and "below" the digger head (can be rotated).
|
|
||||||
minetest.register_node("digtron:dual_soft_digger", {
|
|
||||||
description = S("Digtron Dual Soft Material Digger Head"),
|
|
||||||
_doc_items_longdesc = digtron.doc.dual_soft_digger_longdesc,
|
|
||||||
_doc_items_usagehelp = digtron.doc.dual_soft_digger_usagehelp,
|
|
||||||
groups = {cracky = 3, oddly_breakable_by_hand=3, digtron = 3},
|
|
||||||
drop = "digtron:dual_soft_digger",
|
|
||||||
sounds = digtron.metal_sounds,
|
|
||||||
paramtype = "light",
|
|
||||||
paramtype2= "facedir",
|
|
||||||
is_ground_content = false,
|
|
||||||
drawtype="nodebox",
|
|
||||||
node_box = {
|
|
||||||
type = "fixed",
|
|
||||||
fixed = dual_digger_nodebox,
|
|
||||||
},
|
|
||||||
|
|
||||||
-- Aims in the +Z and -Y direction by default
|
|
||||||
tiles = {
|
|
||||||
"digtron_plate.png^digtron_motor.png^[colorize:" .. digtron.soft_digger_colorize,
|
|
||||||
{
|
|
||||||
name = "digtron_digger_yb.png^[colorize:" .. digtron.soft_digger_colorize,
|
|
||||||
animation = {
|
|
||||||
type = "vertical_frames",
|
|
||||||
aspect_w = 16,
|
|
||||||
aspect_h = 16,
|
|
||||||
length = 1.0,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"digtron_plate.png^[colorize:" .. digtron.soft_digger_colorize,
|
|
||||||
"digtron_plate.png^[transformR180^[colorize:" .. digtron.soft_digger_colorize,
|
|
||||||
{
|
|
||||||
name = "digtron_digger_yb.png^[colorize:" .. digtron.soft_digger_colorize,
|
|
||||||
animation = {
|
|
||||||
type = "vertical_frames",
|
|
||||||
aspect_w = 16,
|
|
||||||
aspect_h = 16,
|
|
||||||
length = 1.0,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"digtron_plate.png^digtron_motor.png^[colorize:" .. digtron.soft_digger_colorize,
|
|
||||||
},
|
|
||||||
|
|
||||||
-- returns fuel_cost, items_produced
|
|
||||||
execute_dig = function(pos, protected_nodes, nodes_dug, controlling_coordinate, lateral_dig, player)
|
|
||||||
local facing = minetest.get_node(pos).param2
|
|
||||||
local digpos = digtron.find_new_pos(pos, facing)
|
|
||||||
local digdown = digtron.find_new_pos_downward(pos, facing)
|
|
||||||
|
|
||||||
local items = {}
|
|
||||||
local cost = 0
|
|
||||||
|
|
||||||
if protected_nodes:get(digpos.x, digpos.y, digpos.z) ~= true and digtron.is_soft_material(digpos) then
|
|
||||||
local forward_cost, forward_items = digtron.mark_diggable(digpos, nodes_dug, player)
|
|
||||||
if forward_items ~= nil then
|
|
||||||
for _, item in pairs(forward_items) do
|
|
||||||
table.insert(items, item)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
cost = cost + forward_cost
|
|
||||||
end
|
|
||||||
if protected_nodes:get(digdown.x, digdown.y, digdown.z) ~= true and digtron.is_soft_material(digdown) then
|
|
||||||
local down_cost, down_items = digtron.mark_diggable(digdown, nodes_dug, player)
|
|
||||||
if down_items ~= nil then
|
|
||||||
for _, item in pairs(down_items) do
|
|
||||||
table.insert(items, item)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
cost = cost + down_cost
|
|
||||||
end
|
|
||||||
|
|
||||||
return cost, items
|
|
||||||
end,
|
|
||||||
|
|
||||||
damage_creatures = function(player, pos, controlling_coordinate, items_dropped)
|
|
||||||
local facing = minetest.get_node(pos).param2
|
|
||||||
digtron.damage_creatures(player, pos, digtron.find_new_pos(pos, facing), damage_hp_half, items_dropped)
|
|
||||||
digtron.damage_creatures(player, pos, digtron.find_new_pos_downward(pos, facing), damage_hp_half, items_dropped)
|
|
||||||
end,
|
|
||||||
})
|
|
@ -1,189 +0,0 @@
|
|||||||
-- internationalization boilerplate
|
|
||||||
local MP = minetest.get_modpath(minetest.get_current_modname())
|
|
||||||
local S, NS = dofile(MP.."/intllib.lua")
|
|
||||||
|
|
||||||
local inventory_formspec_string =
|
|
||||||
"size[9,9.3]" ..
|
|
||||||
default.gui_bg ..
|
|
||||||
default.gui_bg_img ..
|
|
||||||
default.gui_slots ..
|
|
||||||
"label[0,0;" .. S("Digtron components") .. "]" ..
|
|
||||||
"list[current_name;main;0,0.6;8,4;]" ..
|
|
||||||
"list[current_player;main;0,5.15;8,1;]" ..
|
|
||||||
"list[current_player;main;0,6.38;8,3;8]" ..
|
|
||||||
"listring[current_name;main]" ..
|
|
||||||
"listring[current_player;main]" ..
|
|
||||||
default.get_hotbar_bg(0,5.15)..
|
|
||||||
"button_exit[8,3.5;1,1;duplicate;"..S("Duplicate").."]" ..
|
|
||||||
"tooltip[duplicate;" .. S("Puts a copy of the adjacent Digtron into an empty crate\nlocated at the output side of the duplicator,\nusing components from the duplicator's inventory.") .. "]"
|
|
||||||
|
|
||||||
if minetest.get_modpath("doc") then
|
|
||||||
inventory_formspec_string = inventory_formspec_string ..
|
|
||||||
"button_exit[8,4.5;1,1;help;"..S("Help").."]" ..
|
|
||||||
"tooltip[help;" .. S("Show documentation about this block") .. "]"
|
|
||||||
end
|
|
||||||
|
|
||||||
minetest.register_node("digtron:duplicator", {
|
|
||||||
description = S("Digtron Duplicator"),
|
|
||||||
_doc_items_longdesc = digtron.doc.duplicator_longdesc,
|
|
||||||
_doc_items_usagehelp = digtron.doc.duplicator_usagehelp,
|
|
||||||
groups = {cracky = 3, oddly_breakable_by_hand=3},
|
|
||||||
sounds = digtron.metal_sounds,
|
|
||||||
tiles = {"digtron_plate.png^(digtron_axel_side.png^[transformR90)",
|
|
||||||
"digtron_plate.png^(digtron_axel_side.png^[transformR270)",
|
|
||||||
"digtron_plate.png^digtron_axel_side.png",
|
|
||||||
"digtron_plate.png^(digtron_axel_side.png^[transformR180)",
|
|
||||||
"digtron_plate.png^digtron_builder.png",
|
|
||||||
"digtron_plate.png",
|
|
||||||
},
|
|
||||||
paramtype = "light",
|
|
||||||
paramtype2= "facedir",
|
|
||||||
is_ground_content = false,
|
|
||||||
drawtype="nodebox",
|
|
||||||
node_box = {
|
|
||||||
type = "fixed",
|
|
||||||
fixed = {
|
|
||||||
{-0.5, 0.3125, 0.3125, 0.5, 0.5, 0.5}, -- FrontFrame_top
|
|
||||||
{-0.5, -0.5, 0.3125, 0.5, -0.3125, 0.5}, -- FrontFrame_bottom
|
|
||||||
{0.3125, -0.3125, 0.3125, 0.5, 0.3125, 0.5}, -- FrontFrame_right
|
|
||||||
{-0.5, -0.3125, 0.3125, -0.3125, 0.3125, 0.5}, -- FrontFrame_left
|
|
||||||
{-0.0625, -0.3125, 0.3125, 0.0625, 0.3125, 0.375}, -- frontcross_vertical
|
|
||||||
{-0.3125, -0.0625, 0.3125, 0.3125, 0.0625, 0.375}, -- frontcross_horizontal
|
|
||||||
{-0.4375, -0.4375, -0.4375, 0.4375, 0.4375, 0.3125}, -- Body
|
|
||||||
{-0.5, -0.3125, -0.5, -0.3125, 0.3125, -0.3125}, -- backframe_vertical
|
|
||||||
{0.3125, -0.3125, -0.5, 0.5, 0.3125, -0.3125}, -- backframe_left
|
|
||||||
{-0.5, 0.3125, -0.5, 0.5, 0.5, -0.3125}, -- backframe_top
|
|
||||||
{-0.5, -0.5, -0.5, 0.5, -0.3125, -0.3125}, -- backframe_bottom
|
|
||||||
{-0.0625, -0.0625, -0.5625, 0.0625, 0.0625, -0.4375}, -- back_probe
|
|
||||||
},
|
|
||||||
},
|
|
||||||
selection_box = {
|
|
||||||
type = "regular"
|
|
||||||
},
|
|
||||||
|
|
||||||
on_construct = function(pos)
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
meta:set_string("formspec", inventory_formspec_string)
|
|
||||||
local inv = meta:get_inventory()
|
|
||||||
inv:set_size("main", 8*4)
|
|
||||||
end,
|
|
||||||
|
|
||||||
can_dig = function(pos,player)
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
local inv = meta:get_inventory()
|
|
||||||
return inv:is_empty("main")
|
|
||||||
end,
|
|
||||||
|
|
||||||
allow_metadata_inventory_put = function(pos, listname, index, stack, player)
|
|
||||||
if minetest.get_item_group(stack:get_name(), "digtron") > 0 then
|
|
||||||
return stack:get_count()
|
|
||||||
else
|
|
||||||
return 0
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
|
|
||||||
on_receive_fields = function(pos, formname, fields, sender)
|
|
||||||
if fields.help then
|
|
||||||
minetest.after(0.5, doc.show_entry, sender:get_player_name(), "nodes", "digtron:duplicator", true)
|
|
||||||
end
|
|
||||||
|
|
||||||
if fields.duplicate then
|
|
||||||
local node = minetest.get_node(pos)
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
local inv = meta:get_inventory()
|
|
||||||
local target_pos = vector.add(pos, minetest.facedir_to_dir(node.param2))
|
|
||||||
local target_node = minetest.get_node(target_pos)
|
|
||||||
|
|
||||||
if target_node.name ~= "digtron:empty_crate" then
|
|
||||||
minetest.sound_play("buzzer", {gain=0.5, pos=pos})
|
|
||||||
meta:set_string("infotext", S("Needs an empty crate in output position to store duplicate"))
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local layout = DigtronLayout.create(pos, sender)
|
|
||||||
|
|
||||||
if layout.contains_protected_node then
|
|
||||||
minetest.sound_play("buzzer", {gain=0.5, pos=pos})
|
|
||||||
meta:set_string("infotext", S("Digtron can't be duplicated, it contains protected blocks"))
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
if #layout.all == 1 then
|
|
||||||
minetest.sound_play("buzzer", {gain=0.5, pos=pos})
|
|
||||||
meta:set_string("infotext", S("No Digtron components adjacent to duplicate"))
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
layout.all[1] = {node={name="digtron:empty_crate"}, meta={fields = {}, inventory = {}}, pos={x=pos.x, y=pos.y, z=pos.z}} -- replace the duplicator's image with the empty crate image
|
|
||||||
|
|
||||||
-- count required nodes, skipping node 1 since it's the crate and we already know it's present in-world
|
|
||||||
local required_count = {}
|
|
||||||
for i = 2, #layout.all do
|
|
||||||
local nodename = layout.all[i].node.name
|
|
||||||
required_count[nodename] = (required_count[nodename] or 0) + 1
|
|
||||||
end
|
|
||||||
|
|
||||||
-- check that there's enough in the duplicator's inventory
|
|
||||||
local unsatisfied = {}
|
|
||||||
for name, count in pairs(required_count) do
|
|
||||||
if not inv:contains_item("main", ItemStack({name=name, count=count})) then
|
|
||||||
table.insert(unsatisfied, tostring(count) .. " " .. minetest.registered_nodes[name].description)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if #unsatisfied > 0 then
|
|
||||||
minetest.sound_play("dingding", {gain=1.0, pos=pos}) -- Insufficient inventory
|
|
||||||
meta:set_string("infotext", S("Duplicator requires:\n@1", table.concat(unsatisfied, "\n")))
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
meta:set_string("infotext", "") -- clear infotext, we're good to go.
|
|
||||||
|
|
||||||
-- deduct nodes from duplicator inventory
|
|
||||||
for name, count in pairs(required_count) do
|
|
||||||
inv:remove_item("main", ItemStack({name=name, count=count}))
|
|
||||||
end
|
|
||||||
|
|
||||||
-- clear inventories of image's nodes
|
|
||||||
if layout.inventories ~= nil then
|
|
||||||
for _, node_image in pairs(layout.inventories) do
|
|
||||||
local main_inventory = node_image.meta.inventory.main
|
|
||||||
if type(main_inventory) ~= "table" then
|
|
||||||
main_inventory = {}
|
|
||||||
end
|
|
||||||
for index, _ in pairs(main_inventory) do
|
|
||||||
main_inventory[index] = ItemStack(nil)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if layout.fuelstores ~= nil then
|
|
||||||
for _, node_image in pairs(layout.fuelstores) do
|
|
||||||
local fuel_inventory = node_image.meta.inventory.fuel
|
|
||||||
for index, _ in pairs(fuel_inventory) do
|
|
||||||
fuel_inventory[index] = ItemStack(nil)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if layout.battery_holders ~= nil then
|
|
||||||
for _, node_image in pairs(layout.battery_holders) do
|
|
||||||
local battery_inventory = node_image.meta.inventory.batteries
|
|
||||||
for index, _ in pairs(battery_inventory) do
|
|
||||||
battery_inventory[index] = ItemStack(nil)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- replace empty crate with loaded crate and write image to its metadata
|
|
||||||
local layout_string = layout:serialize()
|
|
||||||
|
|
||||||
minetest.set_node(target_pos, {name="digtron:loaded_crate", param1=node.param1, param2=node.param2})
|
|
||||||
local target_meta = minetest.get_meta(target_pos)
|
|
||||||
target_meta:set_string("crated_layout", layout_string)
|
|
||||||
|
|
||||||
local titlestring = S("Crated @1-block Digtron", tostring(#layout.all-1))
|
|
||||||
target_meta:set_string("title", titlestring)
|
|
||||||
target_meta:set_string("infotext", titlestring)
|
|
||||||
minetest.sound_play("machine1", {gain=1.0, pos=pos})
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
|
|
||||||
})
|
|
@ -1,174 +0,0 @@
|
|||||||
-- internationalization boilerplate
|
|
||||||
local MP = minetest.get_modpath(minetest.get_current_modname())
|
|
||||||
local S, NS = dofile(MP.."/intllib.lua")
|
|
||||||
|
|
||||||
--Build up the formspec, somewhat complicated due to multiple mod options
|
|
||||||
local pipeworks_path = minetest.get_modpath("pipeworks")
|
|
||||||
local doc_path = minetest.get_modpath("doc")
|
|
||||||
local formspec_width = 1.5
|
|
||||||
|
|
||||||
local ejector_formspec_string =
|
|
||||||
default.gui_bg ..
|
|
||||||
default.gui_bg_img ..
|
|
||||||
default.gui_slots
|
|
||||||
|
|
||||||
if doc_path then
|
|
||||||
ejector_formspec_string = ejector_formspec_string ..
|
|
||||||
"button_exit[".. 0.2 + formspec_width ..",0.5;1,0.1;help;" .. S("Help") .. "]" ..
|
|
||||||
"tooltip[help;" .. S("Show documentation about this block") .. "]"
|
|
||||||
formspec_width = formspec_width + 1.5
|
|
||||||
end
|
|
||||||
|
|
||||||
local ejector_formspec_string = "size[".. formspec_width .. ",1]" .. ejector_formspec_string
|
|
||||||
|
|
||||||
local ejector_formspec = function(pos, meta)
|
|
||||||
local return_string = ejector_formspec_string
|
|
||||||
if pipeworks_path then
|
|
||||||
return_string = return_string .. "checkbox[0,0.5;nonpipe;"..S("Eject into world")..";"..meta:get_string("nonpipe").."]" ..
|
|
||||||
"tooltip[nonpipe;" .. S("When checked, will eject items even if there's no pipe to accept it") .. "]"
|
|
||||||
end
|
|
||||||
return return_string .. "checkbox[0,0;autoeject;"..S("Automatic")..";"..meta:get_string("autoeject").."]" ..
|
|
||||||
"tooltip[autoeject;" .. S("When checked, will eject items automatically with every Digtron cycle.\nItem ejectors can always be operated manually by punching them.") .. "]"
|
|
||||||
end
|
|
||||||
|
|
||||||
local function eject_items(pos, node, player, eject_even_without_pipeworks, layout)
|
|
||||||
local dir = minetest.facedir_to_dir(node.param2)
|
|
||||||
local destination_pos = vector.add(pos, dir)
|
|
||||||
local destination_node_name = minetest.get_node(destination_pos).name
|
|
||||||
local destination_node_def = minetest.registered_nodes[destination_node_name]
|
|
||||||
|
|
||||||
if not pipeworks_path then eject_even_without_pipeworks = true end -- if pipeworks is not installed, always eject into world (there's no other option)
|
|
||||||
|
|
||||||
local insert_into_pipe = false
|
|
||||||
local eject_into_world = false
|
|
||||||
if pipeworks_path and minetest.get_node_group(destination_node_name, "tubedevice") > 0 then
|
|
||||||
insert_into_pipe = true
|
|
||||||
elseif eject_even_without_pipeworks then
|
|
||||||
if destination_node_def and not destination_node_def.walkable then
|
|
||||||
eject_into_world = true
|
|
||||||
else
|
|
||||||
minetest.sound_play("buzzer", {gain=0.5, pos=pos})
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
else
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
if layout == nil then
|
|
||||||
layout = DigtronLayout.create(pos, player)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Build a list of all the items that builder nodes want to use.
|
|
||||||
local filter_items = {}
|
|
||||||
if layout.builders ~= nil then
|
|
||||||
for _, node_image in pairs(layout.builders) do
|
|
||||||
filter_items[node_image.meta.inventory.main[1]:get_name()] = true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Look through the inventories and find an item that's not on that list.
|
|
||||||
local source_node = nil
|
|
||||||
local source_index = nil
|
|
||||||
local source_stack = nil
|
|
||||||
for _, node_image in pairs(layout.inventories or {}) do
|
|
||||||
if type(node_image.meta.inventory.main) ~= "table" then
|
|
||||||
node_image.meta.inventory.main = {}
|
|
||||||
end
|
|
||||||
for index, item_stack in pairs(node_image.meta.inventory.main) do
|
|
||||||
if item_stack:get_count() > 0 and not filter_items[item_stack:get_name()] then
|
|
||||||
source_node = node_image
|
|
||||||
source_index = index
|
|
||||||
source_stack = item_stack
|
|
||||||
node_image.meta.inventory.main[index] = nil
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if source_node then break end
|
|
||||||
end
|
|
||||||
|
|
||||||
if source_node then
|
|
||||||
local meta = minetest.get_meta(source_node.pos)
|
|
||||||
local inv = meta:get_inventory()
|
|
||||||
|
|
||||||
if insert_into_pipe then
|
|
||||||
local from_pos = vector.add(pos, vector.multiply(dir, 0.5))
|
|
||||||
local start_pos = pos
|
|
||||||
inv:set_stack("main", source_index, nil)
|
|
||||||
pipeworks.tube_inject_item(from_pos, start_pos, vector.multiply(dir, 1), source_stack, player:get_player_name())
|
|
||||||
minetest.sound_play("steam_puff", {gain=0.5, pos=pos})
|
|
||||||
return true
|
|
||||||
elseif eject_into_world then
|
|
||||||
minetest.add_item(destination_pos, source_stack)
|
|
||||||
inv:set_stack("main", source_index, nil)
|
|
||||||
minetest.sound_play("steam_puff", {gain=0.5, pos=pos})
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- couldn't find an item to eject
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
minetest.register_node("digtron:inventory_ejector", {
|
|
||||||
description = S("Digtron Inventory Ejector"),
|
|
||||||
_doc_items_longdesc = digtron.doc.inventory_ejector_longdesc,
|
|
||||||
_doc_items_usagehelp = digtron.doc.inventory_ejector_usagehelp,
|
|
||||||
_digtron_formspec = ejector_formspec,
|
|
||||||
groups = {cracky = 3, oddly_breakable_by_hand=3, digtron = 9, tubedevice = 1},
|
|
||||||
tiles = {"digtron_plate.png", "digtron_plate.png", "digtron_plate.png", "digtron_plate.png", "digtron_plate.png^digtron_output.png", "digtron_plate.png^digtron_output_back.png"},
|
|
||||||
drawtype = "nodebox",
|
|
||||||
sounds = digtron.metal_sounds,
|
|
||||||
paramtype = "light",
|
|
||||||
paramtype2 = "facedir",
|
|
||||||
is_ground_content = false,
|
|
||||||
node_box = {
|
|
||||||
type = "fixed",
|
|
||||||
fixed = {
|
|
||||||
{-0.5, -0.5, -0.5, 0.5, 0.5, 0.1875}, -- NodeBox1
|
|
||||||
{-0.3125, -0.3125, 0.1875, 0.3125, 0.3125, 0.3125}, -- NodeBox2
|
|
||||||
{-0.1875, -0.1875, 0.3125, 0.1875, 0.1875, 0.5}, -- NodeBox3
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
on_construct = function(pos)
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
meta:set_string("autoeject", "true")
|
|
||||||
meta:set_string("formspec", ejector_formspec(pos, meta))
|
|
||||||
end,
|
|
||||||
|
|
||||||
tube = (function() if pipeworks_path then return {
|
|
||||||
connect_sides = {back = 1}
|
|
||||||
} end end)(),
|
|
||||||
|
|
||||||
on_punch = function(pos, node, player)
|
|
||||||
eject_items(pos, node, player, true)
|
|
||||||
end,
|
|
||||||
|
|
||||||
execute_eject = function(pos, node, player, layout)
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
eject_items(pos, node, player, meta:get_string("nonpipe") == "true", layout)
|
|
||||||
end,
|
|
||||||
|
|
||||||
on_receive_fields = function(pos, formname, fields, sender)
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
|
|
||||||
if fields.help and minetest.get_modpath("doc") then --check for mod in case someone disabled it after this digger was built
|
|
||||||
local node_name = minetest.get_node(pos).name
|
|
||||||
minetest.after(0.5, doc.show_entry, sender:get_player_name(), "nodes", node_name, true)
|
|
||||||
end
|
|
||||||
|
|
||||||
if fields.nonpipe then
|
|
||||||
meta:set_string("nonpipe", fields.nonpipe)
|
|
||||||
end
|
|
||||||
|
|
||||||
if fields.autoeject then
|
|
||||||
meta:set_string("autoeject", fields.autoeject)
|
|
||||||
end
|
|
||||||
|
|
||||||
meta:set_string("formspec", ejector_formspec(pos, meta))
|
|
||||||
|
|
||||||
end,
|
|
||||||
|
|
||||||
after_place_node = (function() if pipeworks_path then return pipeworks.after_place end end)(),
|
|
||||||
after_dig_node = (function() if pipeworks_path then return pipeworks.after_dig end end)()
|
|
||||||
})
|
|
@ -8,7 +8,6 @@ minetest.register_node("digtron:structure", {
|
|||||||
_doc_items_longdesc = digtron.doc.structure_longdesc,
|
_doc_items_longdesc = digtron.doc.structure_longdesc,
|
||||||
_doc_items_usagehelp = digtron.doc.structure_usagehelp,
|
_doc_items_usagehelp = digtron.doc.structure_usagehelp,
|
||||||
groups = {cracky = 3, oddly_breakable_by_hand=3, digtron = 1},
|
groups = {cracky = 3, oddly_breakable_by_hand=3, digtron = 1},
|
||||||
drop = "digtron:structure",
|
|
||||||
tiles = {"digtron_plate.png"},
|
tiles = {"digtron_plate.png"},
|
||||||
drawtype = "nodebox",
|
drawtype = "nodebox",
|
||||||
sounds = digtron.metal_sounds,
|
sounds = digtron.metal_sounds,
|
||||||
@ -41,7 +40,6 @@ minetest.register_node("digtron:light", {
|
|||||||
_doc_items_longdesc = digtron.doc.light_longdesc,
|
_doc_items_longdesc = digtron.doc.light_longdesc,
|
||||||
_doc_items_usagehelp = digtron.doc.light_usagehelp,
|
_doc_items_usagehelp = digtron.doc.light_usagehelp,
|
||||||
groups = {cracky = 3, oddly_breakable_by_hand=3, digtron = 1},
|
groups = {cracky = 3, oddly_breakable_by_hand=3, digtron = 1},
|
||||||
drop = "digtron:light",
|
|
||||||
tiles = {"digtron_plate.png^digtron_light.png"},
|
tiles = {"digtron_plate.png^digtron_light.png"},
|
||||||
drawtype = "nodebox",
|
drawtype = "nodebox",
|
||||||
paramtype = "light",
|
paramtype = "light",
|
||||||
@ -63,7 +61,6 @@ minetest.register_node("digtron:panel", {
|
|||||||
_doc_items_longdesc = digtron.doc.panel_longdesc,
|
_doc_items_longdesc = digtron.doc.panel_longdesc,
|
||||||
_doc_items_usagehelp = digtron.doc.panel_usagehelp,
|
_doc_items_usagehelp = digtron.doc.panel_usagehelp,
|
||||||
groups = {cracky = 3, oddly_breakable_by_hand=3, digtron = 1},
|
groups = {cracky = 3, oddly_breakable_by_hand=3, digtron = 1},
|
||||||
drop = "digtron:panel",
|
|
||||||
tiles = {"digtron_plate.png"},
|
tiles = {"digtron_plate.png"},
|
||||||
drawtype = "nodebox",
|
drawtype = "nodebox",
|
||||||
paramtype = "light",
|
paramtype = "light",
|
||||||
@ -86,7 +83,6 @@ minetest.register_node("digtron:edge_panel", {
|
|||||||
_doc_items_longdesc = digtron.doc.edge_panel_longdesc,
|
_doc_items_longdesc = digtron.doc.edge_panel_longdesc,
|
||||||
_doc_items_usagehelp = digtron.doc.edge_panel_usagehelp,
|
_doc_items_usagehelp = digtron.doc.edge_panel_usagehelp,
|
||||||
groups = {cracky = 3, oddly_breakable_by_hand=3, digtron = 1},
|
groups = {cracky = 3, oddly_breakable_by_hand=3, digtron = 1},
|
||||||
drop = "digtron:edge_panel",
|
|
||||||
tiles = {"digtron_plate.png"},
|
tiles = {"digtron_plate.png"},
|
||||||
drawtype = "nodebox",
|
drawtype = "nodebox",
|
||||||
paramtype = "light",
|
paramtype = "light",
|
||||||
@ -115,7 +111,6 @@ minetest.register_node("digtron:corner_panel", {
|
|||||||
_doc_items_longdesc = digtron.doc.corner_panel_longdesc,
|
_doc_items_longdesc = digtron.doc.corner_panel_longdesc,
|
||||||
_doc_items_usagehelp = digtron.doc.corner_panel_usagehelp,
|
_doc_items_usagehelp = digtron.doc.corner_panel_usagehelp,
|
||||||
groups = {cracky = 3, oddly_breakable_by_hand=3, digtron = 1},
|
groups = {cracky = 3, oddly_breakable_by_hand=3, digtron = 1},
|
||||||
drop = "digtron:corner_panel",
|
|
||||||
tiles = {"digtron_plate.png"},
|
tiles = {"digtron_plate.png"},
|
||||||
drawtype = "nodebox",
|
drawtype = "nodebox",
|
||||||
paramtype = "light",
|
paramtype = "light",
|
||||||
|
@ -1,100 +0,0 @@
|
|||||||
-- internationalization boilerplate
|
|
||||||
local MP = minetest.get_modpath(minetest.get_current_modname())
|
|
||||||
local S, NS = dofile(MP.."/intllib.lua")
|
|
||||||
|
|
||||||
local size = 3/16
|
|
||||||
|
|
||||||
local max_dig_cost = math.max(digtron.config.dig_cost_cracky, digtron.config.dig_cost_crumbly, digtron.config.dig_cost_choppy, digtron.config.dig_cost_default)
|
|
||||||
|
|
||||||
local get_formspec_string = function(current_val, current_max)
|
|
||||||
return "size[4.5,0.6]" ..
|
|
||||||
default.gui_bg ..
|
|
||||||
default.gui_bg_img ..
|
|
||||||
default.gui_slots ..
|
|
||||||
"field[0.2,0.3;1,1;value;;".. current_val .. "]" ..
|
|
||||||
"button[1,0;1,1;maximize;" .. S("Maximize\nPower") .."]" ..
|
|
||||||
"label[2,0;"..S("Maximum Power\nRequired: @1", current_max) .."]"..
|
|
||||||
"button[3.5,0;1,1;refresh;" .. S("Refresh\nMax") .."]"
|
|
||||||
end
|
|
||||||
|
|
||||||
local connector_groups = {cracky = 3, oddly_breakable_by_hand=3, digtron = 8, technic_machine=1, technic_hv=1}
|
|
||||||
if not minetest.get_modpath("technic") then
|
|
||||||
-- Technic is not installed, hide this away.
|
|
||||||
connector_groups.not_in_creative_inventory = 1
|
|
||||||
end
|
|
||||||
|
|
||||||
minetest.register_node("digtron:power_connector", {
|
|
||||||
description = S("Digtron HV Power Connector"),
|
|
||||||
_doc_items_longdesc = digtron.doc.power_connector_longdesc,
|
|
||||||
_doc_items_usagehelp = digtron.doc.power_connector_usagehelp,
|
|
||||||
groups = connector_groups,
|
|
||||||
tiles = {"digtron_plate.png^digtron_power_connector_top.png^digtron_digger_yb_frame.png", "digtron_plate.png^digtron_digger_yb_frame.png",
|
|
||||||
"digtron_plate.png^digtron_digger_yb_frame.png^digtron_power_connector_side.png", "digtron_plate.png^digtron_digger_yb_frame.png^digtron_power_connector_side.png",
|
|
||||||
"digtron_plate.png^digtron_digger_yb_frame.png^digtron_power_connector_side.png", "digtron_plate.png^digtron_digger_yb_frame.png^digtron_power_connector_side.png",
|
|
||||||
},
|
|
||||||
connect_sides = {"bottom", "top", "left", "right", "front", "back"},
|
|
||||||
drawtype = "nodebox",
|
|
||||||
sounds = digtron.metal_sounds,
|
|
||||||
paramtype = "light",
|
|
||||||
paramtype2 = "facedir",
|
|
||||||
is_ground_content = false,
|
|
||||||
|
|
||||||
connects_to = {"group:technic_hv_cable"},
|
|
||||||
node_box = {
|
|
||||||
type = "connected",
|
|
||||||
fixed = {
|
|
||||||
{-0.5, -0.5, -0.5, 0.5, 0, 0.5}, -- Main body
|
|
||||||
{-0.1875, 0, -0.1875, 0.1875, 0.5, 0.1875}, -- post
|
|
||||||
{-0.3125, 0.0625, -0.3125, 0.3125, 0.1875, 0.3125}, -- vane
|
|
||||||
{-0.3125, 0.25, -0.3125, 0.3125, 0.375, 0.3125}, -- vane
|
|
||||||
},
|
|
||||||
connect_front = {-size, -size, -0.5, size, size, size}, -- z-
|
|
||||||
connect_back = {-size, -size, size, size, size, 0.5 }, -- z+
|
|
||||||
connect_left = {-0.5, -size, -size, size, size, size}, -- x-
|
|
||||||
connect_right = {-size, -size, -size, 0.5, size, size}, -- x+
|
|
||||||
},
|
|
||||||
|
|
||||||
on_construct = function(pos)
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
meta:set_string("formspec", get_formspec_string(0,0))
|
|
||||||
end,
|
|
||||||
|
|
||||||
technic_run = function(pos, node)
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
local eu_input = meta:get_int("HV_EU_input")
|
|
||||||
local demand = meta:get_int("HV_EU_demand")
|
|
||||||
meta:set_string("infotext", S("Digtron Power @1/@2", eu_input, demand))
|
|
||||||
end,
|
|
||||||
|
|
||||||
on_receive_fields = function(pos, formname, fields, sender)
|
|
||||||
local layout = DigtronLayout.create(pos, sender)
|
|
||||||
local max_cost = 0
|
|
||||||
if layout.builders ~= nil then
|
|
||||||
for _, node_image in pairs(layout.builders) do
|
|
||||||
max_cost = max_cost + (digtron.config.build_cost * (node_image.meta.fields.extrusion or 1))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if layout.diggers ~= nil then
|
|
||||||
for _, node_image in pairs(layout.diggers) do
|
|
||||||
max_cost = max_cost + max_dig_cost
|
|
||||||
end
|
|
||||||
end
|
|
||||||
local current_max = max_cost * digtron.config.power_ratio
|
|
||||||
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
|
|
||||||
if fields.maximize then
|
|
||||||
meta:set_int("HV_EU_demand", current_max)
|
|
||||||
elseif fields.value ~= nil then
|
|
||||||
local number = tonumber(fields.value) or 0
|
|
||||||
local number = math.min(math.max(number, 0), current_max)
|
|
||||||
meta:set_int("HV_EU_demand", number)
|
|
||||||
end
|
|
||||||
|
|
||||||
meta:set_string("formspec", get_formspec_string(meta:get_int("HV_EU_demand"), current_max))
|
|
||||||
end,
|
|
||||||
})
|
|
||||||
|
|
||||||
if minetest.get_modpath("technic") then
|
|
||||||
technic.register_machine("HV", "digtron:power_connector", technic.receiver)
|
|
||||||
end
|
|
@ -2,23 +2,19 @@
|
|||||||
local MP = minetest.get_modpath(minetest.get_current_modname())
|
local MP = minetest.get_modpath(minetest.get_current_modname())
|
||||||
local S, NS = dofile(MP.."/intllib.lua")
|
local S, NS = dofile(MP.."/intllib.lua")
|
||||||
|
|
||||||
local pipeworks_path = minetest.get_modpath("pipeworks")
|
--local pipeworks_path = minetest.get_modpath("pipeworks")
|
||||||
|
|
||||||
local inventory_formspec_string =
|
local get_inventory_formspec = function(pos, player_name)
|
||||||
"size[8,9.3]" ..
|
return "size[8,9.3]" ..
|
||||||
default.gui_bg ..
|
default.gui_bg ..
|
||||||
default.gui_bg_img ..
|
default.gui_bg_img ..
|
||||||
default.gui_slots ..
|
default.gui_slots ..
|
||||||
"label[0,0;" .. S("Inventory items") .. "]" ..
|
"label[0,0;" .. S("Inventory items") .. "]" ..
|
||||||
"list[current_name;main;0,0.6;8,4;]" ..
|
"list[nodemeta:"..pos.x..","..pos.y..","..pos.z..";main;0,0.6;8,4;]" ..
|
||||||
"list[current_player;main;0,5.15;8,1;]" ..
|
"list[current_player;main;0,5.15;8,1;]" ..
|
||||||
|
"listring[]" ..
|
||||||
"list[current_player;main;0,6.38;8,3;8]" ..
|
"list[current_player;main;0,6.38;8,3;8]" ..
|
||||||
"listring[current_name;main]" ..
|
|
||||||
"listring[current_player;main]" ..
|
|
||||||
default.get_hotbar_bg(0,5.15)
|
default.get_hotbar_bg(0,5.15)
|
||||||
|
|
||||||
local inventory_formspec = function(pos, meta)
|
|
||||||
return inventory_formspec_string
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Storage buffer. Builder nodes draw from this inventory and digger nodes deposit into it.
|
-- Storage buffer. Builder nodes draw from this inventory and digger nodes deposit into it.
|
||||||
@ -27,9 +23,7 @@ minetest.register_node("digtron:inventory", {
|
|||||||
description = S("Digtron Inventory Storage"),
|
description = S("Digtron Inventory Storage"),
|
||||||
_doc_items_longdesc = digtron.doc.inventory_longdesc,
|
_doc_items_longdesc = digtron.doc.inventory_longdesc,
|
||||||
_doc_items_usagehelp = digtron.doc.inventory_usagehelp,
|
_doc_items_usagehelp = digtron.doc.inventory_usagehelp,
|
||||||
_digtron_formspec = inventory_formspec,
|
|
||||||
groups = {cracky = 3, oddly_breakable_by_hand=3, digtron = 2, tubedevice = 1, tubedevice_receiver = 1},
|
groups = {cracky = 3, oddly_breakable_by_hand=3, digtron = 2, tubedevice = 1, tubedevice_receiver = 1},
|
||||||
drop = "digtron:inventory",
|
|
||||||
sounds = digtron.metal_sounds,
|
sounds = digtron.metal_sounds,
|
||||||
paramtype2= "facedir",
|
paramtype2= "facedir",
|
||||||
drawtype = "nodebox",
|
drawtype = "nodebox",
|
||||||
@ -52,7 +46,6 @@ minetest.register_node("digtron:inventory", {
|
|||||||
|
|
||||||
on_construct = function(pos)
|
on_construct = function(pos)
|
||||||
local meta = minetest.get_meta(pos)
|
local meta = minetest.get_meta(pos)
|
||||||
meta:set_string("formspec", inventory_formspec(pos, meta))
|
|
||||||
local inv = meta:get_inventory()
|
local inv = meta:get_inventory()
|
||||||
inv:set_size("main", 8*4)
|
inv:set_size("main", 8*4)
|
||||||
end,
|
end,
|
||||||
@ -63,54 +56,62 @@ minetest.register_node("digtron:inventory", {
|
|||||||
return inv:is_empty("main")
|
return inv:is_empty("main")
|
||||||
end,
|
end,
|
||||||
|
|
||||||
-- Pipeworks compatibility
|
on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
|
||||||
----------------------------------------------------------------
|
local meta = minetest.get_meta(pos)
|
||||||
|
local digtron_id = meta:get("digtron_id")
|
||||||
|
local player_name = clicker:get_player_name()
|
||||||
|
if digtron_id == nil then
|
||||||
|
minetest.show_formspec(player_name,
|
||||||
|
"digtron_inventory:"..minetest.pos_to_string(pos)..":"..player_name,
|
||||||
|
get_inventory_formspec(pos, player_name))
|
||||||
|
else
|
||||||
|
minetest.chat_send_player(clicker:get_player_name(), "This Digtron is active, interact with its inventory via the controller node.")
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
|
||||||
tube = (function() if pipeworks_path then return {
|
|
||||||
insert_object = function(pos, node, stack, direction)
|
-- -- Pipeworks compatibility
|
||||||
local meta = minetest.get_meta(pos)
|
-- ----------------------------------------------------------------
|
||||||
local inv = meta:get_inventory()
|
--
|
||||||
return inv:add_item("main", stack)
|
-- tube = (function() if pipeworks_path then return {
|
||||||
end,
|
-- insert_object = function(pos, node, stack, direction)
|
||||||
can_insert = function(pos, node, stack, direction)
|
-- local meta = minetest.get_meta(pos)
|
||||||
local meta = minetest.get_meta(pos)
|
-- local inv = meta:get_inventory()
|
||||||
local inv = meta:get_inventory()
|
-- return inv:add_item("main", stack)
|
||||||
return inv:room_for_item("main", stack)
|
-- end,
|
||||||
end,
|
-- can_insert = function(pos, node, stack, direction)
|
||||||
input_inventory = "main",
|
-- local meta = minetest.get_meta(pos)
|
||||||
connect_sides = {left = 1, right = 1, back = 1, front = 1, bottom = 1, top = 1}
|
-- local inv = meta:get_inventory()
|
||||||
} end end)(),
|
-- return inv:room_for_item("main", stack)
|
||||||
|
-- end,
|
||||||
after_place_node = (function() if pipeworks_path then return pipeworks.after_place end end)(),
|
-- input_inventory = "main",
|
||||||
after_dig_node = (function() if pipeworks_path then return pipeworks.after_dig end end)()
|
-- connect_sides = {left = 1, right = 1, back = 1, front = 1, bottom = 1, top = 1}
|
||||||
|
-- } end end)(),
|
||||||
|
--
|
||||||
|
-- after_place_node = (function() if pipeworks_path then return pipeworks.after_place end end)(),
|
||||||
|
-- after_dig_node = (function() if pipeworks_path then return pipeworks.after_dig end end)()
|
||||||
})
|
})
|
||||||
|
|
||||||
local fuelstore_formspec_string =
|
local get_fuelstore_formspec = function(pos, player_name)
|
||||||
"size[8,9.3]" ..
|
return "size[8,9.3]" ..
|
||||||
default.gui_bg ..
|
default.gui_bg ..
|
||||||
default.gui_bg_img ..
|
default.gui_bg_img ..
|
||||||
default.gui_slots ..
|
default.gui_slots ..
|
||||||
"label[0,0;" .. S("Fuel items") .. "]" ..
|
"label[0,0;" .. S("Fuel items") .. "]" ..
|
||||||
"list[current_name;fuel;0,0.6;8,4;]" ..
|
"list[nodemeta:"..pos.x..","..pos.y..","..pos.z..";fuel;0,0.6;8,4;]" ..
|
||||||
"list[current_player;main;0,5.15;8,1;]" ..
|
"list[current_player;main;0,5.15;8,1;]" ..
|
||||||
|
"listring[]" ..
|
||||||
"list[current_player;main;0,6.38;8,3;8]" ..
|
"list[current_player;main;0,6.38;8,3;8]" ..
|
||||||
"listring[current_name;fuel]" ..
|
|
||||||
"listring[current_player;main]" ..
|
|
||||||
default.get_hotbar_bg(0,5.15)
|
default.get_hotbar_bg(0,5.15)
|
||||||
|
|
||||||
local fuelstore_formspec = function(pos, meta)
|
|
||||||
return fuelstore_formspec_string
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Fuel storage. Controller node draws fuel from here.
|
-- Fuel storage. Controller node draws fuel from here.
|
||||||
-- Note that fuel stores are digtron group 5.
|
-- Note that fuel stores are digtron group 5.
|
||||||
minetest.register_node("digtron:fuelstore", {
|
minetest.register_node("digtron:fuelstore", {
|
||||||
description = S("Digtron Fuel Storage"),
|
description = S("Digtron Fuel Storage"),
|
||||||
_doc_items_longdesc = digtron.doc.fuelstore_longdesc,
|
_doc_items_longdesc = digtron.doc.fuelstore_longdesc,
|
||||||
_doc_items_usagehelp = digtron.doc.fuelstore_usagehelp,
|
_doc_items_usagehelp = digtron.doc.fuelstore_usagehelp,
|
||||||
_digtron_formspec = fuelstore_formspec,
|
|
||||||
groups = {cracky = 3, oddly_breakable_by_hand=3, digtron = 5, tubedevice = 1, tubedevice_receiver = 1},
|
groups = {cracky = 3, oddly_breakable_by_hand=3, digtron = 5, tubedevice = 1, tubedevice_receiver = 1},
|
||||||
drop = "digtron:fuelstore",
|
|
||||||
sounds = digtron.metal_sounds,
|
sounds = digtron.metal_sounds,
|
||||||
paramtype2= "facedir",
|
paramtype2= "facedir",
|
||||||
drawtype = "nodebox",
|
drawtype = "nodebox",
|
||||||
@ -133,7 +134,6 @@ minetest.register_node("digtron:fuelstore", {
|
|||||||
|
|
||||||
on_construct = function(pos)
|
on_construct = function(pos)
|
||||||
local meta = minetest.get_meta(pos)
|
local meta = minetest.get_meta(pos)
|
||||||
meta:set_string("formspec", fuelstore_formspec(pos, meta))
|
|
||||||
local inv = meta:get_inventory()
|
local inv = meta:get_inventory()
|
||||||
inv:set_size("fuel", 8*4)
|
inv:set_size("fuel", 8*4)
|
||||||
end,
|
end,
|
||||||
@ -155,52 +155,63 @@ minetest.register_node("digtron:fuelstore", {
|
|||||||
local inv = meta:get_inventory()
|
local inv = meta:get_inventory()
|
||||||
return inv:is_empty("fuel")
|
return inv:is_empty("fuel")
|
||||||
end,
|
end,
|
||||||
|
|
||||||
-- Pipeworks compatibility
|
|
||||||
----------------------------------------------------------------
|
|
||||||
|
|
||||||
tube = (function() if pipeworks_path then return {
|
|
||||||
insert_object = function(pos, node, stack, direction)
|
|
||||||
if minetest.get_craft_result({method="fuel", width=1, items={stack}}).time ~= 0 then
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
local inv = meta:get_inventory()
|
|
||||||
return inv:add_item("fuel", stack)
|
|
||||||
end
|
|
||||||
return stack
|
|
||||||
end,
|
|
||||||
can_insert = function(pos, node, stack, direction)
|
|
||||||
if minetest.get_craft_result({method="fuel", width=1, items={stack}}).time ~= 0 then
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
local inv = meta:get_inventory()
|
|
||||||
return inv:room_for_item("fuel", stack)
|
|
||||||
end
|
|
||||||
return false
|
|
||||||
end,
|
|
||||||
input_inventory = "fuel",
|
|
||||||
connect_sides = {left = 1, right = 1, back = 1, front = 1, bottom = 1, top = 1}
|
|
||||||
} end end)(),
|
|
||||||
|
|
||||||
after_place_node = (function() if pipeworks_path then return pipeworks.after_place end end)(),
|
on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
|
||||||
after_dig_node = (function() if pipeworks_path then return pipeworks.after_dig end end)()
|
local meta = minetest.get_meta(pos)
|
||||||
})
|
local digtron_id = meta:get("digtron_id")
|
||||||
|
local player_name = clicker:get_player_name()
|
||||||
|
if digtron_id == nil then
|
||||||
|
minetest.show_formspec(player_name,
|
||||||
|
"digtron_fuelstore:"..minetest.pos_to_string(pos)..":"..player_name,
|
||||||
|
get_fuelstore_formspec(pos, player_name))
|
||||||
|
else
|
||||||
|
minetest.chat_send_player(clicker:get_player_name(), "This Digtron is active, interact with its inventory via the controller node.")
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
|
||||||
local combined_storage_formspec_string =
|
--
|
||||||
"size[8,9.9]" ..
|
-- -- Pipeworks compatibility
|
||||||
|
-- ----------------------------------------------------------------
|
||||||
|
--
|
||||||
|
-- tube = (function() if pipeworks_path then return {
|
||||||
|
-- insert_object = function(pos, node, stack, direction)
|
||||||
|
-- if minetest.get_craft_result({method="fuel", width=1, items={stack}}).time ~= 0 then
|
||||||
|
-- local meta = minetest.get_meta(pos)
|
||||||
|
-- local inv = meta:get_inventory()
|
||||||
|
-- return inv:add_item("fuel", stack)
|
||||||
|
-- end
|
||||||
|
-- return stack
|
||||||
|
-- end,
|
||||||
|
-- can_insert = function(pos, node, stack, direction)
|
||||||
|
-- if minetest.get_craft_result({method="fuel", width=1, items={stack}}).time ~= 0 then
|
||||||
|
-- local meta = minetest.get_meta(pos)
|
||||||
|
-- local inv = meta:get_inventory()
|
||||||
|
-- return inv:room_for_item("fuel", stack)
|
||||||
|
-- end
|
||||||
|
-- return false
|
||||||
|
-- end,
|
||||||
|
-- input_inventory = "fuel",
|
||||||
|
-- connect_sides = {left = 1, right = 1, back = 1, front = 1, bottom = 1, top = 1}
|
||||||
|
-- } end end)(),
|
||||||
|
--
|
||||||
|
-- after_place_node = (function() if pipeworks_path then return pipeworks.after_place end end)(),
|
||||||
|
-- after_dig_node = (function() if pipeworks_path then return pipeworks.after_dig end end)()
|
||||||
|
})
|
||||||
|
--
|
||||||
|
local get_combined_formspec = function(pos, player_name)
|
||||||
|
return "size[8,9.9]" ..
|
||||||
default.gui_bg ..
|
default.gui_bg ..
|
||||||
default.gui_bg_img ..
|
default.gui_bg_img ..
|
||||||
default.gui_slots ..
|
default.gui_slots ..
|
||||||
"label[0,0;" .. S("Inventory items") .. "]" ..
|
"label[0,0;" .. S("Inventory items") .. "]" ..
|
||||||
"list[current_name;main;0,0.6;8,3;]" ..
|
"list[nodemeta:"..pos.x..","..pos.y..","..pos.z..";main;0,0.6;8,3;]" ..
|
||||||
"label[0,3.5;" .. S("Fuel items") .. "]" ..
|
"label[0,3.5;" .. S("Fuel items") .. "]" ..
|
||||||
"list[current_name;fuel;0,4.1;8,1;]" ..
|
"list[nodemeta:"..pos.x..","..pos.y..","..pos.z..";fuel;0,4.1;8,1;]" ..
|
||||||
"list[current_player;main;0,5.75;8,1;]" ..
|
"list[current_player;main;0,5.75;8,1;]" ..
|
||||||
"list[current_player;main;0,6.98;8,3;8]" ..
|
"list[current_player;main;0,6.98;8,3;8]" ..
|
||||||
"listring[current_name;main]" ..
|
"listring[nodemeta:"..pos.x..","..pos.y..","..pos.z..";main]" ..
|
||||||
"listring[current_player;main]" ..
|
"listring[current_player;main]" ..
|
||||||
default.get_hotbar_bg(0,5.75)
|
default.get_hotbar_bg(0,5.75)
|
||||||
|
|
||||||
local combined_storage_formspec = function(pos, meta)
|
|
||||||
return combined_storage_formspec_string
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Combined storage. Group 6 has both an inventory and a fuel store
|
-- Combined storage. Group 6 has both an inventory and a fuel store
|
||||||
@ -208,9 +219,7 @@ minetest.register_node("digtron:combined_storage", {
|
|||||||
description = S("Digtron Combined Storage"),
|
description = S("Digtron Combined Storage"),
|
||||||
_doc_items_longdesc = digtron.doc.combined_storage_longdesc,
|
_doc_items_longdesc = digtron.doc.combined_storage_longdesc,
|
||||||
_doc_items_usagehelp = digtron.doc.combined_storage_usagehelp,
|
_doc_items_usagehelp = digtron.doc.combined_storage_usagehelp,
|
||||||
_digtron_formspec = combined_storage_formspec,
|
|
||||||
groups = {cracky = 3, oddly_breakable_by_hand=3, digtron = 6, tubedevice = 1, tubedevice_receiver = 1},
|
groups = {cracky = 3, oddly_breakable_by_hand=3, digtron = 6, tubedevice = 1, tubedevice_receiver = 1},
|
||||||
drop = "digtron:combined_storage",
|
|
||||||
sounds = digtron.metal_sounds,
|
sounds = digtron.metal_sounds,
|
||||||
paramtype2= "facedir",
|
paramtype2= "facedir",
|
||||||
drawtype = "nodebox",
|
drawtype = "nodebox",
|
||||||
@ -231,7 +240,6 @@ minetest.register_node("digtron:combined_storage", {
|
|||||||
},
|
},
|
||||||
on_construct = function(pos)
|
on_construct = function(pos)
|
||||||
local meta = minetest.get_meta(pos)
|
local meta = minetest.get_meta(pos)
|
||||||
meta:set_string("formspec", combined_storage_formspec(pos, meta))
|
|
||||||
local inv = meta:get_inventory()
|
local inv = meta:get_inventory()
|
||||||
inv:set_size("main", 8*3)
|
inv:set_size("main", 8*3)
|
||||||
inv:set_size("fuel", 8*1)
|
inv:set_size("fuel", 8*1)
|
||||||
@ -268,47 +276,60 @@ minetest.register_node("digtron:combined_storage", {
|
|||||||
local inv = meta:get_inventory()
|
local inv = meta:get_inventory()
|
||||||
return inv:is_empty("fuel") and inv:is_empty("main")
|
return inv:is_empty("fuel") and inv:is_empty("main")
|
||||||
end,
|
end,
|
||||||
|
|
||||||
-- Pipeworks compatibility
|
|
||||||
----------------------------------------------------------------
|
|
||||||
tube = (function() if pipeworks_path then return {
|
|
||||||
insert_object = function(pos, node, stack, direction)
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
local inv = meta:get_inventory()
|
|
||||||
if minetest.get_craft_result({method="fuel", width=1, items={stack}}).time ~= 0 and direction.y == 1 then
|
|
||||||
return inv:add_item("fuel", stack)
|
|
||||||
end
|
|
||||||
return inv:add_item("main", stack)
|
|
||||||
end,
|
|
||||||
can_insert = function(pos, node, stack, direction)
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
local inv = meta:get_inventory()
|
|
||||||
if minetest.get_craft_result({method="fuel", width=1, items={stack}}).time ~= 0 and direction.y == 1 then
|
|
||||||
return inv:room_for_item("fuel", stack)
|
|
||||||
end
|
|
||||||
return inv:room_for_item("main", stack)
|
|
||||||
end,
|
|
||||||
input_inventory = "main",
|
|
||||||
connect_sides = {left = 1, right = 1, back = 1, front = 1, bottom = 1, top = 1}
|
|
||||||
} end end)(),
|
|
||||||
|
|
||||||
after_place_node = (function() if pipeworks_path then return pipeworks.after_place end end)(),
|
on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
|
||||||
after_dig_node = (function() if pipeworks_path then return pipeworks.after_dig end end)()
|
local meta = minetest.get_meta(pos)
|
||||||
|
local digtron_id = meta:get("digtron_id")
|
||||||
|
local player_name = clicker:get_player_name()
|
||||||
|
if digtron_id == nil then
|
||||||
|
minetest.show_formspec(player_name,
|
||||||
|
"digtron_combined_storage:"..minetest.pos_to_string(pos)..":"..player_name,
|
||||||
|
get_combined_formspec(pos, player_name))
|
||||||
|
else
|
||||||
|
minetest.chat_send_player(clicker:get_player_name(), "This Digtron is active, interact with its inventory via the controller node.")
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
--
|
||||||
|
-- -- Pipeworks compatibility
|
||||||
|
-- ----------------------------------------------------------------
|
||||||
|
-- tube = (function() if pipeworks_path then return {
|
||||||
|
-- insert_object = function(pos, node, stack, direction)
|
||||||
|
-- local meta = minetest.get_meta(pos)
|
||||||
|
-- local inv = meta:get_inventory()
|
||||||
|
-- if minetest.get_craft_result({method="fuel", width=1, items={stack}}).time ~= 0 and direction.y == 1 then
|
||||||
|
-- return inv:add_item("fuel", stack)
|
||||||
|
-- end
|
||||||
|
-- return inv:add_item("main", stack)
|
||||||
|
-- end,
|
||||||
|
-- can_insert = function(pos, node, stack, direction)
|
||||||
|
-- local meta = minetest.get_meta(pos)
|
||||||
|
-- local inv = meta:get_inventory()
|
||||||
|
-- if minetest.get_craft_result({method="fuel", width=1, items={stack}}).time ~= 0 and direction.y == 1 then
|
||||||
|
-- return inv:room_for_item("fuel", stack)
|
||||||
|
-- end
|
||||||
|
-- return inv:room_for_item("main", stack)
|
||||||
|
-- end,
|
||||||
|
-- input_inventory = "main",
|
||||||
|
-- connect_sides = {left = 1, right = 1, back = 1, front = 1, bottom = 1, top = 1}
|
||||||
|
-- } end end)(),
|
||||||
|
--
|
||||||
|
-- after_place_node = (function() if pipeworks_path then return pipeworks.after_place end end)(),
|
||||||
|
-- after_dig_node = (function() if pipeworks_path then return pipeworks.after_dig end end)()
|
||||||
})
|
})
|
||||||
|
--
|
||||||
-- Hopper compatibility
|
---- Hopper compatibility
|
||||||
if minetest.get_modpath("hopper") and hopper ~= nil and hopper.add_container ~= nil then
|
--if minetest.get_modpath("hopper") and hopper ~= nil and hopper.add_container ~= nil then
|
||||||
hopper:add_container({
|
-- hopper:add_container({
|
||||||
{"top", "digtron:inventory", "main"},
|
-- {"top", "digtron:inventory", "main"},
|
||||||
{"bottom", "digtron:inventory", "main"},
|
-- {"bottom", "digtron:inventory", "main"},
|
||||||
{"side", "digtron:inventory", "main"},
|
-- {"side", "digtron:inventory", "main"},
|
||||||
|
--
|
||||||
{"top", "digtron:fuelstore", "fuel"},
|
-- {"top", "digtron:fuelstore", "fuel"},
|
||||||
{"bottom", "digtron:fuelstore", "fuel"},
|
-- {"bottom", "digtron:fuelstore", "fuel"},
|
||||||
{"side", "digtron:fuelstore", "fuel"},
|
-- {"side", "digtron:fuelstore", "fuel"},
|
||||||
|
--
|
||||||
{"top", "digtron:combined_storage", "main"},
|
-- {"top", "digtron:combined_storage", "main"},
|
||||||
{"bottom", "digtron:combined_storage", "main"},
|
-- {"bottom", "digtron:combined_storage", "main"},
|
||||||
{"side", "digtron:combined_storage", "fuel"},
|
-- {"side", "digtron:combined_storage", "fuel"},
|
||||||
})
|
-- })
|
||||||
end
|
--end
|
||||||
|
@ -1,334 +0,0 @@
|
|||||||
-- internationalization boilerplate
|
|
||||||
local MP = minetest.get_modpath(minetest.get_current_modname())
|
|
||||||
local S, NS = dofile(MP.."/intllib.lua")
|
|
||||||
|
|
||||||
minetest.register_craftitem("digtron:digtron_core", {
|
|
||||||
description = S("Digtron Core"),
|
|
||||||
inventory_image = "digtron_core.png",
|
|
||||||
_doc_items_longdesc = digtron.doc.core_longdesc,
|
|
||||||
_doc_items_usagehelp = digtron.doc.core_usagehelp,
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_craft({
|
|
||||||
output = "digtron:digtron_core",
|
|
||||||
recipe = {
|
|
||||||
{"","default:steel_ingot",""},
|
|
||||||
{"default:steel_ingot","default:mese_crystal_fragment","default:steel_ingot"},
|
|
||||||
{"","default:steel_ingot",""}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_craft({
|
|
||||||
output = "digtron:controller",
|
|
||||||
recipe = {
|
|
||||||
{"","default:mese_crystal",""},
|
|
||||||
{"default:mese_crystal","digtron:digtron_core","default:mese_crystal"},
|
|
||||||
{"","default:mese_crystal",""}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_craft({
|
|
||||||
output = "digtron:auto_controller",
|
|
||||||
recipe = {
|
|
||||||
{"default:mese_crystal","default:mese_crystal","default:mese_crystal"},
|
|
||||||
{"default:mese_crystal","digtron:digtron_core","default:mese_crystal"},
|
|
||||||
{"default:mese_crystal","default:mese_crystal","default:mese_crystal"}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_craft({
|
|
||||||
output = "digtron:builder",
|
|
||||||
recipe = {
|
|
||||||
{"","default:mese_crystal_fragment",""},
|
|
||||||
{"default:mese_crystal_fragment","digtron:digtron_core","default:mese_crystal_fragment"},
|
|
||||||
{"","default:mese_crystal_fragment",""}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_craft({
|
|
||||||
output = "digtron:light",
|
|
||||||
recipe = {
|
|
||||||
{"","default:torch",""},
|
|
||||||
{"","digtron:digtron_core",""},
|
|
||||||
{"","",""}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_craft({
|
|
||||||
output = "digtron:digger",
|
|
||||||
recipe = {
|
|
||||||
{"","default:diamond",""},
|
|
||||||
{"default:diamond","digtron:digtron_core","default:diamond"},
|
|
||||||
{"","default:diamond",""}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_craft({
|
|
||||||
output = "digtron:soft_digger",
|
|
||||||
recipe = {
|
|
||||||
{"","default:steel_ingot",""},
|
|
||||||
{"default:steel_ingot","digtron:digtron_core","default:steel_ingot"},
|
|
||||||
{"","default:steel_ingot",""}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_craft({
|
|
||||||
output = "digtron:inventory",
|
|
||||||
recipe = {
|
|
||||||
{"","default:chest",""},
|
|
||||||
{"","digtron:digtron_core",""},
|
|
||||||
{"","",""}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_craft({
|
|
||||||
output = "digtron:fuelstore",
|
|
||||||
recipe = {
|
|
||||||
{"","default:furnace",""},
|
|
||||||
{"","digtron:digtron_core",""},
|
|
||||||
{"","",""}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
if minetest.get_modpath("technic") then
|
|
||||||
-- no need for this recipe if technic is not installed, avoid cluttering crafting guides
|
|
||||||
minetest.register_craft({
|
|
||||||
output = "digtron:battery_holder",
|
|
||||||
recipe = {
|
|
||||||
{"","default:chest",""},
|
|
||||||
{"","digtron:digtron_core",""},
|
|
||||||
{"","default:steel_ingot",""}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_craft({
|
|
||||||
output = "digtron:power_connector",
|
|
||||||
recipe = {
|
|
||||||
{"","technic:hv_cable",""},
|
|
||||||
{"technic:hv_cable","digtron:digtron_core","technic:hv_cable"},
|
|
||||||
{"","technic:hv_cable",""}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
minetest.register_craft({
|
|
||||||
output = "digtron:combined_storage",
|
|
||||||
recipe = {
|
|
||||||
{"","default:furnace",""},
|
|
||||||
{"","digtron:digtron_core",""},
|
|
||||||
{"","default:chest",""}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_craft({
|
|
||||||
output = "digtron:pusher",
|
|
||||||
recipe = {
|
|
||||||
{"","default:coal_lump",""},
|
|
||||||
{"default:coal_lump","digtron:digtron_core","default:coal_lump"},
|
|
||||||
{"","default:coal_lump",""}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_craft({
|
|
||||||
output = "digtron:axle",
|
|
||||||
recipe = {
|
|
||||||
{"default:coal_lump","default:coal_lump","default:coal_lump"},
|
|
||||||
{"default:coal_lump","digtron:digtron_core","default:coal_lump"},
|
|
||||||
{"default:coal_lump","default:coal_lump","default:coal_lump"}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_craft({
|
|
||||||
output = "digtron:empty_crate",
|
|
||||||
recipe = {
|
|
||||||
{"","default:chest",""},
|
|
||||||
{"","digtron:digtron_core",""},
|
|
||||||
{"","default:mese_crystal",""}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_craft({
|
|
||||||
output = "digtron:empty_locked_crate",
|
|
||||||
type = "shapeless",
|
|
||||||
recipe = {"default:steel_ingot", "digtron:empty_crate"},
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_craft({
|
|
||||||
output = "digtron:empty_crate",
|
|
||||||
type = "shapeless",
|
|
||||||
recipe = {"digtron:empty_locked_crate"},
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_craft({
|
|
||||||
output = "digtron:duplicator",
|
|
||||||
recipe = {
|
|
||||||
{"default:mese_crystal","default:mese_crystal","default:mese_crystal"},
|
|
||||||
{"default:chest","digtron:digtron_core","default:chest"},
|
|
||||||
{"default:mese_crystal","default:mese_crystal","default:mese_crystal"}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_craft({
|
|
||||||
output = "digtron:inventory_ejector",
|
|
||||||
recipe = {
|
|
||||||
{"default:steel_ingot","default:steel_ingot","default:steel_ingot"},
|
|
||||||
{"","digtron:digtron_core",""},
|
|
||||||
{"","default:steel_ingot",""}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
-- Structural
|
|
||||||
|
|
||||||
minetest.register_craft({
|
|
||||||
output = "digtron:structure",
|
|
||||||
recipe = {
|
|
||||||
{"group:stick","","group:stick"},
|
|
||||||
{"","digtron:digtron_core",""},
|
|
||||||
{"group:stick","","group:stick"}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_craft({
|
|
||||||
output = "digtron:panel",
|
|
||||||
recipe = {
|
|
||||||
{"","",""},
|
|
||||||
{"","digtron:digtron_core",""},
|
|
||||||
{"","default:steel_ingot",""}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_craft({
|
|
||||||
output = "digtron:edge_panel",
|
|
||||||
recipe = {
|
|
||||||
{"","",""},
|
|
||||||
{"","digtron:digtron_core","default:steel_ingot"},
|
|
||||||
{"","default:steel_ingot",""}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_craft({
|
|
||||||
output = "digtron:corner_panel",
|
|
||||||
recipe = {
|
|
||||||
{"","",""},
|
|
||||||
{"","digtron:digtron_core","default:steel_ingot"},
|
|
||||||
{"","default:steel_ingot","default:steel_ingot"}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
-- For swapping digger types
|
|
||||||
minetest.register_craft({
|
|
||||||
output = "digtron:digger",
|
|
||||||
recipe = {
|
|
||||||
{"digtron:intermittent_digger"},
|
|
||||||
}
|
|
||||||
})
|
|
||||||
minetest.register_craft({
|
|
||||||
output = "digtron:intermittent_digger",
|
|
||||||
recipe = {
|
|
||||||
{"digtron:digger"},
|
|
||||||
}
|
|
||||||
})
|
|
||||||
minetest.register_craft({
|
|
||||||
output = "digtron:soft_digger",
|
|
||||||
recipe = {
|
|
||||||
{"digtron:intermittent_soft_digger"},
|
|
||||||
}
|
|
||||||
})
|
|
||||||
minetest.register_craft({
|
|
||||||
output = "digtron:intermittent_soft_digger",
|
|
||||||
recipe = {
|
|
||||||
{"digtron:soft_digger"},
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_craft({
|
|
||||||
output = "digtron:dual_soft_digger",
|
|
||||||
type = "shapeless",
|
|
||||||
recipe = {"digtron:soft_digger", "digtron:soft_digger"},
|
|
||||||
})
|
|
||||||
minetest.register_craft({
|
|
||||||
output = "digtron:dual_digger",
|
|
||||||
type = "shapeless",
|
|
||||||
recipe = {"digtron:digger", "digtron:digger"},
|
|
||||||
})
|
|
||||||
minetest.register_craft({
|
|
||||||
output = "digtron:soft_digger 2",
|
|
||||||
recipe = {
|
|
||||||
{"digtron:dual_soft_digger"},
|
|
||||||
}
|
|
||||||
})
|
|
||||||
minetest.register_craft({
|
|
||||||
output = "digtron:digger 2",
|
|
||||||
recipe = {
|
|
||||||
{"digtron:dual_digger"},
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
-- And some recycling reactions to get digtron cores out of the "cheap" parts:
|
|
||||||
|
|
||||||
minetest.register_craft({
|
|
||||||
output = "digtron:digtron_core",
|
|
||||||
recipe = {
|
|
||||||
{"digtron:structure"},
|
|
||||||
}
|
|
||||||
})
|
|
||||||
minetest.register_craft({
|
|
||||||
output = "digtron:digtron_core",
|
|
||||||
recipe = {
|
|
||||||
{"digtron:panel"},
|
|
||||||
}
|
|
||||||
})
|
|
||||||
minetest.register_craft({
|
|
||||||
output = "digtron:digtron_core",
|
|
||||||
recipe = {
|
|
||||||
{"digtron:corner_panel"},
|
|
||||||
}
|
|
||||||
})
|
|
||||||
minetest.register_craft({
|
|
||||||
output = "digtron:digtron_core",
|
|
||||||
recipe = {
|
|
||||||
{"digtron:edge_panel"},
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_craft({
|
|
||||||
output = "digtron:digtron_core",
|
|
||||||
recipe = {
|
|
||||||
{"digtron:inventory"},
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_craft({
|
|
||||||
output = "digtron:digtron_core",
|
|
||||||
recipe = {
|
|
||||||
{"digtron:fuelstore"},
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_craft({
|
|
||||||
output = "digtron:digtron_core",
|
|
||||||
recipe = {
|
|
||||||
{"digtron:combined_storage"},
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_craft({
|
|
||||||
output = "digtron:digtron_core",
|
|
||||||
recipe = {
|
|
||||||
{"digtron:light"},
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_craft({
|
|
||||||
output = "digtron:digtron_core",
|
|
||||||
recipe = {
|
|
||||||
{"digtron:pusher"},
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_craft({
|
|
||||||
output = "digtron:digtron_core",
|
|
||||||
recipe = {
|
|
||||||
{"digtron:axle"},
|
|
||||||
}
|
|
||||||
})
|
|
BIN
screenshot.png
BIN
screenshot.png
Binary file not shown.
Before Width: | Height: | Size: 58 KiB |
@ -1,51 +0,0 @@
|
|||||||
#This can cause digtrons to operate without consuming fuel or building materials,
|
|
||||||
#though they still check whether they have enough in inventory.
|
|
||||||
#It's a separate setting from regular creative mode.
|
|
||||||
digtron_uses_resources (Digtron uses resources) bool true
|
|
||||||
|
|
||||||
#When true, lava counts as protected blocks.
|
|
||||||
digtron_lava_impassible (Lava is impassible to Digtrons) bool true
|
|
||||||
|
|
||||||
#Sets how much HP damage a digger does. Soft material diggers do half this.
|
|
||||||
#Set to 0 to disable damage entirely.
|
|
||||||
digtron_damage_hp (Diggers damage this many hp) int 8
|
|
||||||
|
|
||||||
#How many seconds a digtron waits between cycles.
|
|
||||||
#Auto-controllers can make this wait longer, but cannot make it shorter.
|
|
||||||
digtron_cycle_time (Minimum Digtron cycle time in seconds) float 1.0 0.0 60.0
|
|
||||||
|
|
||||||
#How many Digtron blocks can be moved for each adjacent
|
|
||||||
#solid block that the Digtron has traction against
|
|
||||||
digtron_traction_factor (Digtron traction factor) float 3.0 0.0 1000.0
|
|
||||||
|
|
||||||
#The maximum extrusion setting permitted for a Digtron builder module.
|
|
||||||
digtron_maximum_extrusion (Digtron maximum extrusion) int 25 1 100
|
|
||||||
|
|
||||||
digtron_marker_crate_good_duration (Duration that 'good' crate markers last) float 3.0 0.0 100.0
|
|
||||||
digtron_marker_crate_bad_duration (Duration that 'bad' crate markers last) float 9.0 0.0 100.0
|
|
||||||
|
|
||||||
#When a Digtron encounters unloaded map blocks, cause them to load
|
|
||||||
#so that the Digtron can continue moving.
|
|
||||||
digtron_emerge_unloaded_mapblocks (Emerge unloaded map blocks) bool true
|
|
||||||
|
|
||||||
[Fuel costs]
|
|
||||||
|
|
||||||
#eg, stone.
|
|
||||||
#In a default Minetest game one lump of coal provides 40.0 units of fuel.
|
|
||||||
digtron_dig_cost_cracky (Fuel cost for digging cracky blocks) float 1.0 0.0 100.0
|
|
||||||
# eg, dirt, sand.
|
|
||||||
#In a default Minetest game one lump of coal provides 40.0 units of fuel.
|
|
||||||
digtron_dig_cost_crumbly (Fuel cost for digging crumbly blocks) float 0.5 0.0 100.0
|
|
||||||
#eg, wood.
|
|
||||||
#In a default Minetest game one lump of coal provides 40.0 units of fuel.
|
|
||||||
digtron_dig_cost_choppy (Fuel cost for digging choppy blocks) float 0.75 0.0 100.0
|
|
||||||
#Fuel cost to dig a block that doesn't fall into one of the other categories.
|
|
||||||
#In a default Minetest game one lump of coal provides 40.0 units of fuel.
|
|
||||||
digtron_dig_cost_default (Fuel cost for digging other block types) float 0.5 0.0 100.0
|
|
||||||
#How much fuel is required to build a block
|
|
||||||
digtron_build_cost (Fuel cost to build one block) float 1.0 0.0 100.0
|
|
||||||
|
|
||||||
#If the [technic] mod is installed Digtron can draw power from technic batteries.
|
|
||||||
#A full battery holds 10000 electrical units. This is divided by the power ratio
|
|
||||||
#setting to convert it into fuel units.
|
|
||||||
digtron_power_ratio (Electrical charge to coal heat conversion ratio) int 1 1000 100
|
|
59
upgrades.lua
59
upgrades.lua
@ -1,59 +0,0 @@
|
|||||||
-- re-applies the "_digtron_formspec" property from all digtron node defs to the digtron node's metadata.
|
|
||||||
minetest.register_lbm({
|
|
||||||
name = "digtron:generic_formspec_sanitizer",
|
|
||||||
nodenames = {"group:digtron"},
|
|
||||||
action = function(pos, node)
|
|
||||||
local node_def = minetest.registered_nodes[node.name]
|
|
||||||
if node_def._digtron_formspec then
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
meta:set_string("formspec", node_def._digtron_formspec(pos, meta))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_lbm({
|
|
||||||
name = "digtron:sand_digger_upgrade",
|
|
||||||
nodenames = {"digtron:sand_digger"},
|
|
||||||
action = function(pos, node)
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
local offset = meta:get_string("offset")
|
|
||||||
local period = meta:get_string("period")
|
|
||||||
minetest.set_node(pos, {name = "digtron:soft_digger",
|
|
||||||
param2 = node.param2})
|
|
||||||
meta:set_string("offset", offset)
|
|
||||||
meta:set_string("period", period)
|
|
||||||
end
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_lbm({
|
|
||||||
name = "digtron:fuelstore_upgrade",
|
|
||||||
nodenames = {"digtron:fuelstore"},
|
|
||||||
action = function(pos, node)
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
local inv = meta:get_inventory()
|
|
||||||
local list = inv:get_list("main")
|
|
||||||
inv:set_list("main", {})
|
|
||||||
inv:set_list("fuel", list)
|
|
||||||
end
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_lbm({
|
|
||||||
name = "digtron:autocontroller_lateral_upgrade",
|
|
||||||
nodenames = {"digtron:auto_controller"},
|
|
||||||
action = function(pos, node)
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
local cycles = meta:get_int("offset")
|
|
||||||
meta:set_int("cycles", cycles)
|
|
||||||
meta:set_int("offset", 0)
|
|
||||||
meta:set_int("slope", 0)
|
|
||||||
end
|
|
||||||
})
|
|
||||||
|
|
||||||
minetest.register_lbm({
|
|
||||||
name = "digtron:builder_extrusion_upgrade",
|
|
||||||
nodenames = {"digtron:builder"},
|
|
||||||
action = function(pos, node)
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
meta:set_int("extrusion", 1)
|
|
||||||
end
|
|
||||||
})
|
|
435
util.lua
435
util.lua
@ -1,435 +0,0 @@
|
|||||||
-- A random assortment of methods used in various places in this mod.
|
|
||||||
|
|
||||||
dofile( minetest.get_modpath( "digtron" ) .. "/util_item_place_node.lua" ) -- separated out to avoid potential for license complexity
|
|
||||||
dofile( minetest.get_modpath( "digtron" ) .. "/util_execute_cycle.lua" ) -- separated out simply for tidiness, there's some big code in there
|
|
||||||
|
|
||||||
local node_inventory_table = {type="node"} -- a reusable parameter for get_inventory calls, set the pos parameter before using.
|
|
||||||
|
|
||||||
-- Apparently node_sound_metal_defaults is a newer thing, I ran into games using an older version of the default mod without it.
|
|
||||||
if default.node_sound_metal_defaults ~= nil then
|
|
||||||
digtron.metal_sounds = default.node_sound_metal_defaults()
|
|
||||||
else
|
|
||||||
digtron.metal_sounds = default.node_sound_stone_defaults()
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
digtron.find_new_pos = function(pos, facing)
|
|
||||||
-- finds the point one node "forward", based on facing
|
|
||||||
local dir = minetest.facedir_to_dir(facing)
|
|
||||||
return vector.add(pos, dir)
|
|
||||||
end
|
|
||||||
|
|
||||||
local facedir_to_down_dir_table = {
|
|
||||||
[0]={x=0, y=-1, z=0},
|
|
||||||
{x=0, y=0, z=-1},
|
|
||||||
{x=0, y=0, z=1},
|
|
||||||
{x=-1, y=0, z=0},
|
|
||||||
{x=1, y=0, z=0},
|
|
||||||
{x=0, y=1, z=0}
|
|
||||||
}
|
|
||||||
digtron.facedir_to_down_dir = function(facing)
|
|
||||||
return facedir_to_down_dir_table[math.floor(facing/4)]
|
|
||||||
end
|
|
||||||
|
|
||||||
digtron.find_new_pos_downward = function(pos, facing)
|
|
||||||
return vector.add(pos, digtron.facedir_to_down_dir(facing))
|
|
||||||
end
|
|
||||||
|
|
||||||
digtron.mark_diggable = function(pos, nodes_dug, player)
|
|
||||||
-- mark the node as dug, if the player provided would have been able to dig it.
|
|
||||||
-- Don't *actually* dig the node yet, though, because if we dig a node with sand over it the sand will start falling
|
|
||||||
-- and then destroy whatever node we place there subsequently (either by a builder head or by moving a digtron node)
|
|
||||||
-- I don't like sand. It's coarse and rough and irritating and it gets everywhere. And it necessitates complicated dig routines.
|
|
||||||
-- returns fuel cost and what will be dropped by digging these nodes.
|
|
||||||
|
|
||||||
local target = minetest.get_node(pos)
|
|
||||||
|
|
||||||
-- prevent digtrons from being marked for digging.
|
|
||||||
if minetest.get_item_group(target.name, "digtron") ~= 0 or
|
|
||||||
minetest.get_item_group(target.name, "digtron_protected") ~= 0 or
|
|
||||||
minetest.get_item_group(target.name, "immortal") ~= 0 then
|
|
||||||
return 0
|
|
||||||
end
|
|
||||||
|
|
||||||
local targetdef = minetest.registered_nodes[target.name]
|
|
||||||
if targetdef == nil or targetdef.can_dig == nil or targetdef.can_dig(pos, player) then
|
|
||||||
nodes_dug:set(pos.x, pos.y, pos.z, true)
|
|
||||||
if target.name ~= "air" then
|
|
||||||
local in_known_group = false
|
|
||||||
local material_cost = 0
|
|
||||||
|
|
||||||
if digtron.config.uses_resources then
|
|
||||||
if minetest.get_item_group(target.name, "cracky") ~= 0 then
|
|
||||||
in_known_group = true
|
|
||||||
material_cost = math.max(material_cost, digtron.config.dig_cost_cracky)
|
|
||||||
end
|
|
||||||
if minetest.get_item_group(target.name, "crumbly") ~= 0 then
|
|
||||||
in_known_group = true
|
|
||||||
material_cost = math.max(material_cost, digtron.config.dig_cost_crumbly)
|
|
||||||
end
|
|
||||||
if minetest.get_item_group(target.name, "choppy") ~= 0 then
|
|
||||||
in_known_group = true
|
|
||||||
material_cost = math.max(material_cost, digtron.config.dig_cost_choppy)
|
|
||||||
end
|
|
||||||
if not in_known_group then
|
|
||||||
material_cost = digtron.config.dig_cost_default
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
return material_cost, minetest.get_node_drops(target.name, "")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return 0
|
|
||||||
end
|
|
||||||
|
|
||||||
digtron.can_build_to = function(pos, protected_nodes, dug_nodes)
|
|
||||||
-- Returns whether a space is clear to have something put into it
|
|
||||||
|
|
||||||
if protected_nodes:get(pos.x, pos.y, pos.z) then
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
-- tests if the location pointed to is clear to move something into
|
|
||||||
local target = minetest.get_node(pos)
|
|
||||||
if target.name == "air" or
|
|
||||||
dug_nodes:get(pos.x, pos.y, pos.z) == true or
|
|
||||||
minetest.registered_nodes[target.name].buildable_to == true
|
|
||||||
then
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
digtron.can_move_to = function(pos, protected_nodes, dug_nodes)
|
|
||||||
-- Same as can_build_to, but also checks if the current node is part of the digtron.
|
|
||||||
-- this allows us to disregard obstructions that *will* move out of the way.
|
|
||||||
if digtron.can_build_to(pos, protected_nodes, dug_nodes) == true or
|
|
||||||
minetest.get_item_group(minetest.get_node(pos).name, "digtron") ~= 0 then
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
digtron.place_in_inventory = function(itemname, inventory_positions, fallback_pos)
|
|
||||||
--tries placing the item in each inventory node in turn. If there's no room, drop it at fallback_pos
|
|
||||||
local itemstack = ItemStack(itemname)
|
|
||||||
if inventory_positions ~= nil then
|
|
||||||
for k, location in pairs(inventory_positions) do
|
|
||||||
node_inventory_table.pos = location.pos
|
|
||||||
local inv = minetest.get_inventory(node_inventory_table)
|
|
||||||
itemstack = inv:add_item("main", itemstack)
|
|
||||||
if itemstack:is_empty() then
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
minetest.add_item(fallback_pos, itemstack)
|
|
||||||
end
|
|
||||||
|
|
||||||
digtron.place_in_specific_inventory = function(itemname, pos, inventory_positions, fallback_pos)
|
|
||||||
--tries placing the item in a specific inventory. Other parameters are used as fallbacks on failure
|
|
||||||
--Use this method for putting stuff back after testing and failed builds so that if the player
|
|
||||||
--is trying to keep various inventories organized manually stuff will go back where it came from,
|
|
||||||
--probably.
|
|
||||||
local itemstack = ItemStack(itemname)
|
|
||||||
node_inventory_table.pos = pos
|
|
||||||
local inv = minetest.get_inventory(node_inventory_table)
|
|
||||||
local returned_stack = inv:add_item("main", itemstack)
|
|
||||||
if not returned_stack:is_empty() then
|
|
||||||
-- we weren't able to put the item back into that particular inventory for some reason.
|
|
||||||
-- try putting it *anywhere.*
|
|
||||||
digtron.place_in_inventory(returned_stack, inventory_positions, fallback_pos)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
digtron.take_from_inventory = function(itemname, inventory_positions)
|
|
||||||
if inventory_positions == nil then return nil end
|
|
||||||
--tries to take an item from each inventory node in turn. Returns location of inventory item was taken from on success, nil on failure
|
|
||||||
local itemstack = ItemStack(itemname)
|
|
||||||
for k, location in pairs(inventory_positions) do
|
|
||||||
node_inventory_table.pos = location.pos
|
|
||||||
local inv = minetest.get_inventory(node_inventory_table)
|
|
||||||
local output = inv:remove_item("main", itemstack)
|
|
||||||
if not output:is_empty() then
|
|
||||||
return location.pos
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Used to determine which coordinate is being checked for periodicity. eg, if the digtron is moving in the z direction, then periodicity is checked for every n nodes in the z axis.
|
|
||||||
digtron.get_controlling_coordinate = function(pos, facedir)
|
|
||||||
-- used for determining builder period and offset
|
|
||||||
local dir = digtron.facedir_to_dir_map[facedir]
|
|
||||||
if dir == 1 or dir == 3 then
|
|
||||||
return "z"
|
|
||||||
elseif dir == 2 or dir == 4 then
|
|
||||||
return "x"
|
|
||||||
else
|
|
||||||
return "y"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local fuel_craft = {method="fuel", width=1, items={}} -- reusable crafting recipe table for get_craft_result calls below
|
|
||||||
-- Searches fuel store inventories for burnable items and burns them until target is reached or surpassed
|
|
||||||
-- (or there's nothing left to burn). Returns the total fuel value burned
|
|
||||||
-- if the "test" parameter is set to true, doesn't actually take anything out of inventories.
|
|
||||||
-- We can get away with this sort of thing for fuel but not for builder inventory because there's just one
|
|
||||||
-- controller node burning stuff, not multiple build heads drawing from inventories in turn. Much simpler.
|
|
||||||
digtron.burn = function(fuelstore_positions, target, test)
|
|
||||||
if fuelstore_positions == nil then
|
|
||||||
return 0
|
|
||||||
end
|
|
||||||
|
|
||||||
local current_burned = 0
|
|
||||||
for k, location in pairs(fuelstore_positions) do
|
|
||||||
if current_burned > target then
|
|
||||||
break
|
|
||||||
end
|
|
||||||
node_inventory_table.pos = location.pos
|
|
||||||
local inv = minetest.get_inventory(node_inventory_table)
|
|
||||||
local invlist = inv:get_list("fuel")
|
|
||||||
|
|
||||||
if invlist == nil then -- This check shouldn't be needed, it's yet another guard against https://github.com/minetest/minetest/issues/8067
|
|
||||||
break
|
|
||||||
end
|
|
||||||
|
|
||||||
for i, itemstack in pairs(invlist) do
|
|
||||||
fuel_craft.items[1] = itemstack:peek_item(1)
|
|
||||||
local fuel_per_item = minetest.get_craft_result(fuel_craft).time
|
|
||||||
if fuel_per_item ~= 0 then
|
|
||||||
local actual_burned = math.min(
|
|
||||||
math.ceil((target - current_burned)/fuel_per_item), -- burn this many, if we can.
|
|
||||||
itemstack:get_count() -- how many we have at most.
|
|
||||||
)
|
|
||||||
if test ~= true then
|
|
||||||
-- don't bother recording the items if we're just testing, nothing is actually being removed.
|
|
||||||
itemstack:set_count(itemstack:get_count() - actual_burned)
|
|
||||||
end
|
|
||||||
current_burned = current_burned + actual_burned * fuel_per_item
|
|
||||||
end
|
|
||||||
if current_burned > target then
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if test ~= true then
|
|
||||||
-- only update the list if we're doing this for real.
|
|
||||||
inv:set_list("fuel", invlist)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return current_burned
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Consume energy from the batteries
|
|
||||||
-- The same as burning coal, except that instead of destroying the items in the inventory, we merely drain
|
|
||||||
-- the charge in them, leaving them empty. The charge is converted into "coal heat units" by a downscaling
|
|
||||||
-- factor, since if taken at face value (10000 EU), the batteries would be the ultimate power source barely
|
|
||||||
-- ever needing replacement.
|
|
||||||
digtron.tap_batteries = function(battery_positions, target, test)
|
|
||||||
if (battery_positions == nil) then
|
|
||||||
return 0
|
|
||||||
end
|
|
||||||
|
|
||||||
local current_burned = 0
|
|
||||||
-- 1 coal block is 370 PU
|
|
||||||
-- 1 coal lump is 40 PU
|
|
||||||
-- An RE battery holds 10000 EU of charge
|
|
||||||
-- local power_ratio = 100 -- How much charge equals 1 unit of PU from coal
|
|
||||||
-- setting Moved to digtron.config.power_ratio
|
|
||||||
|
|
||||||
for k, location in pairs(battery_positions) do
|
|
||||||
if current_burned > target then
|
|
||||||
break
|
|
||||||
end
|
|
||||||
node_inventory_table.pos = location.pos
|
|
||||||
local inv = minetest.get_inventory(node_inventory_table)
|
|
||||||
local invlist = inv:get_list("batteries")
|
|
||||||
|
|
||||||
if (invlist == nil) then -- This check shouldn't be needed, it's yet another guard against https://github.com/minetest/minetest/issues/8067
|
|
||||||
break
|
|
||||||
end
|
|
||||||
|
|
||||||
for i, itemstack in pairs(invlist) do
|
|
||||||
local meta = minetest.deserialize(itemstack:get_metadata())
|
|
||||||
if (meta ~= nil) then
|
|
||||||
local power_available = math.floor(meta.charge / digtron.config.power_ratio)
|
|
||||||
if power_available ~= 0 then
|
|
||||||
local actual_burned = power_available -- we just take all we have from the battery, since they aren't stackable
|
|
||||||
if test ~= true then
|
|
||||||
-- don't bother recording the items if we're just testing, nothing is actually being removed.
|
|
||||||
local charge_left = meta.charge - power_available * digtron.config.power_ratio
|
|
||||||
local properties = itemstack:get_tool_capabilities()
|
|
||||||
-- itemstack = technic.set_RE_wear(itemstack, charge_left, properties.groupcaps.fleshy.uses)
|
|
||||||
-- we only need half the function, so why bother using it in the first place
|
|
||||||
|
|
||||||
-- Charge is stored separately, but shown as wear level
|
|
||||||
-- This calls for recalculating the value.
|
|
||||||
local charge_level
|
|
||||||
if charge_left == 0 then
|
|
||||||
charge_level = 0
|
|
||||||
else
|
|
||||||
charge_level = 65536 - math.floor(charge_left / properties.groupcaps.fleshy.uses * 65535)
|
|
||||||
if charge_level > 65535 then charge_level = 65535 end
|
|
||||||
if charge_level < 1 then charge_level = 1 end
|
|
||||||
end
|
|
||||||
itemstack:set_wear(charge_level)
|
|
||||||
|
|
||||||
meta.charge = charge_left
|
|
||||||
itemstack:set_metadata(minetest.serialize(meta))
|
|
||||||
|
|
||||||
end
|
|
||||||
current_burned = current_burned + actual_burned
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
if current_burned > target then
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if test ~= true then
|
|
||||||
-- only update the list if we're doing this for real.
|
|
||||||
inv:set_list("batteries", invlist)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return current_burned
|
|
||||||
end
|
|
||||||
|
|
||||||
digtron.remove_builder_item = function(pos)
|
|
||||||
local objects = minetest.env:get_objects_inside_radius(pos, 0.5)
|
|
||||||
if objects ~= nil then
|
|
||||||
for _, obj in ipairs(objects) do
|
|
||||||
if obj and obj:get_luaentity() and obj:get_luaentity().name == "digtron:builder_item" then
|
|
||||||
obj:remove()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
digtron.update_builder_item = function(pos)
|
|
||||||
digtron.remove_builder_item(pos)
|
|
||||||
node_inventory_table.pos = pos
|
|
||||||
local inv = minetest.get_inventory(node_inventory_table)
|
|
||||||
local item_stack = inv:get_stack("main", 1)
|
|
||||||
if not item_stack:is_empty() then
|
|
||||||
digtron.create_builder_item = item_stack:get_name()
|
|
||||||
minetest.add_entity(pos,"digtron:builder_item")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local damage_def = {
|
|
||||||
full_punch_interval = 1.0,
|
|
||||||
damage_groups = {},
|
|
||||||
}
|
|
||||||
digtron.damage_creatures = function(player, source_pos, target_pos, amount, items_dropped)
|
|
||||||
local objects = minetest.env:get_objects_inside_radius(target_pos, 1.0)
|
|
||||||
if objects ~= nil then
|
|
||||||
damage_def.damage_groups.fleshy = amount
|
|
||||||
local velocity = {
|
|
||||||
x = target_pos.x-source_pos.x,
|
|
||||||
y = target_pos.y-source_pos.y + 0.2,
|
|
||||||
z = target_pos.z-source_pos.z,
|
|
||||||
}
|
|
||||||
for _, obj in ipairs(objects) do
|
|
||||||
if obj:is_player() then
|
|
||||||
-- See issue #2960 for status of a "set player velocity" method
|
|
||||||
-- instead, knock the player back
|
|
||||||
local newpos = {
|
|
||||||
x = target_pos.x + velocity.x,
|
|
||||||
y = target_pos.y + velocity.y,
|
|
||||||
z = target_pos.z + velocity.z,
|
|
||||||
}
|
|
||||||
obj:set_pos(newpos)
|
|
||||||
obj:punch(player, 1.0, damage_def, nil)
|
|
||||||
else
|
|
||||||
local lua_entity = obj:get_luaentity()
|
|
||||||
if lua_entity ~= nil then
|
|
||||||
if lua_entity.name == "__builtin:item" then
|
|
||||||
table.insert(items_dropped, lua_entity.itemstring)
|
|
||||||
lua_entity.itemstring = ""
|
|
||||||
obj:remove()
|
|
||||||
else
|
|
||||||
if obj.add_velocity ~= nil then
|
|
||||||
obj:add_velocity(velocity)
|
|
||||||
else
|
|
||||||
local vel = obj:get_velocity()
|
|
||||||
obj:set_velocity(vector.add(vel, velocity))
|
|
||||||
end
|
|
||||||
obj:punch(player, 1.0, damage_def, nil)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
-- If we killed any mobs they might have dropped some stuff, vacuum that up now too.
|
|
||||||
objects = minetest.env:get_objects_inside_radius(target_pos, 1.0)
|
|
||||||
if objects ~= nil then
|
|
||||||
for _, obj in ipairs(objects) do
|
|
||||||
if not obj:is_player() then
|
|
||||||
local lua_entity = obj:get_luaentity()
|
|
||||||
if lua_entity ~= nil and lua_entity.name == "__builtin:item" then
|
|
||||||
table.insert(items_dropped, lua_entity.itemstring)
|
|
||||||
lua_entity.itemstring = ""
|
|
||||||
obj:remove()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
digtron.is_soft_material = function(target)
|
|
||||||
local target_node = minetest.get_node(target)
|
|
||||||
if minetest.get_item_group(target_node.name, "crumbly") ~= 0 or
|
|
||||||
minetest.get_item_group(target_node.name, "choppy") ~= 0 or
|
|
||||||
minetest.get_item_group(target_node.name, "snappy") ~= 0 or
|
|
||||||
minetest.get_item_group(target_node.name, "oddly_breakable_by_hand") ~= 0 or
|
|
||||||
minetest.get_item_group(target_node.name, "fleshy") ~= 0 then
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
-- If someone sets very large offsets or intervals for the offset markers they might be added too far
|
|
||||||
-- away. safe_add_entity causes these attempts to be ignored rather than crashing the game.
|
|
||||||
-- returns the entity if successful, nil otherwise
|
|
||||||
function safe_add_entity(pos, name)
|
|
||||||
success, ret = pcall(minetest.add_entity, pos, name)
|
|
||||||
if success then return ret else return nil end
|
|
||||||
end
|
|
||||||
|
|
||||||
digtron.show_offset_markers = function(pos, offset, period)
|
|
||||||
local buildpos = digtron.find_new_pos(pos, minetest.get_node(pos).param2)
|
|
||||||
local x_pos = math.floor((buildpos.x+offset)/period)*period - offset
|
|
||||||
safe_add_entity({x=x_pos, y=buildpos.y, z=buildpos.z}, "digtron:marker")
|
|
||||||
if x_pos >= buildpos.x then
|
|
||||||
safe_add_entity({x=x_pos - period, y=buildpos.y, z=buildpos.z}, "digtron:marker")
|
|
||||||
end
|
|
||||||
if x_pos <= buildpos.x then
|
|
||||||
safe_add_entity({x=x_pos + period, y=buildpos.y, z=buildpos.z}, "digtron:marker")
|
|
||||||
end
|
|
||||||
|
|
||||||
local y_pos = math.floor((buildpos.y+offset)/period)*period - offset
|
|
||||||
safe_add_entity({x=buildpos.x, y=y_pos, z=buildpos.z}, "digtron:marker_vertical")
|
|
||||||
if y_pos >= buildpos.y then
|
|
||||||
safe_add_entity({x=buildpos.x, y=y_pos - period, z=buildpos.z}, "digtron:marker_vertical")
|
|
||||||
end
|
|
||||||
if y_pos <= buildpos.y then
|
|
||||||
safe_add_entity({x=buildpos.x, y=y_pos + period, z=buildpos.z}, "digtron:marker_vertical")
|
|
||||||
end
|
|
||||||
|
|
||||||
local z_pos = math.floor((buildpos.z+offset)/period)*period - offset
|
|
||||||
|
|
||||||
local entity = safe_add_entity({x=buildpos.x, y=buildpos.y, z=z_pos}, "digtron:marker")
|
|
||||||
if entity ~= nil then entity:setyaw(1.5708) end
|
|
||||||
|
|
||||||
if z_pos >= buildpos.z then
|
|
||||||
local entity = safe_add_entity({x=buildpos.x, y=buildpos.y, z=z_pos - period}, "digtron:marker")
|
|
||||||
if entity ~= nil then entity:setyaw(1.5708) end
|
|
||||||
end
|
|
||||||
if z_pos <= buildpos.z then
|
|
||||||
local entity = safe_add_entity({x=buildpos.x, y=buildpos.y, z=z_pos + period}, "digtron:marker")
|
|
||||||
if entity ~= nil then entity:setyaw(1.5708) end
|
|
||||||
end
|
|
||||||
end
|
|
@ -1,617 +0,0 @@
|
|||||||
-- internationalization boilerplate
|
|
||||||
local MP = minetest.get_modpath(minetest.get_current_modname())
|
|
||||||
local S, NS = dofile(MP.."/intllib.lua")
|
|
||||||
|
|
||||||
local dig_dust = function(pos, facing)
|
|
||||||
local direction = minetest.facedir_to_dir(facing)
|
|
||||||
return {
|
|
||||||
amount = 10,
|
|
||||||
time = 1.0,
|
|
||||||
minpos = vector.subtract(pos, vector.new(0.5,0.5,0.5)),
|
|
||||||
maxpos = vector.add(pos, vector.new(0.5,0.5,0.5)),
|
|
||||||
minvel = vector.multiply(direction, -10),
|
|
||||||
maxvel = vector.multiply(direction, -20),
|
|
||||||
minacc = {x=0, y=-40, z=0},
|
|
||||||
maxacc = {x=0, y=-40, z=0},
|
|
||||||
minexptime = 0.25,
|
|
||||||
maxexptime = 0.5,
|
|
||||||
minsize = 2,
|
|
||||||
maxsize = 5,
|
|
||||||
collisiondetection = false,
|
|
||||||
vertical = false,
|
|
||||||
texture = "default_item_smoke.png^[colorize:#9F817080",
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
local burn_smoke = function(pos, amount)
|
|
||||||
return {
|
|
||||||
amount = math.min(amount, 40),
|
|
||||||
time = 1.0,
|
|
||||||
minpos = vector.subtract(pos, vector.new(0.5,0.5,0.5)),
|
|
||||||
maxpos = vector.add(pos, vector.new(0.5,0.5,0.5)),
|
|
||||||
minvel = {x=0, y=2, z=0},
|
|
||||||
maxvel = {x=0, y=5, z=0},
|
|
||||||
minacc = {x=0, y=0, z=0},
|
|
||||||
maxacc = {x=0, y=0, z=0},
|
|
||||||
minexptime = 0.5,
|
|
||||||
maxexptime = 1.5,
|
|
||||||
minsize = 8,
|
|
||||||
maxsize = 12,
|
|
||||||
collisiondetection = false,
|
|
||||||
vertical = false,
|
|
||||||
texture = "default_item_smoke.png^[colorize:#000000DD",
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
--Performs various tests on a layout to play warning noises and see if Digtron can move at all.
|
|
||||||
local function neighbour_test(layout, status_text, dir)
|
|
||||||
if layout.ignore_touching == true then
|
|
||||||
-- if the digtron array touches unloaded nodes, too dangerous to do anything in that situation. Abort.
|
|
||||||
minetest.sound_play("buzzer", {gain=0.25, pos=layout.controller})
|
|
||||||
return S("Digtron is adjacent to unloaded nodes.") .. "\n" .. status_text, 1
|
|
||||||
end
|
|
||||||
|
|
||||||
if layout.water_touching == true then
|
|
||||||
minetest.sound_play("sploosh", {gain=1.0, pos=layout.controller})
|
|
||||||
end
|
|
||||||
|
|
||||||
if layout.lava_touching == true then
|
|
||||||
minetest.sound_play("woopwoopwoop", {gain=1.0, pos=layout.controller})
|
|
||||||
end
|
|
||||||
|
|
||||||
if dir and dir.y ~= -1 and layout.traction * digtron.config.traction_factor < table.getn(layout.all) then
|
|
||||||
-- digtrons can't fly, though they can fall
|
|
||||||
minetest.sound_play("squeal", {gain=1.0, pos=layout.controller})
|
|
||||||
return S("Digtron has @1 blocks but only enough traction to move @2 blocks.\n", table.getn(layout.all), layout.traction * digtron.config.traction_factor)
|
|
||||||
.. status_text, 2
|
|
||||||
end
|
|
||||||
|
|
||||||
return status_text, 0
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Checks if a player is within a layout's extents.
|
|
||||||
local function move_player_test(layout, player)
|
|
||||||
local player_pos = player:getpos()
|
|
||||||
if player_pos.x >= layout.extents_min_x - 1 and player_pos.x <= layout.extents_max_x + 1 and
|
|
||||||
player_pos.y >= layout.extents_min_y - 1 and player_pos.y <= layout.extents_max_y + 1 and
|
|
||||||
player_pos.z >= layout.extents_min_z - 1 and player_pos.z <= layout.extents_max_z + 1 then
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
local node_inventory_table = {type="node"} -- a reusable parameter for get_inventory calls, set the pos parameter before using.
|
|
||||||
local function test_stop_block(pos, items)
|
|
||||||
node_inventory_table.pos = pos
|
|
||||||
local inv = minetest.get_inventory(node_inventory_table)
|
|
||||||
local item_stack = inv:get_stack("stop", 1)
|
|
||||||
if not item_stack:is_empty() then
|
|
||||||
for _, item in pairs(items) do
|
|
||||||
if item == item_stack:get_name() then
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
local function check_digtron_size(layout)
|
|
||||||
if #layout.all > digtron.config.size_limit then
|
|
||||||
return S("Size limit of @1 reached with @2 nodes!", digtron.config.size_limit, #layout.all)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- returns newpos, status string, and a return code indicating why the method returned (so the auto-controller can keep trying if it's due to unloaded nodes)
|
|
||||||
-- 0 - success
|
|
||||||
-- 1 - failed due to unloaded nodes
|
|
||||||
-- 2 - failed due to insufficient traction
|
|
||||||
-- 3 - obstructed by undiggable node
|
|
||||||
-- 4 - insufficient fuel
|
|
||||||
-- 5 - unknown builder error during testing
|
|
||||||
-- 6 - builder with unset output
|
|
||||||
-- 7 - insufficient builder materials in inventory
|
|
||||||
-- 8 - size/node limit reached
|
|
||||||
digtron.execute_dig_cycle = function(pos, clicker)
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
local facing = minetest.get_node(pos).param2
|
|
||||||
local dir = minetest.facedir_to_dir(facing)
|
|
||||||
local fuel_burning = meta:get_float("fuel_burning") -- get amount of burned fuel left over from last cycle
|
|
||||||
local status_text = S("Heat remaining in controller furnace: @1", math.floor(math.max(0, fuel_burning)))
|
|
||||||
local exhaust = meta:get_int("on_coal")
|
|
||||||
|
|
||||||
local layout = DigtronLayout.create(pos, clicker)
|
|
||||||
|
|
||||||
local status_text, return_code = neighbour_test(layout, status_text, dir)
|
|
||||||
if return_code ~= 0 then
|
|
||||||
return pos, status_text, return_code
|
|
||||||
end
|
|
||||||
|
|
||||||
local size_check_error = check_digtron_size(layout)
|
|
||||||
if size_check_error then
|
|
||||||
return pos, size_check_error, 8
|
|
||||||
end
|
|
||||||
|
|
||||||
local controlling_coordinate = digtron.get_controlling_coordinate(pos, facing)
|
|
||||||
|
|
||||||
----------------------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
local items_dropped = {}
|
|
||||||
local digging_fuel_cost = 0
|
|
||||||
local particle_systems = {}
|
|
||||||
|
|
||||||
-- execute the execute_dig method on all digtron components that have one
|
|
||||||
-- This builds a set of nodes that will be dug and returns a list of products that will be generated
|
|
||||||
-- but doesn't actually dig the nodes yet. That comes later.
|
|
||||||
-- If we dug them now, sand would fall and some digtron nodes would die.
|
|
||||||
if layout.diggers ~= nil then
|
|
||||||
for k, location in pairs(layout.diggers) do
|
|
||||||
local target = minetest.get_node(location.pos)
|
|
||||||
local targetdef = minetest.registered_nodes[target.name]
|
|
||||||
if targetdef.execute_dig ~= nil then
|
|
||||||
local fuel_cost, dropped = targetdef.execute_dig(location.pos, layout.protected, layout.nodes_dug, controlling_coordinate, false, clicker)
|
|
||||||
if dropped ~= nil then
|
|
||||||
for _, itemname in pairs(dropped) do
|
|
||||||
table.insert(items_dropped, itemname)
|
|
||||||
end
|
|
||||||
if digtron.config.particle_effects then
|
|
||||||
table.insert(particle_systems, dig_dust(vector.add(location.pos, dir), target.param2))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
digging_fuel_cost = digging_fuel_cost + fuel_cost
|
|
||||||
else
|
|
||||||
minetest.log(string.format("%s has digger group but is missing execute_dig method! This is an error in mod programming, file a bug.", targetdef.name))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
----------------------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
-- test if any digtrons are obstructed by non-digtron nodes that haven't been marked
|
|
||||||
-- as having been dug.
|
|
||||||
local can_move = true
|
|
||||||
for _, location in pairs(layout.all) do
|
|
||||||
local newpos = vector.add(location.pos, dir)
|
|
||||||
if not digtron.can_move_to(newpos, layout.protected, layout.nodes_dug) then
|
|
||||||
can_move = false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if test_stop_block(pos, items_dropped) then
|
|
||||||
can_move = false
|
|
||||||
end
|
|
||||||
|
|
||||||
if not can_move then
|
|
||||||
-- mark this node as waiting, will clear this flag in digtron.config.cycle_time seconds
|
|
||||||
minetest.get_meta(pos):set_string("waiting", "true")
|
|
||||||
minetest.get_node_timer(pos):start(digtron.config.cycle_time)
|
|
||||||
minetest.sound_play("squeal", {gain=1.0, pos=pos})
|
|
||||||
minetest.sound_play("buzzer", {gain=0.5, pos=pos})
|
|
||||||
return pos, S("Digtron is obstructed.") .. "\n" .. status_text, 3 --Abort, don't dig and don't build.
|
|
||||||
end
|
|
||||||
|
|
||||||
----------------------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
-- ask each builder node if it can get what it needs from inventory to build this cycle.
|
|
||||||
-- This is a complicated test because each builder needs to actually *take* the item it'll
|
|
||||||
-- need from inventory, and then we put it all back afterward.
|
|
||||||
-- Note that this test may overestimate the amount of work that will actually need to be done so don't treat its fuel cost as authoritative.
|
|
||||||
local can_build = true
|
|
||||||
local test_build_return_code = nil
|
|
||||||
local test_build_return_items = nil
|
|
||||||
local failed_to_find = nil
|
|
||||||
local test_items = {}
|
|
||||||
local test_fuel_items = {}
|
|
||||||
local test_build_fuel_cost = 0
|
|
||||||
if layout.builders ~= nil then
|
|
||||||
for k, location in pairs(layout.builders) do
|
|
||||||
local target = minetest.get_node(location.pos)
|
|
||||||
local targetdef = minetest.registered_nodes[target.name]
|
|
||||||
local test_location = vector.add(location.pos, dir)
|
|
||||||
if targetdef.test_build ~= nil then
|
|
||||||
test_build_return_code, test_build_return_items, failed_to_find = targetdef.test_build(location.pos, test_location, layout.inventories, layout.protected, layout.nodes_dug, controlling_coordinate, layout.controller)
|
|
||||||
for k, return_item in pairs(test_build_return_items) do
|
|
||||||
table.insert(test_items, return_item)
|
|
||||||
test_build_fuel_cost = test_build_fuel_cost + digtron.config.build_cost
|
|
||||||
end
|
|
||||||
if test_build_return_code > 1 then
|
|
||||||
can_build = false
|
|
||||||
break
|
|
||||||
end
|
|
||||||
else
|
|
||||||
minetest.log(string.format("%s has builder group but is missing test_build method! This is an error in mod programming, file a bug.", targetdef.name))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local test_fuel_needed = test_build_fuel_cost + digging_fuel_cost - fuel_burning
|
|
||||||
local test_fuel_burned = 0
|
|
||||||
|
|
||||||
local power_from_cables = 0
|
|
||||||
if minetest.get_modpath("technic") then
|
|
||||||
if layout.power_connectors ~= nil then
|
|
||||||
local power_inputs = {}
|
|
||||||
for _, power_connector in pairs(layout.power_connectors) do
|
|
||||||
if power_connector.meta.fields.HV_network and power_connector.meta.fields.HV_EU_input then
|
|
||||||
power_inputs[power_connector.meta.fields.HV_network] = tonumber(power_connector.meta.fields.HV_EU_input)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
for _, power in pairs(power_inputs) do
|
|
||||||
power_from_cables = power_from_cables + power
|
|
||||||
end
|
|
||||||
power_from_cables = power_from_cables / digtron.config.power_ratio
|
|
||||||
test_fuel_burned = power_from_cables
|
|
||||||
end
|
|
||||||
|
|
||||||
if test_fuel_needed - test_fuel_burned > 0 then
|
|
||||||
-- check for the available electrical power
|
|
||||||
test_fuel_burned = test_fuel_burned + digtron.tap_batteries(layout.battery_holders, test_fuel_needed, true)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if (test_fuel_needed < test_fuel_burned) then
|
|
||||||
exhaust = 0 -- all power needs met by electricity, don't blow smoke
|
|
||||||
else
|
|
||||||
-- burn combustible fuel if not enough power
|
|
||||||
test_fuel_burned = test_fuel_burned + digtron.burn(layout.fuelstores, test_fuel_needed - test_fuel_burned, true)
|
|
||||||
exhaust = 1 -- burning fuel produces smoke
|
|
||||||
end
|
|
||||||
|
|
||||||
--Put everything back where it came from
|
|
||||||
for k, item_return in pairs(test_items) do
|
|
||||||
digtron.place_in_specific_inventory(item_return.item, item_return.location, layout.inventories, layout.controller)
|
|
||||||
end
|
|
||||||
|
|
||||||
if test_fuel_needed > fuel_burning + test_fuel_burned then
|
|
||||||
minetest.sound_play("buzzer", {gain=0.5, pos=pos})
|
|
||||||
return pos, S("Digtron needs more fuel."), 4 -- abort, don't dig and don't build.
|
|
||||||
end
|
|
||||||
|
|
||||||
if not can_build then
|
|
||||||
minetest.get_meta(pos):set_string("waiting", "true")
|
|
||||||
minetest.get_node_timer(pos):start(digtron.config.cycle_time)
|
|
||||||
local return_string = nil
|
|
||||||
local return_code = 5
|
|
||||||
if test_build_return_code == 3 then
|
|
||||||
minetest.sound_play("honk", {gain=0.5, pos=pos}) -- A builder is not configured
|
|
||||||
return_string = S("Digtron connected to at least one builder with no output material assigned.") .. "\n"
|
|
||||||
return_code = 6
|
|
||||||
elseif test_build_return_code == 2 then
|
|
||||||
minetest.sound_play("dingding", {gain=1.0, pos=pos}) -- Insufficient inventory
|
|
||||||
return_string = S("Digtron has insufficient building materials. Needed: @1", failed_to_find:get_name()) .. "\n"
|
|
||||||
return_code = 7
|
|
||||||
end
|
|
||||||
return pos, return_string .. status_text, return_code --Abort, don't dig and don't build.
|
|
||||||
end
|
|
||||||
|
|
||||||
----------------------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
-- All tests passed, ready to go for real!
|
|
||||||
minetest.sound_play("construction", {gain=1.0, pos=pos})
|
|
||||||
|
|
||||||
-- if the player is standing within the array or next to it, move him too.
|
|
||||||
local move_player = move_player_test(layout, clicker)
|
|
||||||
|
|
||||||
-- damage the weak flesh
|
|
||||||
if digtron.config.damage_hp > 0 and layout.diggers ~= nil then
|
|
||||||
for k, location in pairs(layout.diggers) do
|
|
||||||
local target = minetest.get_node(location.pos)
|
|
||||||
local targetdef = minetest.registered_nodes[target.name]
|
|
||||||
if targetdef.damage_creatures ~= nil then
|
|
||||||
targetdef.damage_creatures(clicker, location.pos, controlling_coordinate, items_dropped)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
--move the array
|
|
||||||
layout:move_layout_image(dir)
|
|
||||||
if not layout:write_layout_image(clicker) then
|
|
||||||
return pos, "unrecoverable write_layout_image error", 1
|
|
||||||
end
|
|
||||||
local oldpos = {x=pos.x, y=pos.y, z=pos.z}
|
|
||||||
pos = vector.add(pos, dir)
|
|
||||||
meta = minetest.get_meta(pos)
|
|
||||||
if move_player then
|
|
||||||
clicker:moveto(vector.add(dir, clicker:getpos()), true)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- store or drop the products of the digger heads
|
|
||||||
for _, itemname in pairs(items_dropped) do
|
|
||||||
digtron.place_in_inventory(itemname, layout.inventories, oldpos)
|
|
||||||
end
|
|
||||||
digtron.award_item_dug(items_dropped, clicker) -- Achievements mod hook
|
|
||||||
|
|
||||||
local building_fuel_cost = 0
|
|
||||||
local strange_failure = false
|
|
||||||
-- execute_build on all digtron components that have one
|
|
||||||
if layout.builders ~= nil then
|
|
||||||
for k, location in pairs(layout.builders) do
|
|
||||||
local target = minetest.get_node(location.pos)
|
|
||||||
local targetdef = minetest.registered_nodes[target.name]
|
|
||||||
if targetdef.execute_build ~= nil then
|
|
||||||
--using the old location of the controller as fallback so that any leftovers land with the rest of the digger output. Not that there should be any.
|
|
||||||
local build_return = targetdef.execute_build(location.pos, clicker, layout.inventories, layout.protected, layout.nodes_dug, controlling_coordinate, oldpos)
|
|
||||||
if build_return < 0 then
|
|
||||||
-- This happens if there's insufficient inventory, but we should have confirmed there was sufficient inventory during test phase.
|
|
||||||
-- So this should never happen. However, "should never happens" happen sometimes. So
|
|
||||||
-- don't interrupt the build cycle as a whole, we've already moved so might as well try to complete as much as possible.
|
|
||||||
strange_failure = true
|
|
||||||
build_return = (build_return * -1) - 1
|
|
||||||
elseif digtron.config.uses_resources then
|
|
||||||
building_fuel_cost = building_fuel_cost + (digtron.config.build_cost * build_return)
|
|
||||||
end
|
|
||||||
else
|
|
||||||
minetest.log(string.format("%s has builder group but is missing execute_build method! This is an error in mod programming, file a bug.", targetdef.name))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if layout.auto_ejectors ~= nil then
|
|
||||||
for k, location in pairs(layout.auto_ejectors) do
|
|
||||||
local target = minetest.get_node(location.pos)
|
|
||||||
local targetdef = minetest.registered_nodes[target.name]
|
|
||||||
if targetdef.execute_eject ~= nil then
|
|
||||||
targetdef.execute_eject(location.pos, target, clicker, layout)
|
|
||||||
else
|
|
||||||
minetest.log(string.format("%s has an ejector group but is missing execute_eject method! This is an error in mod programming, file a bug.", targetdef.name))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local status_text = ""
|
|
||||||
if strange_failure then
|
|
||||||
-- We weren't able to detect this build failure ahead of time, so make a big noise now. This is strange, shouldn't happen.
|
|
||||||
minetest.sound_play("dingding", {gain=1.0, pos=pos})
|
|
||||||
minetest.sound_play("buzzer", {gain=0.5, pos=pos})
|
|
||||||
status_text = S("Digtron unexpectedly failed to execute one or more build operations, likely due to an inventory error.") .. "\n"
|
|
||||||
end
|
|
||||||
|
|
||||||
local total_fuel_cost = math.max(digging_fuel_cost + building_fuel_cost - power_from_cables, 0)
|
|
||||||
|
|
||||||
-- actually burn the fuel needed
|
|
||||||
fuel_burning = fuel_burning - total_fuel_cost
|
|
||||||
if digtron.config.particle_effects and exhaust == 1 then
|
|
||||||
table.insert(particle_systems, burn_smoke(pos, total_fuel_cost))
|
|
||||||
end
|
|
||||||
if fuel_burning < 0 then
|
|
||||||
-- we tap into the batteries either way
|
|
||||||
fuel_burning = fuel_burning + digtron.tap_batteries(layout.battery_holders, -fuel_burning, false)
|
|
||||||
if exhaust == 1 then
|
|
||||||
-- but we burn coal only if we must (exhaust = flag)
|
|
||||||
fuel_burning = fuel_burning + digtron.burn(layout.fuelstores, -fuel_burning, false)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
meta:set_float("fuel_burning", fuel_burning)
|
|
||||||
meta:set_int("on_coal", exhaust)
|
|
||||||
status_text = status_text .. S("Heat remaining in controller furnace: @1", math.floor(math.max(0, fuel_burning)))
|
|
||||||
|
|
||||||
-- Eyecandy
|
|
||||||
for _, particles in pairs(particle_systems) do
|
|
||||||
minetest.add_particlespawner(particles)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- finally, dig out any nodes remaining to be dug. Some of these will have had their flag revoked because
|
|
||||||
-- a builder put something there or because they're another digtron node.
|
|
||||||
local node_to_dig, whether_to_dig = layout.nodes_dug:pop()
|
|
||||||
while node_to_dig ~= nil do
|
|
||||||
if whether_to_dig == true then
|
|
||||||
minetest.log("action", string.format("%s uses Digtron to dig %s at (%d, %d, %d)", clicker:get_player_name(), minetest.get_node(node_to_dig).name, node_to_dig.x, node_to_dig.y, node_to_dig.z))
|
|
||||||
minetest.remove_node(node_to_dig)
|
|
||||||
end
|
|
||||||
-- all of the digtron's nodes wind up in nodes_dug, so this is an ideal place to stick
|
|
||||||
-- a check to make sand fall after the digtron has passed.
|
|
||||||
minetest.check_for_falling({x=node_to_dig.x, y=node_to_dig.y+1, z=node_to_dig.z})
|
|
||||||
node_to_dig, whether_to_dig = layout.nodes_dug:pop()
|
|
||||||
end
|
|
||||||
return pos, status_text, 0
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
-- Simplified version of the above method that only moves, and doesn't execute diggers or builders.
|
|
||||||
digtron.execute_move_cycle = function(pos, clicker)
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
local layout = DigtronLayout.create(pos, clicker)
|
|
||||||
|
|
||||||
local status_text = ""
|
|
||||||
local status_text, return_code = neighbour_test(layout, status_text, nil) -- skip traction check for pusher by passing nil for direction
|
|
||||||
if return_code ~= 0 then
|
|
||||||
return pos, status_text, return_code
|
|
||||||
end
|
|
||||||
|
|
||||||
local size_check_error = check_digtron_size(layout)
|
|
||||||
if size_check_error then
|
|
||||||
return pos, size_check_error, 8
|
|
||||||
end
|
|
||||||
|
|
||||||
local facing = minetest.get_node(pos).param2
|
|
||||||
local dir = minetest.facedir_to_dir(facing)
|
|
||||||
local controlling_coordinate = digtron.get_controlling_coordinate(pos, facing)
|
|
||||||
|
|
||||||
-- if the player is standing within the array or next to it, move him too.
|
|
||||||
local move_player = move_player_test(layout, clicker)
|
|
||||||
|
|
||||||
-- test if any digtrons are obstructed by non-digtron nodes
|
|
||||||
layout:move_layout_image(dir)
|
|
||||||
if not layout:can_write_layout_image() then
|
|
||||||
-- mark this node as waiting, will clear this flag in digtron.config.cycle_time seconds
|
|
||||||
minetest.get_meta(pos):set_string("waiting", "true")
|
|
||||||
minetest.get_node_timer(pos):start(digtron.config.cycle_time)
|
|
||||||
minetest.sound_play("squeal", {gain=1.0, pos=pos})
|
|
||||||
minetest.sound_play("buzzer", {gain=0.5, pos=pos})
|
|
||||||
return pos, S("Digtron is obstructed.") .. "\n" .. status_text, 3 --Abort, don't dig and don't build.
|
|
||||||
end
|
|
||||||
|
|
||||||
minetest.sound_play("truck", {gain=1.0, pos=pos})
|
|
||||||
|
|
||||||
--move the array
|
|
||||||
if not layout:write_layout_image(clicker) then
|
|
||||||
return pos, "unrecoverable write_layout_image error", 1
|
|
||||||
end
|
|
||||||
|
|
||||||
pos = vector.add(pos, dir)
|
|
||||||
if move_player then
|
|
||||||
clicker:moveto(vector.add(clicker:getpos(), dir), true)
|
|
||||||
end
|
|
||||||
return pos, "", 0
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Simplified version of the dig cycle that moves laterally relative to the controller's orientation ("downward")
|
|
||||||
-- Does the dig portion of the cycle, but skips the build portion.
|
|
||||||
-- returns newpos, status string, and a return code indicating why the method returned (so the auto-controller can keep trying if it's due to unloaded nodes)
|
|
||||||
-- 0 - success
|
|
||||||
-- 1 - failed due to unloaded nodes
|
|
||||||
-- 2 - failed due to insufficient traction
|
|
||||||
-- 3 - obstructed by undiggable node
|
|
||||||
-- 4 - insufficient fuel
|
|
||||||
digtron.execute_downward_dig_cycle = function(pos, clicker)
|
|
||||||
local meta = minetest.get_meta(pos)
|
|
||||||
local facing = minetest.get_node(pos).param2
|
|
||||||
local dir = digtron.facedir_to_down_dir(facing)
|
|
||||||
local fuel_burning = meta:get_float("fuel_burning") -- get amount of burned fuel left over from last cycle
|
|
||||||
local status_text = S("Heat remaining in controller furnace: @1", math.floor(math.max(0, fuel_burning)))
|
|
||||||
local exhaust = meta:get_int("on_coal")
|
|
||||||
|
|
||||||
local layout = DigtronLayout.create(pos, clicker)
|
|
||||||
|
|
||||||
local status_text, return_code = neighbour_test(layout, status_text, dir)
|
|
||||||
if return_code ~= 0 then
|
|
||||||
return pos, status_text, return_code
|
|
||||||
end
|
|
||||||
|
|
||||||
local size_check_error = check_digtron_size(layout)
|
|
||||||
if size_check_error then
|
|
||||||
return pos, size_check_error, 8
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
local controlling_coordinate = digtron.get_controlling_coordinate(pos, facing)
|
|
||||||
|
|
||||||
----------------------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
local items_dropped = {}
|
|
||||||
local digging_fuel_cost = 0
|
|
||||||
local particle_systems = {}
|
|
||||||
|
|
||||||
-- execute the execute_dig method on all digtron components that have one
|
|
||||||
-- This builds a set of nodes that will be dug and returns a list of products that will be generated
|
|
||||||
-- but doesn't actually dig the nodes yet. That comes later.
|
|
||||||
-- If we dug them now, sand would fall and some digtron nodes would die.
|
|
||||||
if layout.diggers ~= nil then
|
|
||||||
for k, location in pairs(layout.diggers) do
|
|
||||||
local target = minetest.get_node(location.pos)
|
|
||||||
local targetdef = minetest.registered_nodes[target.name]
|
|
||||||
if targetdef.execute_dig ~= nil then
|
|
||||||
local fuel_cost, dropped = targetdef.execute_dig(location.pos, layout.protected, layout.nodes_dug, controlling_coordinate, true, clicker)
|
|
||||||
if dropped ~= nil then
|
|
||||||
for _, itemname in pairs(dropped) do
|
|
||||||
table.insert(items_dropped, itemname)
|
|
||||||
end
|
|
||||||
if digtron.config.particle_effects then
|
|
||||||
table.insert(particle_systems, dig_dust(vector.add(location.pos, dir), target.param2))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
digging_fuel_cost = digging_fuel_cost + fuel_cost
|
|
||||||
else
|
|
||||||
minetest.log(string.format("%s has digger group but is missing execute_dig method! This is an error in mod programming, file a bug.", targetdef.name))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
----------------------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
-- test if any digtrons are obstructed by non-digtron nodes that haven't been marked
|
|
||||||
-- as having been dug.
|
|
||||||
local can_move = true
|
|
||||||
for _, location in pairs(layout.all) do
|
|
||||||
local newpos = vector.add(location.pos, dir)
|
|
||||||
if not digtron.can_move_to(newpos, layout.protected, layout.nodes_dug) then
|
|
||||||
can_move = false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if test_stop_block(pos, items_dropped) then
|
|
||||||
can_move = false
|
|
||||||
end
|
|
||||||
|
|
||||||
if not can_move then
|
|
||||||
-- mark this node as waiting, will clear this flag in digtron.config.cycle_time seconds
|
|
||||||
minetest.get_meta(pos):set_string("waiting", "true")
|
|
||||||
minetest.get_node_timer(pos):start(digtron.config.cycle_time)
|
|
||||||
minetest.sound_play("squeal", {gain=1.0, pos=pos})
|
|
||||||
minetest.sound_play("buzzer", {gain=0.5, pos=pos})
|
|
||||||
return pos, S("Digtron is obstructed.") .. "\n" .. status_text, 3 --Abort, don't dig and don't build.
|
|
||||||
end
|
|
||||||
|
|
||||||
----------------------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
-- All tests passed, ready to go for real!
|
|
||||||
minetest.sound_play("construction", {gain=1.0, pos=pos})
|
|
||||||
|
|
||||||
-- if the player is standing within the array or next to it, move him too.
|
|
||||||
local move_player = move_player_test(layout, clicker)
|
|
||||||
|
|
||||||
-- damage the weak flesh
|
|
||||||
if digtron.config.damage_hp > 0 and layout.diggers ~= nil then
|
|
||||||
for k, location in pairs(layout.diggers) do
|
|
||||||
local target = minetest.get_node(location.pos)
|
|
||||||
local targetdef = minetest.registered_nodes[target.name]
|
|
||||||
if targetdef.damage_creatures ~= nil then
|
|
||||||
targetdef.damage_creatures(clicker, location.pos, controlling_coordinate, items_dropped)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
--move the array
|
|
||||||
layout:move_layout_image(digtron.facedir_to_down_dir(facing))
|
|
||||||
if not layout:write_layout_image(clicker) then
|
|
||||||
return pos, "unrecoverable write_layout_image error", 1
|
|
||||||
end
|
|
||||||
local oldpos = {x=pos.x, y=pos.y, z=pos.z}
|
|
||||||
pos = vector.add(pos, dir)
|
|
||||||
meta = minetest.get_meta(pos)
|
|
||||||
if move_player then
|
|
||||||
clicker:moveto(vector.add(clicker:getpos(), dir), true)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- store or drop the products of the digger heads
|
|
||||||
for _, itemname in pairs(items_dropped) do
|
|
||||||
digtron.place_in_inventory(itemname, layout.inventories, oldpos)
|
|
||||||
end
|
|
||||||
digtron.award_item_dug(items_dropped, clicker) -- Achievements mod hook
|
|
||||||
|
|
||||||
local status_text = ""
|
|
||||||
|
|
||||||
-- actually burn the fuel needed
|
|
||||||
fuel_burning = fuel_burning - digging_fuel_cost
|
|
||||||
if digtron.config.particle_effects and exhaust == 1 then
|
|
||||||
table.insert(particle_systems, burn_smoke(pos, digging_fuel_cost))
|
|
||||||
end
|
|
||||||
if fuel_burning < 0 then
|
|
||||||
-- we tap into the batteries either way
|
|
||||||
fuel_burning = fuel_burning + digtron.tap_batteries(layout.battery_holders, -fuel_burning, false)
|
|
||||||
if exhaust == 1 then
|
|
||||||
-- but we burn coal only if we must (exhaust = flag)
|
|
||||||
fuel_burning = fuel_burning + digtron.burn(layout.fuelstores, -fuel_burning, false)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
meta:set_float("fuel_burning", fuel_burning)
|
|
||||||
meta:set_int("on_coal", exhaust)
|
|
||||||
status_text = status_text .. S("Heat remaining in controller furnace: @1", math.floor(math.max(0, fuel_burning)))
|
|
||||||
|
|
||||||
-- Eyecandy
|
|
||||||
for _, particles in pairs(particle_systems) do
|
|
||||||
minetest.add_particlespawner(particles)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- finally, dig out any nodes remaining to be dug. Some of these will have had their flag revoked because
|
|
||||||
-- a builder put something there or because they're another digtron node.
|
|
||||||
local node_to_dig, whether_to_dig = layout.nodes_dug:pop()
|
|
||||||
while node_to_dig ~= nil do
|
|
||||||
if whether_to_dig == true then
|
|
||||||
minetest.log("action", string.format("%s uses Digtron to dig %s at (%d, %d, %d)", clicker:get_player_name(), minetest.get_node(node_to_dig).name, node_to_dig.x, node_to_dig.y, node_to_dig.z))
|
|
||||||
minetest.remove_node(node_to_dig)
|
|
||||||
end
|
|
||||||
node_to_dig, whether_to_dig = layout.nodes_dug:pop()
|
|
||||||
end
|
|
||||||
return pos, status_text, 0
|
|
||||||
end
|
|
@ -1,181 +0,0 @@
|
|||||||
-- The default minetest.item_place_node from item.lua was hard to work with given some of the details
|
|
||||||
-- of how it handled pointed_thing. It also didn't work right with default:torch and seeds. It was simpler to
|
|
||||||
-- just copy it here and chop out the special cases that were causing problems, and add some special handling.
|
|
||||||
-- for nodes that define on_place
|
|
||||||
|
|
||||||
-- This specific file is therefore licensed under the LGPL 2.1
|
|
||||||
|
|
||||||
--GNU Lesser General Public License, version 2.1
|
|
||||||
--Copyright (C) 2011-2016 celeron55, Perttu Ahola <celeron55@gmail.com>
|
|
||||||
--Copyright (C) 2011-2016 Various Minetest developers and contributors
|
|
||||||
|
|
||||||
--This program is free software; you can redistribute it and/or modify it under the terms
|
|
||||||
--of the GNU Lesser General Public License as published by the Free Software Foundation;
|
|
||||||
--either version 2.1 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 Lesser General Public License for more details:
|
|
||||||
--https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
|
|
||||||
|
|
||||||
-- Mapping from facedir value to index in facedir_to_dir.
|
|
||||||
digtron.facedir_to_dir_map = {
|
|
||||||
[0]=1, 2, 3, 4,
|
|
||||||
5, 2, 6, 4,
|
|
||||||
6, 2, 5, 4,
|
|
||||||
1, 5, 3, 6,
|
|
||||||
1, 6, 3, 5,
|
|
||||||
1, 4, 3, 2,
|
|
||||||
}
|
|
||||||
|
|
||||||
local function has_prefix(str, prefix)
|
|
||||||
return str:sub(1, string.len(prefix)) == prefix
|
|
||||||
end
|
|
||||||
|
|
||||||
digtron.whitelisted_on_place = function (item_name)
|
|
||||||
for listed_item, value in pairs(digtron.builder_on_place_items) do
|
|
||||||
if item_name == listed_item then return value end
|
|
||||||
end
|
|
||||||
|
|
||||||
for prefix, value in pairs(digtron.builder_on_place_prefixes) do
|
|
||||||
if has_prefix(item_name, prefix) then return value end
|
|
||||||
end
|
|
||||||
|
|
||||||
if minetest.get_item_group(item_name, "digtron_on_place") > 0 then return true end
|
|
||||||
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
local function copy_pointed_thing(pointed_thing)
|
|
||||||
return {
|
|
||||||
type = pointed_thing.type,
|
|
||||||
above = vector.new(pointed_thing.above),
|
|
||||||
under = vector.new(pointed_thing.under),
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
local function check_attached_node(p, n)
|
|
||||||
local def = minetest.registered_nodes[n.name]
|
|
||||||
local d = {x = 0, y = 0, z = 0}
|
|
||||||
if def.paramtype2 == "wallmounted" then
|
|
||||||
-- The fallback vector here is in case 'wallmounted to dir' is nil due
|
|
||||||
-- to voxelmanip placing a wallmounted node without resetting a
|
|
||||||
-- pre-existing param2 value that is out-of-range for wallmounted.
|
|
||||||
-- The fallback vector corresponds to param2 = 0.
|
|
||||||
d = minetest.wallmounted_to_dir(n.param2) or {x = 0, y = 1, z = 0}
|
|
||||||
else
|
|
||||||
d.y = -1
|
|
||||||
end
|
|
||||||
local p2 = vector.add(p, d)
|
|
||||||
local nn = minetest.get_node(p2).name
|
|
||||||
local def2 = minetest.registered_nodes[nn]
|
|
||||||
if def2 and not def2.walkable then
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
digtron.item_place_node = function(itemstack, placer, place_to, param2)
|
|
||||||
local item_name = itemstack:get_name()
|
|
||||||
local def = itemstack:get_definition()
|
|
||||||
if (not def) or (param2 < 0) or (def.paramtype2 == "wallmounted" and param2 > 5) or (param2 > 23) then -- validate parameters
|
|
||||||
return itemstack, false
|
|
||||||
end
|
|
||||||
|
|
||||||
local pointed_thing = {}
|
|
||||||
pointed_thing.type = "node"
|
|
||||||
pointed_thing.above = {x=place_to.x, y=place_to.y, z=place_to.z}
|
|
||||||
pointed_thing.under = {x=place_to.x, y=place_to.y - 1, z=place_to.z}
|
|
||||||
|
|
||||||
-- Handle node-specific on_place calls as best we can.
|
|
||||||
if def.on_place and def.on_place ~= minetest.nodedef_default.on_place and digtron.whitelisted_on_place(item_name) then
|
|
||||||
if def.paramtype2 == "facedir" then
|
|
||||||
pointed_thing.under = vector.add(place_to, minetest.facedir_to_dir(param2))
|
|
||||||
elseif def.paramtype2 == "wallmounted" then
|
|
||||||
pointed_thing.under = vector.add(place_to, minetest.wallmounted_to_dir(param2))
|
|
||||||
end
|
|
||||||
|
|
||||||
-- pass a copy of the item stack parameter because on_place might modify it directly and then we can't tell if we succeeded or not
|
|
||||||
-- though note that some mods do "creative_mode" handling within their own on_place methods, which makes it impossible for Digtron
|
|
||||||
-- to know what to do in that case - if you're in creative_mode Digtron will place such items but it will think it failed and not
|
|
||||||
-- deduct them from inventory no matter what Digtron's settings are. Unfortunate, but not very harmful and I have no workaround.
|
|
||||||
local returnstack, success = def.on_place(ItemStack(itemstack), placer, pointed_thing)
|
|
||||||
if returnstack and returnstack:get_count() < itemstack:get_count() then success = true end -- some mods neglect to return a success condition
|
|
||||||
if success then
|
|
||||||
-- Override the param2 value to force it to be what Digtron wants
|
|
||||||
local placed_node = minetest.get_node(place_to)
|
|
||||||
placed_node.param2 = param2
|
|
||||||
minetest.set_node(place_to, placed_node)
|
|
||||||
end
|
|
||||||
|
|
||||||
return returnstack, success
|
|
||||||
end
|
|
||||||
|
|
||||||
if minetest.registered_nodes[item_name] == nil then
|
|
||||||
-- Permitted craft items are handled by the node-specific on_place call, above.
|
|
||||||
-- if we are a craft item and we get here then we're not whitelisted and we should fail.
|
|
||||||
-- Note that builder settings should be filtering out craft items like this before we get here,
|
|
||||||
-- but this will protect us just in case.
|
|
||||||
return itemstack, false
|
|
||||||
end
|
|
||||||
|
|
||||||
local oldnode = minetest.get_node_or_nil(place_to)
|
|
||||||
|
|
||||||
--this should never happen, digtron is testing for adjacent unloaded nodes before getting here.
|
|
||||||
if not oldnode then
|
|
||||||
minetest.log("info", placer:get_player_name() .. " tried to place"
|
|
||||||
.. " node in unloaded position " .. minetest.pos_to_string(place_to)
|
|
||||||
.. " using a digtron.")
|
|
||||||
return itemstack, false
|
|
||||||
end
|
|
||||||
|
|
||||||
local newnode = {name = def.name, param1 = 0, param2 = param2}
|
|
||||||
if def.place_param2 ~= nil then
|
|
||||||
newnode.param2 = def.place_param2
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Check if the node is attached and if it can be placed there
|
|
||||||
if minetest.get_item_group(def.name, "attached_node") ~= 0 and
|
|
||||||
not check_attached_node(place_to, newnode) then
|
|
||||||
minetest.log("action", "attached node " .. def.name ..
|
|
||||||
" can not be placed at " .. minetest.pos_to_string(place_to))
|
|
||||||
return itemstack, false
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Add node and update
|
|
||||||
minetest.add_node(place_to, newnode)
|
|
||||||
|
|
||||||
local take_item = true
|
|
||||||
|
|
||||||
-- Run callback, using genuine player for per-node definition.
|
|
||||||
if def.after_place_node then
|
|
||||||
-- Deepcopy place_to and pointed_thing because callback can modify it
|
|
||||||
local place_to_copy = {x=place_to.x, y=place_to.y, z=place_to.z}
|
|
||||||
local pointed_thing_copy = copy_pointed_thing(pointed_thing)
|
|
||||||
if def.after_place_node(place_to_copy, placer, itemstack,
|
|
||||||
pointed_thing_copy) then
|
|
||||||
take_item = false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Run script hook, using fake_player to take the blame.
|
|
||||||
-- Note that fake_player:update is called in the DigtronLayout class's "create" function,
|
|
||||||
-- which is called before Digtron does any of this building stuff, so it's not necessary
|
|
||||||
-- to update it here.
|
|
||||||
local _, callback
|
|
||||||
for _, callback in ipairs(minetest.registered_on_placenodes) do
|
|
||||||
-- Deepcopy pos, node and pointed_thing because callback can modify them
|
|
||||||
local place_to_copy = {x=place_to.x, y=place_to.y, z=place_to.z}
|
|
||||||
local newnode_copy = {name=newnode.name, param1=newnode.param1, param2=newnode.param2}
|
|
||||||
local oldnode_copy = {name=oldnode.name, param1=oldnode.param1, param2=oldnode.param2}
|
|
||||||
local pointed_thing_copy = copy_pointed_thing(pointed_thing)
|
|
||||||
if callback(place_to_copy, newnode_copy, digtron.fake_player, oldnode_copy, itemstack, pointed_thing_copy) then
|
|
||||||
take_item = false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if take_item then
|
|
||||||
itemstack:take_item()
|
|
||||||
end
|
|
||||||
return itemstack, true
|
|
||||||
end
|
|
Loading…
Reference in New Issue
Block a user