Initial commit

This commit is contained in:
Evert Prants 2018-06-18 10:09:43 +03:00
commit de2c0a15ea
Signed by: evert
GPG Key ID: 1688DA83D222D0B5
77 changed files with 1975 additions and 0 deletions

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright © 2018 Evert "Diamond" Prants <evert@lunasqu.ee>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the “Software”), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

27
README.md Normal file
View File

@ -0,0 +1,27 @@
# Elepower
A new *powerful* modpack for [Minetest](http://minetest.net)!
**I do not recommend using this modpack with technic or pipeworks, as this modpack aims to become the all-in-one solution. However, compatibility might be added at a later date.**
## Features
### Universal Electric Power API
How is this any different from technic I hear you asking? Well, first of all, I have eliminated the concept of "tiers" in the **technic** sense, as all types of machines will now be accepting any conduit. Machines can be upgraded for speed and efficiency.
### (Planned) Universal Fluid Transfer API
Exactly what it sounds like. Pipeworks failed to do this.
### (Planned) Universal Item Transfer API
Also exactly what it sounds like. /might/ be backwards-compatible with pipeworks, currently undecided.
### Machinery
Machines for doubling your ore output and helping you create more powerful materials.
### Tools
Powered tools that you can simply recharge instead of crafting them again.
### (Planned) Farming
Farming automation machines.
### (Planned) Nuclear
Nuclear power. Both fission and fusion will be presented!

View File

@ -0,0 +1,6 @@
ele.register_conduit("elepower_dynamics:conduit", {
description = "Power Conduit",
tiles = {"elepower_conduit.png"},
groups = {oddly_breakable_by_hand = 1, cracky = 1}
})

View File

@ -0,0 +1,110 @@
---------------
-- Overrides --
---------------
minetest.clear_craft({type = "cooking", output = "default:steel_ingot"})
-----------
-- Tools --
-----------
-- Pickaxes
minetest.register_craft({
output = 'elepower_dynamics:pick_iron',
recipe = {
{'elepower_dynamics:iron_ingot', 'elepower_dynamics:iron_ingot', 'elepower_dynamics:iron_ingot'},
{'', 'group:stick', ''},
{'', 'group:stick', ''},
}
})
minetest.register_craft({
output = 'elepower_dynamics:pick_lead',
recipe = {
{'elepower_dynamics:lead_ingot', 'elepower_dynamics:lead_ingot', 'elepower_dynamics:lead_ingot'},
{'', 'group:stick', ''},
{'', 'group:stick', ''},
}
})
-- Shovels
minetest.register_craft({
output = 'elepower_dynamics:shovel_iron',
recipe = {
{'elepower_dynamics:iron_ingot'},
{'group:stick'},
{'group:stick'},
}
})
minetest.register_craft({
output = 'elepower_dynamics:shovel_lead',
recipe = {
{'elepower_dynamics:lead_ingot'},
{'group:stick'},
{'group:stick'},
}
})
-- Axes
minetest.register_craft({
output = 'elepower_dynamics:axe_iron',
recipe = {
{'elepower_dynamics:iron_ingot', 'elepower_dynamics:iron_ingot'},
{'elepower_dynamics:iron_ingot', 'group:stick'},
{'', 'group:stick'},
}
})
minetest.register_craft({
output = 'elepower_dynamics:axe_lead',
recipe = {
{'elepower_dynamics:lead_ingot', 'elepower_dynamics:lead_ingot'},
{'elepower_dynamics:lead_ingot', 'group:stick'},
{'', 'group:stick'},
}
})
-- Swords
minetest.register_craft({
output = 'elepower_dynamics:sword_iron',
recipe = {
{'elepower_dynamics:iron_ingot'},
{'elepower_dynamics:iron_ingot'},
{'group:stick'},
}
})
minetest.register_craft({
output = 'elepower_dynamics:sword_lead',
recipe = {
{'elepower_dynamics:lead_ingot'},
{'elepower_dynamics:lead_ingot'},
{'group:stick'},
}
})
-----------
-- Items --
-----------
--------------
-- Smelting --
--------------
minetest.register_craft({
type = "cooking",
output = "elepower_dynamics:iron_ingot",
recipe = "default:iron_lump"
})
minetest.register_craft({
type = "cooking",
output = "elepower_dynamics:lead_lump",
recipe = "elepower_dynamics:lead_ingot"
})

View File

@ -0,0 +1,44 @@
----------------
-- Craftitems --
----------------
-- Ingots
minetest.register_craftitem("elepower_dynamics:lead_ingot", {
description = "Lead Ingot",
inventory_image = "elepower_lead_ingot.png",
groups = {lead = 1, ingot = 1}
})
minetest.register_craftitem("elepower_dynamics:iron_ingot", {
description = "Iron Ingot",
inventory_image = "elepower_iron_ingot.png",
groups = {iron = 1, ingot = 1}
})
-- Lumps
minetest.register_craftitem("elepower_dynamics:lead_lump", {
description = "Lead Lump",
inventory_image = "elepower_lead_lump.png",
groups = {lead = 1, lump = 1}
})
-- Other
minetest.register_craftitem("elepower_dynamics:carbon_fiber", {
description = "Carbon Fibers",
inventory_image = "elepower_carbon_fiber.png",
groups = {carbon_fiber = 1}
})
minetest.register_craftitem("elepower_dynamics:carbon_sheet", {
description = "Carbon Fiber Sheet",
inventory_image = "elepower_carbon_fiber_sheet.png",
groups = {carbon_fiber_sheet = 1, sheet = 1}
})
---------------
-- Overrides --
---------------

View File

@ -0,0 +1,82 @@
----------------------
-- Ground materials --
----------------------
elepd.registered_dusts = {}
function elepd.register_dust(mat, data)
local mod = minetest.get_current_modname()
local itemname = mod..":"..mat.."_dust"
data.item = itemname
elepd.registered_dusts[mat] = data
minetest.register_craftitem(itemname, {
description = "Pulverized " .. data.description,
inventory_image = "elepower_dust.png^[multiply:" .. data.color,
groups = {["dust_" .. mat] = 1, dust = 1}
})
end
-- Default dust list
elepd.register_dust("bronze", {
description = "Bronze",
color = "#fa7b26"
})
elepd.register_dust("copper", {
description = "Copper",
color = "#fcb15f"
})
elepd.register_dust("gold", {
description = "Gold",
color = "#ffff47"
})
elepd.register_dust("steel", {
description = "Steel",
color = "#ffffff"
})
elepd.register_dust("tin", {
description = "Tin",
color = "#c1c1c1"
})
elepd.register_dust("mithril", {
description = "Mithril",
color = "#8686df"
})
elepd.register_dust("silver", {
description = "Silver",
color = "#d7e2e8"
})
elepd.register_dust("lead", {
description = "Lead",
color = "#aeaedc"
})
elepd.register_dust("iron", {
description = "Iron",
color = "#dddddd"
})
elepd.register_dust("coal", {
description = "Coal",
color = "#222222"
})
elepd.register_dust("diamond", {
description = "Diamond",
color = "#02c1e8"
})
elepd.register_dust("energium", {
description = "Energium",
color = "#ff1111"
})

View File

@ -0,0 +1,15 @@
-- A Elepower Mod
-- Copyright 2018 Evert "Diamond" Prants <evert@lunasqu.ee>
local modpath = minetest.get_modpath(minetest.get_current_modname())
elepd = rawget(_G, "elepd") or {}
elepd.modpath = modpath
dofile(modpath.."/conduits.lua")
dofile(modpath.."/craftitems.lua")
dofile(modpath.."/tools.lua")
dofile(modpath.."/nodes.lua")
dofile(modpath.."/dusts.lua")
dofile(modpath.."/worldgen.lua")
dofile(modpath.."/crafting.lua")

View File

@ -0,0 +1,4 @@
name = elepower_dynamics
description = Elepower Dynamics. Conduits and materials!
depends = elepower_papi,default
optional_depends = moreores

View File

@ -0,0 +1,16 @@
---------------
-- Overrides --
---------------
-----------
-- Nodes --
-----------
minetest.register_node("elepower_dynamics:stone_with_lead", {
description = "Lead Ore",
tiles = {"default_stone.png^elepower_mineral_lead.png"},
groups = {cracky = 2},
drop = 'elepower_dynamics:lead_lump',
sounds = default.node_sound_stone_defaults(),
})

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 329 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 490 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 406 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 410 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

122
elepower_dynamics/tools.lua Normal file
View File

@ -0,0 +1,122 @@
-- Pickaxes
minetest.register_tool("elepower_dynamics:pick_iron", {
description = "Iron Pickaxe",
inventory_image = "elepower_tool_ironpick.png",
tool_capabilities = {
full_punch_interval = 1.0,
max_drop_level=1,
groupcaps={
cracky = {times={[1]=3.90, [2]=1.50, [3]=0.60}, uses=20, maxlevel=2},
},
damage_groups = {fleshy=4},
},
sound = {breaks = "default_tool_breaks"},
})
minetest.register_tool("elepower_dynamics:pick_lead", {
description = "Lead Pickaxe",
inventory_image = "elepower_tool_leadpick.png",
tool_capabilities = {
full_punch_interval = 0.8,
max_drop_level=1,
groupcaps={
cracky = {times={[1]=3.90, [2]=1.60, [3]=0.50}, uses=20, maxlevel=2},
},
damage_groups = {fleshy=5},
},
sound = {breaks = "default_tool_breaks"},
})
-- Shovels
minetest.register_tool("elepower_dynamics:shovel_iron", {
description = "Iron Shovel",
inventory_image = "elepower_tool_ironshovel.png",
wield_image = "elepower_tool_ironshovel.png^[transformR90",
tool_capabilities = {
full_punch_interval = 1.1,
max_drop_level=1,
groupcaps={
crumbly = {times={[1]=1.40, [2]=0.80, [3]=0.20}, uses=30, maxlevel=2},
},
damage_groups = {fleshy=3},
},
sound = {breaks = "default_tool_breaks"},
})
minetest.register_tool("elepower_dynamics:shovel_lead", {
description = "Lead Shovel",
inventory_image = "elepower_tool_leadshovel.png",
wield_image = "elepower_tool_leadshovel.png^[transformR90",
tool_capabilities = {
full_punch_interval = 1.0,
max_drop_level=1,
groupcaps={
crumbly = {times={[1]=1.50, [2]=0.50, [3]=0.10}, uses=30, maxlevel=2},
},
damage_groups = {fleshy=4},
},
sound = {breaks = "default_tool_breaks"},
})
-- Axes
minetest.register_tool("elepower_dynamics:axe_iron", {
description = "Iron Axe",
inventory_image = "elepower_tool_ironaxe.png",
tool_capabilities = {
full_punch_interval = 1.0,
max_drop_level=1,
groupcaps={
choppy={times={[1]=2.40, [2]=1.30, [3]=0.80}, uses=20, maxlevel=2},
},
damage_groups = {fleshy=4},
},
sound = {breaks = "default_tool_breaks"},
})
minetest.register_tool("elepower_dynamics:axe_lead", {
description = "Lead Axe",
inventory_image = "elepower_tool_leadaxe.png",
tool_capabilities = {
full_punch_interval = 0.9,
max_drop_level=1,
groupcaps={
choppy={times={[1]=2.40, [2]=1.20, [3]=0.70}, uses=20, maxlevel=2},
},
damage_groups = {fleshy=5},
},
sound = {breaks = "default_tool_breaks"},
})
-- Swords
minetest.register_tool("elepower_dynamics:sword_iron", {
description = "Iron Sword",
inventory_image = "elepower_tool_ironsword.png",
tool_capabilities = {
full_punch_interval = 0.8,
max_drop_level=1,
groupcaps={
snappy={times={[1]=2.4, [2]=1.10, [3]=0.2}, uses=30, maxlevel=2},
},
damage_groups = {fleshy=5},
},
sound = {breaks = "default_tool_breaks"},
})
minetest.register_tool("elepower_dynamics:sword_lead", {
description = "Lead Sword",
inventory_image = "elepower_tool_leadsword.png",
tool_capabilities = {
full_punch_interval = 0.7,
max_drop_level=1,
groupcaps={
snappy={times={[1]=2.2, [2]=1.00, [3]=0.1}, uses=30, maxlevel=2},
},
damage_groups = {fleshy=7},
},
sound = {breaks = "default_tool_breaks"},
})

View File

@ -0,0 +1,39 @@
--------------
-- Worldgen --
--------------
-- Lead
minetest.register_ore({
ore_type = "scatter",
ore = "elepower_dynamics:stone_with_lead",
wherein = "default:stone",
clust_scarcity = 9 * 9 * 9,
clust_num_ores = 12,
clust_size = 3,
y_max = 31000,
y_min = 1025,
})
minetest.register_ore({
ore_type = "scatter",
ore = "elepower_dynamics:stone_with_lead",
wherein = "default:stone",
clust_scarcity = 7 * 7 * 7,
clust_num_ores = 5,
clust_size = 3,
y_max = 0,
y_min = -31000,
})
minetest.register_ore({
ore_type = "scatter",
ore = "elepower_dynamics:stone_with_lead",
wherein = "default:stone",
clust_scarcity = 18 * 18 * 18,
clust_num_ores = 5,
clust_size = 3,
y_max = -128,
y_min = -31000,
})

View File

@ -0,0 +1,8 @@
-- A Elepower Mod
-- Copyright 2018 Evert "Diamond" Prants <evert@lunasqu.ee>
local modpath = minetest.get_modpath(minetest.get_current_modname())
elefarm = rawget(_G, "elefarm") or {}
elefarm.modpath = modpath

View File

@ -0,0 +1,3 @@
name = elepower_farming
description = Electric Farming Automation!
depends = elepower_papi, elepower_tools

View File

@ -0,0 +1,128 @@
-- This is a crafter type machine base.
-- It accepts a recipe type registered beforehand.
function elepm.register_crafter(nodename, nodedef)
local craft_type = nodedef.craft_type
if not craft_type or not elepm.craft.types[craft_type] then
return nil
end
if not nodedef.groups then
nodedef.groups = {}
end
nodedef.groups["ele_machine"] = 1
nodedef.groups["ele_user"] = 1
nodedef.on_timer = function (pos, elapsed)
local refresh = false
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local machine_node = nodename
local machine_speed = nodedef.craft_speed or 1
local capacity = ele.helpers.get_node_property(meta, pos, "capacity")
while true do
local result = elepm.get_recipe(craft_type, inv:get_list("src"))
local usage = ele.helpers.get_node_property(meta, pos, "usage")
local storage = ele.helpers.get_node_property(meta, pos, "storage")
local pow_percent = math.floor((storage / capacity) * 100)
local power_operation = false
-- Determine if there is enough power for this action
if result and storage >= usage then
power_operation = true
end
if not result or not power_operation then
ele.helpers.swap_node(pos, machine_node)
if not result then
meta:set_string("formspec", ele.formspec.get_crafter_formspec(craft_type, pow_percent))
meta:set_int("src_time", 0)
meta:set_string("infotext", ("%s Idle"):format(nodedef.description))
else
local pct = math.floor((ele.helpers.round(result.time * 10) / meta:get_int("src_time")) * 100)
meta:set_string("formspec", ele.formspec.get_crafter_formspec(craft_type, pow_percent, pct))
meta:set_string("infotext", ("%s Out of Power!"):format(nodedef.description))
end
break
end
refresh = true
-- One step
meta:set_int("storage", storage - usage)
pow_percent = math.floor((storage / capacity) * 100)
meta:set_int("src_time", meta:get_int("src_time") + ele.helpers.round(machine_speed * 10))
meta:set_string("infotext", ("%s Active"):format(nodedef.description))
if nodedef.ele_active_node then
local active_node = nodename.."_active"
if nodedef.ele_active_node ~= true then
active_node = nodedef.ele_active_node
end
ele.helpers.swap_node(pos, active_node)
end
if meta:get_int("src_time") <= ele.helpers.round(result.time * 10) then
local pct = math.floor((meta:get_int("src_time") / ele.helpers.round(result.time * 10)) * 100)
meta:set_string("formspec", ele.formspec.get_crafter_formspec(craft_type, pow_percent, pct))
break
end
local output = result.output
if type(output) ~= "table" then output = { output } end
local output_stacks = {}
for _, o in ipairs(output) do
table.insert(output_stacks, ItemStack(o))
end
local room_for_output = true
inv:set_size("dst_tmp", inv:get_size("dst"))
inv:set_list("dst_tmp", inv:get_list("dst"))
for _, o in ipairs(output_stacks) do
if not inv:room_for_item("dst_tmp", o) then
room_for_output = false
break
end
inv:add_item("dst_tmp", o)
end
if not room_for_output then
ele.helpers.swap_node(pos, machine_node)
meta:set_string("formspec", ele.formspec.get_crafter_formspec(craft_type, pow_percent))
meta:set_int("src_time", ele.helpers.round(result.time*10))
meta:set_string("infotext", ("%s Output Full!"):format(nodedef.description))
break
end
meta:set_int("src_time", meta:get_int("src_time") - ele.helpers.round(result.time*10))
inv:set_list("src", result.new_input)
inv:set_list("dst", inv:get_list("dst_tmp"))
end
return refresh
end
local sizes = elepm.craft.types[craft_type]
nodedef.on_construct = function (pos)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
inv:set_size("src", sizes.inputs)
inv:set_size("dst", 4)
local storage = ele.helpers.get_node_property(meta, pos, "storage")
local capacity = ele.helpers.get_node_property(meta, pos, "capacity")
meta:set_string("formspec", ele.formspec.get_crafter_formspec(craft_type, capacity, storage))
end
ele.register_machine(nodename, nodedef)
end

View File

@ -0,0 +1,86 @@
function elepm.register_fuel_generator(nodename, nodedef)
if not nodedef.groups then
nodedef.groups = {}
end
nodedef.groups["ele_machine"] = 1
nodedef.groups["ele_provider"] = 1
nodedef.on_timer = function (pos, elapsed)
local meta = minetest.get_meta(pos)
local burn_time = meta:get_int("burn_time")
local burn_totaltime = meta:get_int("burn_totaltime")
local capacity = ele.helpers.get_node_property(meta, pos, "capacity")
local generation = ele.helpers.get_node_property(meta, pos, "usage")
local storage = ele.helpers.get_node_property(meta, pos, "storage")
-- If more to burn and the energy produced was used: produce some more
if burn_time > 0 then
if storage + generation > capacity then
return false
end
meta:set_int("storage", storage + generation)
burn_time = burn_time - 1
meta:set_int("burn_time", burn_time)
end
local pow_percent = math.floor((storage / capacity) * 100)
-- Burn another piece of fuel
if burn_time == 0 then
local inv = meta:get_inventory()
if not inv:is_empty("src") then
local fuellist = inv:get_list("src")
local fuel, afterfuel = minetest.get_craft_result({method = "fuel", width = 1, items = fuellist})
if not fuel or fuel.time == 0 then
ele.helpers.swap_node(pos, nodename)
return false
end
meta:set_int("burn_time", fuel.time)
meta:set_int("burn_totaltime", fuel.time)
inv:set_stack("src", 1, afterfuel.items[1])
if nodedef.ele_active_node then
local active_node = nodename.."_active"
if nodedef.ele_active_node ~= true then
active_node = nodedef.ele_active_node
end
ele.helpers.swap_node(pos, active_node)
end
else
meta:set_string("formspec", ele.formspec.get_generator_formspec(pow_percent, 0))
meta:set_string("infotext", ("%s Idle"):format(nodedef.description))
ele.helpers.swap_node(pos, nodename)
return false
end
end
if burn_totaltime == 0 then burn_totaltime = 1 end
local percent = math.floor((burn_time / burn_totaltime) * 100)
meta:set_string("formspec", ele.formspec.get_generator_formspec(pow_percent, percent))
meta:set_string("infotext", ("%s Active"):format(nodedef.description))
return true
end
nodedef.on_construct = function (pos)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
inv:set_size("src", 1)
local capacity = ele.helpers.get_node_property(meta, pos, "capacity")
local storage = ele.helpers.get_node_property(meta, pos, "storage")
meta:set_string("formspec", ele.formspec.get_generator_formspec(math.floor((storage / capacity) * 100), 0))
end
ele.register_machine(nodename, nodedef)
end

View File

@ -0,0 +1,4 @@
dofile(elepm.modpath.."/bases/crafter.lua")
dofile(elepm.modpath.."/bases/generator.lua")
dofile(elepm.modpath.."/bases/storage.lua")

View File

@ -0,0 +1,52 @@
function elepm.register_storage(nodename, nodedef)
local levels = nodedef.ele_levels or 8
local level_overlay = nodedef.ele_overlay or "elepower_power_level_"
if not nodedef.groups then
nodedef.groups = {}
end
nodedef.groups["ele_machine"] = 1
nodedef.groups["ele_storage"] = 1
nodedef.groups["ele_provider"] = 1
nodedef.on_timer = function (pos, elapsed)
local meta = minetest.get_meta(pos)
local capacity = ele.helpers.get_node_property(meta, pos, "capacity")
local storage = ele.helpers.get_node_property(meta, pos, "storage")
local percent = storage / capacity
local level = math.floor(percent * levels)
local rounded = math.floor(percent * 100)
ele.helpers.swap_node(pos, nodename .. "_" .. level)
meta:set_string("formspec", ele.formspec.get_storage_formspec(rounded))
meta:set_string("infotext", ("%s Active"):format(nodedef.description))
return false
end
nodedef.on_construct = function (pos)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
inv:set_size("src", 1)
inv:set_size("dst", 1)
meta:set_string("formspec", ele.formspec.get_storage_formspec(0))
end
for i = 0, levels do
local cpdef = ele.helpers.table_copy(nodedef)
-- Add overlay to the tile texture
if cpdef.tiles and cpdef.tiles[6] and i > 0 then
cpdef.tiles[6] = cpdef.tiles[6] .. "^" .. level_overlay .. i ..".png"
end
if i > 0 then
cpdef.groups["not_in_creative_inventory"] = 1
end
ele.register_machine(nodename .. "_" .. i, cpdef)
end
end

127
elepower_machines/craft.lua Normal file
View File

@ -0,0 +1,127 @@
elepm.craft = {}
elepm.craft.types = {}
function elepm.register_craft_type(name, def)
elepm.craft.types[name] = {
inputs = def.inputs or 2,
description = def.description or name,
time = def.time or 0
}
elepm.craft[name] = {}
end
function elepm.register_craft(craftdef)
if not craftdef.type or not elepm.craft.types[craftdef.type] then
return nil
end
local inputs = craftdef.recipe
local outputs = craftdef.output
local ctype = craftdef.type
local time = (craftdef.time or craftdef.cooktime or 5) + (elepm.craft.types[ctype].time or 0)
local craftrecipe = {}
for _,input in ipairs(inputs) do
local stack = ItemStack(input)
if stack and not stack:is_empty() then
craftrecipe[stack:get_name()] = stack:get_count()
end
end
local craftresult = {}
if type(outputs) == "table" then
for _,output in ipairs(output) do
local stack = ItemStack(output)
if stack and not stack:is_empty() then
craftresult[stack:get_name()] = stack:get_count()
end
end
else
craftresult = ItemStack(outputs)
end
local recipe = {
recipe = craftrecipe,
output = craftresult,
time = time
}
table.insert(elepm.craft[ctype], recipe)
end
function elepm.get_recipe(type, inputs)
if not elepm.craft[type] then
return nil
end
-- Minetest's cooking builtin type
if type == "cooking" then
local result, new_input = minetest.get_craft_result({
method = "cooking",
width = 1,
items = inputs
})
if not result or result.time == 0 then
return nil
else
return {
time = result.time,
new_input = new_input.items,
output = result.item
}
end
end
-- Custom types
local result = nil
for _,recipe in ipairs(elepm.craft[type]) do
local recip_match = true
local inputs_full = {}
local new_input = {}
for _,input in ipairs(inputs) do
local in_name = input:get_name()
if not recipe.recipe[in_name] then
recip_match = false
elseif recipe.recipe[in_name] > input:get_count() then
recip_match = false
end
if not recip_match then break end
table.insert(inputs_full, in_name)
local istack = ItemStack(in_name)
istack:set_count(input:get_count() - recipe.recipe[in_name])
new_input[#new_input + 1] = istack
end
if recip_match then
for _,ingredient in ipairs(recipe.recipe) do
local its = ItemStack(ingredient)
if not inputs_full[its:get_name()] then
recip_match = false
break
end
end
end
if recip_match then
result = recipe
result.new_input = new_input
break
end
end
return result
end
-- Cooking craft type built-in.
elepm.register_craft_type("cooking", {
description = "Cooking",
inputs = 1,
})

View File

@ -0,0 +1,65 @@
-- Specialized formspec for crafters
function ele.formspec.get_crafter_formspec(craft_type, power, percent)
local craftstats = elepm.craft.types[craft_type]
local input_size = craftstats.inputs
local bar = "image[4,1.5;1,1;gui_furnace_arrow_bg.png^[transformR270]"
if percent ~= nil then
bar = "image[4,1.5;1,1;gui_furnace_arrow_bg.png^[lowpart:"..
(percent)..":gui_furnace_arrow_fg.png^[transformR270]"
end
return "size[8,8.5]"..
default.gui_bg..
default.gui_bg_img..
default.gui_slots..
ele.formspec.power_meter(power)..
"list[context;src;1.5,1.5;"..input_size..",1;]"..
bar..
"list[context;dst;5,1;2,2;]"..
"list[current_player;main;0,4.25;8,1;]"..
"list[current_player;main;0,5.5;8,3;8]"..
"listring[current_player;main]"..
"listring[context;src]"..
"listring[current_player;main]"..
"listring[context;dst]"..
"listring[current_player;main]"..
default.get_hotbar_bg(0, 4.25)
end
function ele.formspec.get_generator_formspec(power, percent)
return "size[8,8.5]"..
default.gui_bg..
default.gui_bg_img..
default.gui_slots..
ele.formspec.power_meter(power)..
"list[context;src;3,1.5;1,1;]"..
"image[4,1.5;1,1;default_furnace_fire_bg.png^[lowpart:"..
percent..":default_furnace_fire_fg.png]"..
"list[current_player;main;0,4.25;8,1;]"..
"list[current_player;main;0,5.5;8,3;8]"..
"listring[current_player;main]"..
"listring[context;src]"..
"listring[current_player;main]"..
default.get_hotbar_bg(0, 4.25)
end
function ele.formspec.get_storage_formspec(power)
return "size[8,8.5]"..
default.gui_bg..
default.gui_bg_img..
default.gui_slots..
ele.formspec.power_meter(power)..
"list[context;src;2,1.5;1,1;]"..
"list[context;dst;5,1.5;1,1;]"..
"list[current_player;main;0,4.25;8,1;]"..
"list[current_player;main;0,5.5;8,3;8]"..
"listring[current_player;main]"..
"listring[context;src]"..
"listring[current_player;main]"..
"listring[context;dst]"..
"listring[current_player;main]"..
default.get_hotbar_bg(0, 4.25)
end

View File

@ -0,0 +1,13 @@
-- Elepower Mod
-- Copyright 2018 Evert "Diamond" Prants <evert@lunasqu.ee>
local modpath = minetest.get_modpath(minetest.get_current_modname())
elepm = rawget(_G, "elepm") or {}
elepm.modpath = modpath
dofile(modpath.."/craft.lua")
dofile(modpath.."/formspec.lua")
dofile(modpath.."/bases/init.lua")
dofile(modpath.."/nodes.lua")
dofile(modpath.."/register.lua")

View File

@ -0,0 +1,3 @@
name = elepower_machines
description = Elepower machinery!
depends = elepower_dynamics

View File

@ -0,0 +1,8 @@
-- Nodes other than machines.
-- Machines are registered in `register.lua`!
minetest.register_node("elepower_machines:machine_block", {
description = "Machine Block",
tiles = {"elepower_machine_top.png", "elepower_machine_base.png", "elepower_machine_side.png"},
groups = {oddly_breakable_by_hand = 1, cracky = 1},
})

View File

@ -0,0 +1,162 @@
--------------
-- Alloying --
--------------
elepm.register_craft_type("alloy", {
description = "Alloying",
inputs = 2,
})
elepm.register_craft({
type = "alloy",
recipe = { "elepower_dynamics:iron_ingot", "elepower_dynamics:coal_dust 4" },
output = "default:steel_ingot",
time = 6,
})
elepm.register_crafter("elepower_machines:alloy_furnace", {
description = "Alloy Furnace",
craft_type = "alloy",
ele_active_node = true,
tiles = {
"elepower_machine_top.png", "elepower_machine_base.png", "elepower_machine_side.png",
"elepower_machine_side.png", "elepower_machine_side.png", "elepower_alloy_furnace.png",
},
ele_active_nodedef = {
tiles = {
"elepower_machine_top.png", "elepower_machine_base.png", "elepower_machine_side.png",
"elepower_machine_side.png", "elepower_machine_side.png", "elepower_alloy_furnace_active.png",
},
},
groups = {oddly_breakable_by_hand = 1}
})
--------------
-- Grinding --
--------------
elepm.register_craft_type("grind", {
description = "Grinding",
inputs = 1,
})
-- Look for item name regardless of mod
local function scan_item_list(item_name)
local found = nil
for name in pairs(minetest.registered_items) do
local nomod = name:gsub("(%w+):", "")
if nomod == item_name then
found = name
break
end
end
return found
end
local keywords = { _ingot = 1, _lump = 2, _block = 9, block = 9 }
for mat, data in pairs(elepd.registered_dusts) do
local kwfound = nil
for keyword,count in pairs(keywords) do
local found = scan_item_list(mat .. keyword)
if found then
if keyword == "_ingot" and not kwfound then
kwfound = found
end
-- Grind recipe for material
elepm.register_craft({
type = "grind",
recipe = { found },
output = data.item .. " " .. count,
time = count + 4,
})
end
end
-- Add dust -> ingot smelting
if kwfound then
minetest.register_craft({
type = "cooking",
recipe = data.item,
output = kwfound
})
end
end
elepm.register_crafter("elepower_machines:pulverizer", {
description = "Pulverizer",
craft_type = "grind",
ele_active_node = true,
ele_usage = 32,
tiles = {
"elepower_machine_top.png", "elepower_machine_base.png", "elepower_machine_side.png",
"elepower_machine_side.png", "elepower_machine_side.png", "elepower_grinder.png",
},
ele_active_nodedef = {
tiles = {
"elepower_machine_top.png", "elepower_machine_base.png", "elepower_machine_side.png",
"elepower_machine_side.png", "elepower_machine_side.png", "elepower_grinder_active.png",
},
},
groups = {oddly_breakable_by_hand = 1}
})
-------------
-- Furnace --
-------------
elepm.register_crafter("elepower_machines:furnace", {
description = "Powered Furnace",
craft_type = "cooking",
ele_active_node = true,
ele_usage = 32,
tiles = {
"elepower_machine_top.png", "elepower_machine_base.png", "elepower_machine_side.png",
"elepower_machine_side.png", "elepower_machine_side.png", "elepower_furnace.png",
},
ele_active_nodedef = {
tiles = {
"elepower_machine_top.png", "elepower_machine_base.png", "elepower_machine_side.png",
"elepower_machine_side.png", "elepower_machine_side.png", "elepower_furnace_active.png",
},
},
groups = {oddly_breakable_by_hand = 1}
})
----------------------
-- Power Generation --
----------------------
elepm.register_fuel_generator("elepower_machines:generator", {
description = "Coal-fired Generator",
ele_active_node = true,
ele_capacity = 6400,
tiles = {
"elepower_machine_top.png", "elepower_machine_base.png", "elepower_machine_side.png",
"elepower_machine_side.png", "elepower_machine_side.png", "elepower_generator.png",
},
ele_active_nodedef = {
tiles = {
"elepower_machine_top.png", "elepower_machine_base.png", "elepower_machine_side.png",
"elepower_machine_side.png", "elepower_machine_side.png", "elepower_generator_active.png",
}
},
groups = {oddly_breakable_by_hand = 1}
})
-------------------
-- Power Storage --
-------------------
elepm.register_storage("elepower_machines:power_cell", {
description = "Power Cell",
ele_capacity = 16000,
tiles = {
"elepower_machine_top.png", "elepower_machine_base.png", "elepower_machine_side.png",
"elepower_machine_side.png", "elepower_machine_side.png", "elepower_power_cell.png",
},
groups = {oddly_breakable_by_hand = 1}
})

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 201 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 489 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

View File

@ -0,0 +1,7 @@
-- A Elepower Mod
-- Copyright 2018 Evert "Diamond" Prants <evert@lunasqu.ee>
local modpath = minetest.get_modpath(minetest.get_current_modname())
elenuclear = rawget(_G, "elenuclear") or {}
elenuclear.modpath = modpath

View File

@ -0,0 +1,3 @@
name = elepower_nuclear
description = Atomic Science!
depends = elepower_machines

View File

@ -0,0 +1,62 @@
function ele.register_conduit(nodename, nodedef)
if not nodedef.groups then
nodedef.groups = {}
end
-- Ensure this node is in the conductor group
if not nodedef.groups["ele_conductor"] then
nodedef.groups["ele_conductor"] = 1
end
-- Cable node density
local cd = 1/8
if nodedef.ele_conductor_density then
cd = nodedef.ele_conductor_density
end
-- Default values, including the nodebox
local defaults = {
drawtype = "nodebox",
node_box = {
type = "connected",
fixed = {
{-cd, -cd, -cd, cd, cd, cd}
},
connect_front = {
{-cd, -cd, -1/2, cd, cd, -cd}
},
connect_back = {
{-cd, -cd, cd, cd, cd, 1/2}
},
connect_top = {
{-cd, cd, -cd, cd, 1/2, cd}
},
connect_bottom = {
{-cd, -1/2, -cd, cd, -cd, cd}
},
connect_left = {
{-1/2, -cd, -cd, cd, cd, cd}
},
connect_right = {
{cd, -cd, -cd, 1/2, cd, cd}
},
},
paramtype = "light",
connect_sides = { "top", "bottom", "front", "left", "back", "right" },
is_ground_content = false,
connects_to = {
"group:ele_machine",
"group:ele_conductor",
},
}
for k,v in pairs(defaults) do
if not nodedef[k] then
nodedef[k] = v
end
end
ele.register_base_device(nodename, nodedef)
end

View File

@ -0,0 +1,9 @@
-- Formspec helper: Add power bar
ele.formspec = {}
function ele.formspec.power_meter(pw_percent)
return "image[0,0;1,2.8;elepower_gui_barbg.png"..
"^[lowpart:"..pw_percent..":elepower_gui_bar.png]"..
"image[0,0;1,2.8;elepower_gui_gauge.png]"
end

74
elepower_papi/helpers.lua Normal file
View File

@ -0,0 +1,74 @@
-----------------------
-- Utility Functions --
-----------------------
ele.helpers = {}
function ele.helpers.table_copy(tab)
local retval = {}
for k, v in pairs(tab) do
if type(v) == "table" then
retval[k] = ele.helpers.table_copy(v)
else
retval[k] = v
end
end
return retval
end
function ele.helpers.round(v)
return math.floor(v + 0.5)
end
function ele.helpers.swap_node(pos, noded)
local node = minetest.get_node(pos)
if type(noded) ~= "table" then
local n = ele.helpers.table_copy(node)
n.name = noded
noded = n
end
if node.name == noded.name then
return false
end
minetest.swap_node(pos, noded)
return true
end
function ele.helpers.get_or_load_node(pos)
local node = minetest.get_node_or_nil(pos)
if node then return node end
local vm = VoxelManip()
local MinEdge, MaxEdge = vm:read_from_map(pos, pos)
return nil
end
function ele.helpers.get_item_group(name, grp)
return minetest.get_item_group(name, grp) > 0
end
function ele.helpers.flatten(map)
local list = {}
for key, value in pairs(map) do
list[#list + 1] = value
end
return list
end
function ele.helpers.get_node_property(meta, pos, prop)
local value = meta:get_int(prop)
if value == 0 or value == nil then
local nname = minetest.get_node(pos).name
local ndef = minetest.registered_nodes[nname]
value = ndef["ele_"..prop]
end
if not value then return 0 end
return value
end

19
elepower_papi/init.lua Normal file
View File

@ -0,0 +1,19 @@
-- Elepower Mod
-- Copyright 2018 Evert "Diamond" Prants <evert@lunasqu.ee>
local modpath = minetest.get_modpath(minetest.get_current_modname())
ele = rawget(_G, "ele") or {}
ele.modpath = modpath
-- Constants
ele.unit = "EpU"
ele.unit_description = "Elepower Unit"
-- APIs
dofile(modpath..'/helpers.lua')
dofile(modpath..'/network.lua')
dofile(modpath..'/formspec.lua')
dofile(modpath..'/machine.lua')
dofile(modpath..'/conductor.lua')
dofile(modpath..'/tool.lua')

238
elepower_papi/machine.lua Normal file
View File

@ -0,0 +1,238 @@
-- Machine definitions
--[[
Groups:
ele_machine Any machine that does something with power
ele_provider Any machine that can provide power (generator, storage, etc)
ele_user Any machine that uses power
ele_storage Any machine that stores power
ele_conductor A node that is used to connect ele_machine nodes together
Custom nodedef variables:
ele_capacity = 12000
Static capacitor for nodes.
** Can be overridden by metadata: `capacity`
ele_inrush = 32
Decides how much power can be inserted into this machine's internal capacitor.
** Can be overridden by metadata: `inrush`
ele_output = 64
Decides how much power a `ele_provider` node can output.
** SHOULD be overridden by metadata: `output`
ele_sides = nil
All sides of providers currently output power. All sides of other nodes accept power.
** SHOULD be overridden by metadata: `sides`
ele_usage = 16
How much power this machine uses or generates.
** Can be overridden by metadata: `usage`
ele_active_node = nil
Set to true or a string to also register an active variant of this node.
If the parameter is a boolean, "_active" will be appended to the `node_name`
ele_active_nodedef = nil
If set, the `ele_active_node` will have this table in its nodedef.
Intended use: to set textures or light output.
]]
local function allow_metadata_inventory_put(pos, listname, index, stack, player)
if minetest.is_protected(pos, player:get_player_name()) then
return 0
end
if listname == "dst" then
return 0
end
return stack:get_count()
end
local function allow_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
local stack = inv:get_stack(from_list, from_index)
return allow_metadata_inventory_put(pos, to_list, to_index, stack, player)
end
local function allow_metadata_inventory_take(pos, listname, index, stack, player)
if minetest.is_protected(pos, player:get_player_name()) then
return 0
end
return stack:get_count()
end
function metadata_inventory_changed(pos)
local t = minetest.get_node_timer(pos)
if not t:is_started() then
t:start(1.0)
end
end
-- Preserve power storage in the item stack dropped
local function preserve_metadata(pos, oldnode, oldmeta, drops)
local meta = minetest.get_meta(pos)
local capacity = ele.helpers.get_node_property(meta, pos, "capacity")
local storage = ele.helpers.get_node_property(meta, pos, "storage")
local nodedesc = minetest.registered_nodes[oldnode.name].description
if storage == 0 then
return drops
end
for i,stack in pairs(drops) do
local stack_meta = stack:get_meta()
stack_meta:set_int("storage", storage)
stack_meta:set_string("description", nodedesc.."\nCharge: " .. storage .. "/" .. capacity .. " " .. ele.unit)
drops[i] = stack
end
return drops
end
-- Retrieve power storage from itemstack when placed
local function retrieve_metadata(pos, placer, itemstack, pointed_thing)
local item_meta = itemstack:get_meta()
local storage = item_meta:get_int("storage")
if storage and storage > 0 then
local meta = minetest.get_meta(pos)
meta:set_int("storage", storage)
minetest.get_node_timer(pos):start(1.0)
end
return false
end
-- Register a base device
function ele.register_base_device(nodename, nodedef)
-- Override construct callback
local original_on_construct = nodedef.on_construct
nodedef.on_construct = function (pos)
if nodedef.groups and nodedef.groups["ele_machine"] then
local meta = minetest.get_meta(pos)
meta:set_int("storage", 0)
end
ele.clear_networks(pos)
if original_on_construct then
original_on_construct(pos)
end
end
-- Override destruct callback
local original_after_destruct = nodedef.after_destruct
nodedef.after_destruct = function (pos)
ele.clear_networks(pos)
if original_after_destruct then
original_after_destruct(pos)
end
end
-- Save storage amount when picked up
nodedef.preserve_metadata = preserve_metadata
nodedef.after_place_node = retrieve_metadata
-- Finally, register the damn thing already
minetest.register_node(nodename, nodedef)
-- Register an active variant if configured.
if nodedef.ele_active_node then
local active_nodedef = ele.helpers.table_copy(nodedef)
local active_name = nodename.."_active"
if nodedef.ele_active_node ~= true then
active_name = nodedef.ele_active_node
end
if nodedef.ele_active_nodedef then
for k,v in pairs(nodedef.ele_active_nodedef) do
active_nodedef[k] = v
end
nodedef.ele_active_nodedef = nil
active_nodedef.ele_active_nodedef = nil
end
active_nodedef.groups["ele_active"] = 1
active_nodedef.groups["not_in_creative_inventory"] = 1
active_nodedef.drop = nodename
minetest.register_node(active_name, active_nodedef)
end
end
function ele.register_machine(nodename, nodedef)
if not nodedef.groups then
nodedef.groups = {}
end
-- Start cleaning up the nodedef
local defaults = {
ele_capacity = 1600,
ele_inrush = 64,
ele_usage = 64,
ele_output = 64,
ele_sides = nil,
paramtype2 = "facedir"
}
-- Ensure everything that's required is present
for k,v in pairs(defaults) do
if not nodedef[k] then
nodedef[k] = v
end
end
-- Ensure machine group is used properly
if not nodedef.groups["ele_conductor"] and not nodedef.groups["ele_machine"] then
nodedef.groups["ele_machine"] = 1
elseif nodedef.groups["ele_conductor"] and nodedef.groups["ele_machine"] then
nodedef.groups["ele_machine"] = 0
end
-- Add ports to the device's faces
if nodedef.tiles and #nodedef.tiles == 6 then
for i = 1, 5 do
nodedef.tiles[i] = nodedef.tiles[i] .. "^elepower_power_port.png"
end
end
-- Add ports to the device's active faces
if nodedef.ele_active_nodedef and nodedef.ele_active_nodedef.tiles and #nodedef.ele_active_nodedef.tiles == 6 then
for i = 1, 5 do
nodedef.ele_active_nodedef.tiles[i] = nodedef.ele_active_nodedef.tiles[i] .. "^elepower_power_port.png"
end
end
-- Default metadata handlers for "src" and "dst"
if not nodedef.allow_metadata_inventory_put then
nodedef.allow_metadata_inventory_put = allow_metadata_inventory_put
nodedef.allow_metadata_inventory_move = allow_metadata_inventory_move
end
if not nodedef.allow_metadata_inventory_take then
nodedef.allow_metadata_inventory_take = allow_metadata_inventory_take
end
-- Default metadata changed handlers for inventories
-- Starts the timer on the node
if not nodedef.on_metadata_inventory_move then
nodedef.on_metadata_inventory_move = metadata_inventory_changed
end
if not nodedef.on_metadata_inventory_put then
nodedef.on_metadata_inventory_put = metadata_inventory_changed
end
if not nodedef.on_metadata_inventory_take then
nodedef.on_metadata_inventory_take = metadata_inventory_changed
end
ele.register_base_device(nodename, nodedef)
end

3
elepower_papi/mod.conf Normal file
View File

@ -0,0 +1,3 @@
name = elepower_papi
description = Elepower Power Network API
optional_depends = default

398
elepower_papi/network.lua Normal file
View File

@ -0,0 +1,398 @@
-- Network graphs are built eminating from provider nodes.
--[[
TODO:
Currently, there's a problem where storage nodes are allowed to create their own graph.
When placing the storage onto a cable, it will add itself to the graph of that cable.
But, when placing a cable onto the storage, that cable is added to the storage's own graph
and thus cannot be connected to the previous graph.
]]
-- Network cache
ele.graphcache = {devices = {}}
---------------------
-- Graph Functions --
---------------------
local function clear_networks_from_node(pos)
local meta = minetest.get_meta(pos)
meta:set_string("network_id", "")
end
local function add_node(nodes, pos, pnodeid)
local node_id = minetest.hash_node_position(pos)
if ele.graphcache.devices[node_id] and ele.graphcache.devices[node_id] ~= pnodeid then return end
ele.graphcache.devices[node_id] = pnodeid
if nodes[node_id] then
return false
end
nodes[node_id] = pos
return true
end
local function add_conductor_node(nodes, pos, pnodeid, queue)
if add_node(nodes, pos, pnodeid) then
queue[#queue + 1] = pos
end
end
local function check_node(users, providers, all_nodes, pos, pr_pos, pnodeid, queue)
ele.helpers.get_or_load_node(pos)
local node = minetest.get_node(pos)
local meta = minetest.get_meta(pos)
if ele.helpers.get_item_group(node.name, "ele_conductor") then
local nodedef = minetest.registered_nodes[node.name]
local ptransfer = 0
if nodedef.elepower_transfer then
ptransfer = nodedef.elepower_transfer
end
add_conductor_node(all_nodes, pos, pnodeid, queue)
return
end
if not ele.helpers.get_item_group(node.name, "ele_machine") then
return
end
-- Don't add already networked nodes to this network
if meta:get_string("network_id") ~= "" and meta:get_string("network_id") ~= pnodeid then
return
end
meta:set_string("network_id", pnodeid)
if ele.helpers.get_item_group(node.name, "ele_user") then
add_node(users, pos, pnodeid)
elseif ele.helpers.get_item_group(node.name, "ele_provider") then
if ele.helpers.get_item_group(node.name, "ele_storage") then
-- Storage gets added to users, for now
add_node(users, pos, pnodeid)
else
add_node(providers, pos, pnodeid)
end
end
end
local function traverse_network(users, providers, all_nodes, pos, pr_pos, pnodeid, queue)
local positions = {
{x=pos.x+1, y=pos.y, z=pos.z},
{x=pos.x-1, y=pos.y, z=pos.z},
{x=pos.x, y=pos.y+1, z=pos.z},
{x=pos.x, y=pos.y-1, z=pos.z},
{x=pos.x, y=pos.y, z=pos.z+1},
{x=pos.x, y=pos.y, z=pos.z-1}}
for _, cur_pos in pairs(positions) do
check_node(users, providers, all_nodes, cur_pos, pr_pos, pnodeid, queue)
end
end
local function power_networks(pr_pos, positions)
local provider = minetest.get_node(pr_pos)
local pnodeid = minetest.pos_to_string(pr_pos)
if ele.graphcache[pnodeid] then
local cached = ele.graphcache[pnodeid]
return cached.users, cached.providers
end
local users = {}
local providers = {}
local queue = {}
local all_nodes = {}
for pos in pairs(positions) do
queue = {}
local node = minetest.get_node(pos)
if node and ele.helpers.get_item_group(node.name, "ele_conductor") then
add_conductor_node(all_nodes, pos, pnodeid, queue)
elseif node and ele.helpers.get_item_group(node.name, "ele_machine") then
queue = {pr_pos}
end
while next(queue) do
local to_visit = {}
for _, posi in ipairs(queue) do
traverse_network(users, providers, all_nodes, posi, pr_pos, pnodeid, to_visit)
end
queue = to_visit
end
end
-- Add self to providers
local prov_id = minetest.hash_node_position(pr_pos)
ele.graphcache.devices[prov_id] = pnodeid
providers[prov_id] = pr_pos
users = ele.helpers.flatten(users)
providers = ele.helpers.flatten(providers)
all_nodes = ele.helpers.flatten(all_nodes)
ele.graphcache[pnodeid] = {all_nodes = all_nodes, users = users, providers = providers}
return users, providers
end
-----------------------
-- Main Transfer ABM --
-----------------------
local function give_node_power(pos, available)
local user_meta = minetest.get_meta(pos)
local capacity = ele.helpers.get_node_property(user_meta, pos, "capacity")
local inrush = ele.helpers.get_node_property(user_meta, pos, "inrush")
local storage = user_meta:get_int("storage")
local total_add = 0
if available >= inrush then
total_add = inrush
elseif available < inrush then
total_add = inrush - available
end
if total_add + storage > capacity then
total_add = (total_add + storage) - capacity
end
if storage >= capacity then
total_add = 0
storage = capacity
end
return total_add, storage
end
minetest.register_abm({
nodenames = {"group:ele_provider"},
label = "elepowerPowerGraphSource",
interval = 1,
chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider)
local meta = minetest.get_meta(pos)
local meta1 = nil
-- Check if a provider is attached to a network.
-- If that network has been abolished, we will use this node as the network's root this time.
local netwrkto = meta:get_string("ele_network")
if netwrkto ~= "" and netwrkto ~= nil then
if not ele.helpers.get_item_group(node.name, "ele_storage") then
local lpos = minetest.string_to_pos(netwrkto)
if ele.helpers.get_item_group(minetest.get_node(lpos).name, "ele_provider") then
return
else
ele.graphcache[netwrkto] = nil
end
meta:set_string("ele_network", "")
end
end
local users = {}
local providers = {}
local providerdef = minetest.registered_nodes[node.name]
-- TODO: Customizable output sides
local positions = {
{x=pos.x, y=pos.y-1, z=pos.z},
{x=pos.x, y=pos.y+1, z=pos.z},
{x=pos.x-1, y=pos.y, z=pos.z},
{x=pos.x+1, y=pos.y, z=pos.z},
{x=pos.x, y=pos.y, z=pos.z-1},
{x=pos.x, y=pos.y, z=pos.z+1}
}
local ntwks = {}
local errored = false
local nw_branches = 0
for _,pos1 in pairs(positions) do
local name = node.name
local networked = ele.helpers.get_item_group(name, "ele_machine") or ele.helpers.get_item_group(name, "ele_conductor")
if networked then
ntwks[pos1] = true
nw_branches = nw_branches + 1
end
end
if errored then
return
end
if nw_branches == 0 then
minetest.forceload_free_block(pos)
return
else
minetest.forceload_block(pos)
end
users, providers = power_networks(pos, ntwks)
-- Calculate power data
local pw_supply = 0
local pw_demand = 0
for _, spos in ipairs(providers) do
local smeta = minetest.get_meta(spos)
local pw_storage = smeta:get_int("storage")
local p_output = ele.helpers.get_node_property(smeta, spos, "output")
if p_output and pw_storage >= p_output then
pw_supply = pw_supply + p_output
elseif p_output and pw_storage < p_output then
pw_supply = pw_supply + pw_storage
end
end
-- Give power to users
for _,ndv in ipairs(users) do
if pw_demand >= pw_supply then
break
end
local user_gets, user_storage = give_node_power(ndv, pw_supply - pw_demand)
pw_demand = pw_demand + user_gets
local user_meta = minetest.get_meta(ndv)
user_meta:set_int("storage", user_storage + user_gets)
if user_gets > 0 then
-- Set timer on this node
local t = minetest.get_node_timer(ndv)
if not t:is_started() then
t:start(1.0)
end
end
end
-- Take the power from a provider node
if pw_demand > 0 then
for _, spos in ipairs(providers) do
local smeta = minetest.get_meta(spos)
local pw_storage = smeta:get_int("storage")
if pw_storage >= pw_demand then
smeta:set_int("storage", pw_storage - pw_demand)
else
pw_demand = pw_demand - pw_storage
smeta:set_int("storage", 0)
end
minetest.get_node_timer(spos):start(1.0)
end
end
end,
})
local function check_connections(pos)
local connections = {}
local positions = {
{x=pos.x+1, y=pos.y, z=pos.z},
{x=pos.x-1, y=pos.y, z=pos.z},
{x=pos.x, y=pos.y+1, z=pos.z},
{x=pos.x, y=pos.y-1, z=pos.z},
{x=pos.x, y=pos.y, z=pos.z+1},
{x=pos.x, y=pos.y, z=pos.z-1}}
for _,connected_pos in pairs(positions) do
local name = minetest.get_node(connected_pos).name
if ele.helpers.get_item_group(name, "ele_conductor") or ele.helpers.get_item_group(name, "ele_machine") then
table.insert(connections, connected_pos)
end
end
return connections
end
-- Update networks when a node has been placed or removed
function ele.clear_networks(pos)
local node = minetest.get_node(pos)
local meta = minetest.get_meta(pos)
local name = node.name
local placed = name ~= "air"
local positions = check_connections(pos)
if #positions < 1 then return end
local dead_end = #positions == 1
for _,connected_pos in pairs(positions) do
local net = ele.graphcache.devices[minetest.hash_node_position(connected_pos)] or minetest.pos_to_string(connected_pos)
if net and ele.graphcache[net] then
if dead_end and placed then
-- Dead end placed, add it to the network
-- Get the network
local node_at = minetest.get_node(positions[1])
local network_id = ele.graphcache.devices[minetest.hash_node_position(positions[1])] or minetest.pos_to_string(positions[1])
if not network_id or not ele.graphcache[network_id] then
-- We're evidently not on a network, nothing to add ourselves to
return
end
local c_pos = minetest.string_to_pos(network_id)
local network = ele.graphcache[network_id]
-- Actually add it to the (cached) network
-- This is similar to check_node_subp
ele.graphcache.devices[minetest.hash_node_position(pos)] = network_id
pos.visited = 1
if ele.helpers.get_item_group(name, "ele_conductor") then
table.insert(network.all_nodes, pos)
end
if ele.helpers.get_item_group(name, "ele_machine") then
meta:set_string("ele_network", network_id)
if ele.helpers.get_item_group(name, "ele_provider") then
if ele.helpers.get_item_group(name, "ele_storage") then
-- TODO: Add storage to users for now
table.insert(network.users, pos)
else
table.insert(network.providers, pos)
end
elseif ele.helpers.get_item_group(name, "ele_user") then
table.insert(network.users, pos)
end
end
elseif dead_end and not placed then
-- Dead end removed, remove it from the network
-- Get the network
local network_id = ele.graphcache.devices[minetest.hash_node_position(positions[1])] or minetest.pos_to_string(positions[1])
if not network_id or not ele.graphcache[network_id] then
-- We're evidently not on a network, nothing to remove ourselves from
return
end
local network = ele.graphcache[network_id]
-- The network was deleted.
if network_id == minetest.pos_to_string(pos) then
for _,v in pairs(network.all_nodes) do
local pos1 = minetest.hash_node_position(v)
clear_networks_from_node(v)
ele.graphcache.devices[pos1] = nil
end
ele.graphcache[network_id] = nil
return
end
-- Search for and remove device
ele.graphcache.devices[minetest.hash_node_position(pos)] = nil
for tblname,table in pairs(network) do
if type(table) == "table" then
for devicenum,device in pairs(table) do
if vector.equals(device, pos) then
table[devicenum] = nil
end
end
end
end
else
-- Not a dead end, so the whole network needs to be recalculated
for _,v in pairs(ele.graphcache[net].all_nodes) do
local pos1 = minetest.hash_node_position(v)
clear_networks_from_node(v)
ele.graphcache.devices[pos1] = nil
end
ele.graphcache[net] = nil
end
end
end
end

View File

@ -0,0 +1,6 @@
dofile(ele.modpath..'/power/network.lua')
dofile(ele.modpath..'/power/formspec.lua')
dofile(ele.modpath..'/power/machine.lua')
dofile(ele.modpath..'/power/conductor.lua')
dofile(ele.modpath..'/power/tool.lua')

0
elepower_papi/tool.lua Normal file
View File

8
elepower_tools/init.lua Normal file
View File

@ -0,0 +1,8 @@
-- A Elepower Mod
-- Copyright 2018 Evert "Diamond" Prants <evert@lunasqu.ee>
local modpath = minetest.get_modpath(minetest.get_current_modname())
elepd = rawget(_G, "elepd") or {}
elepd.modpath = modpath

3
elepower_tools/mod.conf Normal file
View File

@ -0,0 +1,3 @@
name = elepower_tools
description = Elepower powered tools!
depends = elepower_machines

0
modpack.txt Normal file
View File