remade power networking

This commit is contained in:
theFox6 2019-05-01 13:20:09 +02:00
parent 8e1dc22f7b
commit cd35a2ccbb
10 changed files with 228 additions and 160 deletions

@ -3,27 +3,13 @@
MicroExpansion - ME [microexpansion] MicroExpansion - ME [microexpansion]
====================================== ======================================
* **Version:** 0.2, unstable
* **Licence:** Code: MIT (see LICENSE), Media: CC-BY-SA 3.0 * **Licence:** Code: MIT (see LICENSE), Media: CC-BY-SA 3.0
* [Github Repository](https://github.com/octacian/microexpansion) * [Github Repository](https://github.com/octacian/microexpansion)
* **Downloads:** * **Downloads:**
* [Master (Unstable)](https://github.com/octacian/microexpansion/archive/master.zip) * [Master (Unstable)](https://github.com/octacian/microexpansion/archive/master.zip)
* ...or browse the code on [GitHub](https://github.com/octacian/microexpansion) * ...or browse the code on [GitHub](https://github.com/octacian/microexpansion)
**Note**: MicroExpansion requires that you have `minetest-dev` with [this commit](https://github.com/minetest/minetest/commit/f2f9a923515386d787a245fac52f78e815b3a839) or later.
When you really get into a survival world, you typically end up with a lot of items, like a ton of items. Sometimes literally. But with that huge amount of resources, comes something annoying and typically unwanted: chests. Well, of course. You have to have chests to store items, but no biggie, it's just chests. Then your storage room starts to grow, soon you have 25 chests, then 50, then 100. Management gets kinda hard. MicroExpansion, is the solution. When you really get into a survival world, you typically end up with a lot of items, like a ton of items. Sometimes literally. But with that huge amount of resources, comes something annoying and typically unwanted: chests. Well, of course. You have to have chests to store items, but no biggie, it's just chests. Then your storage room starts to grow, soon you have 25 chests, then 50, then 100. Management gets kinda hard. MicroExpansion, is the solution.
Remade by theFox, original mod by octacian.
Originally inspired by Applied Energistics 2 for Minecraft, MicroExpansion introduces many new nodes and items giving the player simpler and more compact ways to store thousands of items inside of a single ME drive. Originally inspired by Applied Energistics 2 for Minecraft, MicroExpansion introduces many new nodes and items giving the player simpler and more compact ways to store thousands of items inside of a single ME drive.
**Note:** not all the features mentioned above are complete, so see the list directly below for planned and complete features.
### To Do List
- [x] ME Chests
- [ ] ME Networks
- [ ] Remote Access to ME Networks
- [ ] Spatial Storage Drives
- [ ] ...and more.
### Discussion / Issues
Discussion should take place here, on the forum post, or on enDEV IRC (irc.endev.xyz, port 6697, SSL, accept invalid certs), channel `#minetest`. Features requests should be made on the forum or through a GitHub issue. Bugs can best be reported by creating an issue on GitHub.

@ -22,36 +22,6 @@ end
-- Load API -- Load API
dofile(modpath.."/api.lua") dofile(modpath.."/api.lua")
-----------------
---- ME DATA ----
-----------------
-- [function] Load
function microexpansion.load()
local res = io.open(worldpath.."/microexpansion.txt", "r")
if res then
res = minetest.deserialize(res:read("*all"))
if type(res) == "table" then
microexpansion.networks = res.networks or {}
end
end
end
-- Load
microexpansion.load()
-- [function] Save
function microexpansion.save()
local data = {
networks = microexpansion.networks,
}
io.open(worldpath.."/microexpansion.txt", "w"):write(minetest.serialize(data))
end
-- [register on] Server Shutdown
minetest.register_on_shutdown(microexpansion.save)
------------------- -------------------
----- MODULES ----- ----- MODULES -----
------------------- -------------------
@ -64,7 +34,9 @@ local settings = Settings(modpath.."/modules.conf"):to_table()
function microexpansion.get_module_path(name) function microexpansion.get_module_path(name)
local module_path = modpath.."/modules/"..name local module_path = modpath.."/modules/"..name
if io.open(module_path.."/init.lua") then local handle = io.open(module_path.."/init.lua")
if handle then
io.close(handle)
return module_path return module_path
end end
end end
@ -72,10 +44,10 @@ end
-- [function] Load module (overrides modules.conf) -- [function] Load module (overrides modules.conf)
function microexpansion.load_module(name) function microexpansion.load_module(name)
if loaded_modules[name] ~= false then if loaded_modules[name] ~= false then
local module_init = microexpansion.get_module_path(name).."/init.lua" local module_path = microexpansion.get_module_path(name)
if module_init then if module_path then
dofile(module_init) dofile(module_path.."/init.lua")
loaded_modules[name] = true loaded_modules[name] = true
return true return true
else else
@ -89,7 +61,7 @@ end
-- [function] Require module (does not override modules.conf) -- [function] Require module (does not override modules.conf)
function microexpansion.require_module(name) function microexpansion.require_module(name)
if settings[name] and settings[name] ~= false then if settings[name] then
return microexpansion.load_module(name) return microexpansion.load_module(name)
end end
end end

@ -1,5 +1,5 @@
shared = true shared = true
power = true network = true
power = false
storage = true storage = true
ores = true ores = true
tools = true

101
modules/network/init.lua Normal file

@ -0,0 +1,101 @@
local me = microexpansion
me.networks = {}
local networks = me.networks
local path = microexpansion.get_module_path("network")
-- get a node, if nessecary load it
function me.get_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 minetest.get_node(pos)
end
-- load Resources
dofile(path.."/network.lua") -- Network Management
-- generate iterator to find all connected nodes
function me.connected_nodes(start_pos)
-- nodes to be checked
local open_list = {start_pos}
-- nodes that were checked
local closed_set = {}
-- local connected nodes function to reduce table lookups
local adjacent_connected_nodes = me.network.adjacent_connected_nodes
-- return the generated iterator
return function ()
-- start looking for next pos
local found = false
-- pos to be checked
local current_pos
-- find next unclosed
while not found do
-- get unchecked pos
current_pos = table.remove(open_list)
-- none are left
if current_pos == nil then return end
-- check the closed positions
for _,closed in pairs(closed_set) do
-- if current is unclosed
if not vector.equals(closed,current_pos) then
--found next unclosed
found = true
end
end
end
-- get all connected nodes
local next_pos = adjacent_connected_nodes(current_pos)
-- iterate through them
for _,p in pairs(next_pos) do
-- mark position to be checked
table.insert(open_set,p)
end
-- add this one to the closed set
table.insert(closed_set,current_pos)
-- return the one to be checked
return current_pos
end
end
-- get network connected to position
function me.get_network(start_pos)
for npos in me.connected_nodes(start_pos) do
if me.get_node(npos).name == "microexpansion:ctrl" then
for _,net in pairs(networks) do
if vector.equals(npos, net.pos) then
return net
end
end
end
end
end
-- load networks
function me.load()
local res = io.open(me.worldpath.."/microexpansion.txt", "r")
if res then
res = minetest.deserialize(res:read("*all"))
if type(res) == "table" then
for _,n in pairs(res.networks) do
table.insert(networks,me.network:new(n))
end
end
end
end
-- load now
me.load()
-- save networks
function me.save()
local data = {
networks = networks,
}
io.open(me.worldpath.."/microexpansion.txt", "w"):write(minetest.serialize(data))
end
-- save on server shutdown
minetest.register_on_shutdown(me.save)

103
modules/network/network.lua Normal file

@ -0,0 +1,103 @@
--- Microexpansion network
-- @type network
-- @field #table controller_pos the position of the controller
-- @field #number power_load the power currently provided to the network
-- @field #number power_storage the power that can be stored for the next tick
local network = {
power_load = 0,
power_storage = 0
}
microexpansion.network = network
--- construct a new network
-- @function [parent=#network] new
-- @param #table o the object to become a network or nil
function network:new(o)
local n = setmetatable(o or {}, {__index = self})
o.machines = {}
return o
end
--- check if a node can be connected
-- @function [parent=#network] can_connect
-- @param #table pos the position of the node to be checked
-- @return #boolean whether this node has the group me_connect
function network.can_connect(pos)
local node = me.get_node(pos)
return minetest.get_item_group(node.name, "me_connect") > 0
end
--- get all adjacent connected nodes
-- @function [parent=#network] adjacent_connected_nodes
-- @param #table pos the position of the base node
-- @param #boolean include_ctrl whether to check for the controller
-- @return #table all nodes that have the group me_connect
function network.adjacent_connected_nodes(pos, include_ctrl)
local adjacent = {
{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},
}
local nodes = {}
for _,pos in pairs(adjacent) do
if network.can_connect(pos) then
if include_ctrl == false then
if not me.get_node(pos).name == "microexpansion:ctrl" then
table.insert(nodes, pos)
end
else
table.insert(nodes, pos)
end
end
end
return nodes
end
--- provide power to the network
-- @function [parent=#network] provide
-- @param #number power the amount of power provided
function network:provide(power)
self.power_load = self.power_load + power
end
--- demand power from the network
-- @function [parent=#network] demand
-- @param #number power the amount of power demanded
-- @return #boolean whether the power was provided
function network:demand(power)
if self.power_load - power < 0 then
return false
end
self.power_load = self.power_load - power
return true
end
--- add power capacity to the network
-- @function [parent=#network] add_power_capacity
-- @param #number power the amount of power that can be stored
function network:add_power_capacity(power)
self.power_storage = self.power_storage + power
end
--- add power capacity to the network
-- @function [parent=#network] add_power_capacity
-- @param #number power the amount of power that can't be stored anymore
function network:remove_power_capacity(power)
self.power_storage = self.power_storage - power
if self.power_storage < 0 then
minetest.log("warning","[Microexpansion] power storage of network "..self.." dropped below zero")
end
end
--- remove overload
-- to be called by the controller every turn
-- @function [parent=#network] remove_overload
function network:remove_overload()
self.power_load = math.min(self.power_load, self.power_storage)
end

@ -1,10 +1,11 @@
-- power/ctrl.lua -- power/ctrl.lua
local me = microexpansion local me = microexpansion
local power = me.power
-- [register node] Controller -- [register node] Controller
me.register_node("ctrl", { me.register_node("ctrl", {
description = "Power Controller", description = "ME Drive",
tiles = { tiles = {
"ctrl_sides", "ctrl_sides",
"ctrl_bottom", "ctrl_bottom",
@ -45,12 +46,7 @@ me.register_node("ctrl", {
meta:set_string("network_id", id) meta:set_string("network_id", id)
meta:set_string("owner", name) meta:set_string("owner", name)
-- Initialize other meta me.networks[id] = {pos = pos}
meta:set_int("input", 0)
meta:set_int("output", 0)
meta:set_int("storage", 0)
me.networks[id] = pos
-- Trace Network -- Trace Network
power.trace(pos) power.trace(pos)
@ -61,7 +57,7 @@ me.register_node("ctrl", {
me.networks[id] = nil me.networks[id] = nil
-- Remove unit from network -- Remove unit from network
me.network_remove(pos) --me.network_remove(pos)
-- Trace/clear network -- Trace/clear network
power.trace(pos) power.trace(pos)
end, end,

@ -29,12 +29,13 @@ me.register_machine("fuel_fired_generator", {
machine = { machine = {
type = "provider", type = "provider",
on_survey = function(pos) on_survey = function(pos)
--TODO: burn fuel
return 5 -- Generate 5 ME/tick return 5 -- Generate 5 ME/tick
end, end,
}, },
}) })
-- [register node] Super Smelter --[[register node] Super Smelter
me.register_node("super_smelter", { me.register_node("super_smelter", {
description = "Super Smelter", description = "Super Smelter",
tiles = { tiles = {
@ -86,4 +87,4 @@ me.register_node("geo_generator", {
return 10 -- Generate 10 ME/tick return 10 -- Generate 10 ME/tick
end, end,
}, },
}) })]]

@ -9,11 +9,11 @@ local power = me.power
-- [local function] Renumber table -- [local function] Renumber table
local function renumber_table(t) local function renumber_table(t)
local result = {} local result = {}
for _, value in pairs(t) do for _, value in pairs(t) do
result[#result+1] = value table.insert(result,value)
end end
return result return result
end end
-- [local function] Get netitem by position -- [local function] Get netitem by position
@ -25,65 +25,9 @@ local function get_netitem_by_pos(list, pos)
end end
end end
---
--- API Functions
---
-- [function] Get node
function me.get_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 minetest.get_node(pos)
end
-- [function] Generate new network ID -- [function] Generate new network ID
function power.new_id() function power.new_id()
local count = 1 return "network_"..#me.networks+1
for _, i in pairs(me.networks) do
count = count + 1
end
return "network_"..count
end
-- [function] Can connect
function power.can_connect(pos)
local node = me.get_node(pos)
local res = minetest.get_item_group(node.name, "me_connect")
if res == 1 then
return true
else
return false
end
end
-- [function] Get connected nodes
function power.get_connected_nodes(pos, include_ctrl)
local nodes = {
{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 _, pos in pairs(nodes) do
if not power.can_connect(pos) then
nodes[_] = nil
else
if include_ctrl == false then
if me.get_node(pos).name == "microexpansion:ctrl" then
nodes[_] = nil
end
end
end
end
return renumber_table(nodes)
end end
-- [function] Add machine to network -- [function] Add machine to network

@ -1,6 +0,0 @@
-- tools/init.lua
local path = microexpansion.get_module_path("tools")
-- Load In Xtremo Tools
dofile(path.."/xtremo.lua")

@ -1,29 +0,0 @@
-- tools/xtremo.lua
-- [register tool] Pickaxe
minetest.register_tool("microexpansion:xtremo_pickaxe", {
description = "In Xtremo Pickaxe",
inventory_image = "microexpansion_in_xtremo_pickaxe.png",
tool_capabilities = {
full_punch_interval = 0.9,
max_drop_level=3,
groupcaps={
cracky = {times={[1]=1.90, [2]=0.90, [3]=0.40}, uses=300, maxlevel=4},
},
damage_groups = {fleshy=5},
},
})
-- [register tool] Axe
minetest.register_tool("microexpansion:xtremo_axe", {
description = "In Xtremo Axe",
inventory_image = "microexpansion_in_xtremo_axe.png",
tool_capabilities = {
full_punch_interval = 0.9,
max_drop_level=3,
groupcaps={
choppy={times={[1]=2.00, [2]=0.80, [3]=0.40}, uses=300, maxlevel=4},
},
damage_groups = {fleshy=7},
},
})