Compare commits

33 Commits
v0.2 ... master

Author SHA1 Message Date
63409be0ee Fix crash 2018-03-26 19:43:58 +02:00
5a5ca11ecd Replace spaces with tabs 2017-11-28 19:25:49 -08:00
be54e91335 Storage: Improve ME Chest formspec
Hide all buttons when no drive in slot, prevents spamming of log when search buttons are clicked with nothing to search. Move search field to the left so as to be in line with the inventory slots and move page number to the right for a more viewable interface due to spacing.
2017-05-03 11:28:51 -07:00
64805c5cba Make machine_sides texture more consistent 2017-03-24 09:15:57 -07:00
6fcb3ea6ac Change: SuperSmelter front face texture 2017-03-24 04:26:50 +00:00
81ed2d3122 Update screenshot 2017-03-06 20:09:47 -08:00
e7a194a08c Tools: New module and Add In Xtremo Pick & Pickaxe
Textures by @XtremeHacker
2017-03-03 16:18:27 -08:00
3e1a298f08 Ores: Update supernatet texture
Texture by @XtremeHacker
2017-03-03 16:02:03 -08:00
53efb78c81 API: Allow texture modifiers in node registration
If using texture modifiers, you must use the full texture name.
2017-03-02 17:33:00 -08:00
45f3ca4732 Power: Add ME Cable 2017-03-01 21:45:23 -08:00
8bb8a49701 Add disabled definition property 2017-03-01 17:30:50 -08:00
4d97ea6d80 Power: Add Controller 2017-03-01 17:27:00 -08:00
f86e433680 Add first textures for In Xtremo tools 2017-03-01 16:38:35 -08:00
daedd72a66 Add Supernatet Ore texture 2017-03-01 01:14:04 +00:00
e33131a695 Add ore definition registration API 2017-02-26 17:52:36 -08:00
1638d081eb Crafting: Remove module 2017-02-26 11:40:07 -08:00
ce8269fb03 Improve recipe API 2017-02-26 11:32:32 -08:00
d58afdee89 Ores: Fix code/module 2017-02-26 10:54:15 -08:00
2de5cfe2a2 Power: Add Solar generator textures 2017-02-26 10:54:05 -08:00
e8dbb44db4 Ores: Added Supernatet Ore 2017-02-26 09:23:06 -08:00
6c912106fb Ores: Added Incranium Ore 2017-02-26 09:13:30 -08:00
169ea1ce76 Added Ores module 2017-02-26 09:12:52 -08:00
9cb4790f40 Power: Add geothermal generator
Texture by @XtremeHacker
Non-functional.
2017-02-24 22:09:48 -08:00
080ee17335 Use single texture for sides of machines 2017-02-24 22:09:06 -08:00
ad80c63682 ME Drives: Show percent full in description 2017-02-24 16:26:45 -08:00
e0e5702053 Add status parameter to item & node def
Colours the item/node description to red if "no," orange if "unstable," and white if anything else.
2017-02-24 16:20:05 -08:00
81705adbdc Storage: Add 16k, 32k, and 64k ME Drives 2017-02-24 15:47:43 -08:00
7245476030 Power: Add super smelter
Textures by @XtremeHacker
Non-functional
2017-02-24 14:42:52 -08:00
45f28d18cf Power: Add fuel-fired generator
Textures by @XtremeHacker
Non-functional.
2017-02-24 14:32:58 -08:00
cad8033e34 Add power module
For power generators, wires, etc...
2017-02-24 14:32:04 -08:00
b1c894871f Shared: Add machine casing
Texture by @XtremeHacker
2017-02-24 14:15:02 -08:00
f4671fb685 Add Shared Module
Adds shared module along with Steel Infused Obsidian Ingot. Textures by @XtremeHacker
2017-02-24 14:14:41 -08:00
f11fe2ff90 Fix documentation of recipe registration 2017-02-24 14:08:28 -08:00
38 changed files with 975 additions and 191 deletions

View File

@ -7,8 +7,8 @@ MicroExpansion - ME [microexpansion]
* **Licence:** Code: MIT (see LICENSE), Media: CC-BY-SA 3.0
* [Github Repository](https://github.com/octacian/microexpansion)
* **Downloads:**
* [Master (Unstable)](https://github.com/octacian/microexpansion/archive/master.zip)
* ...or browse the code on [GitHub](https://github.com/octacian/microexpansion)
* [Master (Unstable)](https://github.com/octacian/microexpansion/archive/master.zip)
* ...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.

191
api.lua
View File

@ -3,82 +3,151 @@ local BASENAME = "microexpansion"
-- [function] Register Recipe
function microexpansion.register_recipe(output, recipe)
local function isint(n)
return n==math.floor(n)
end
-- Check if disabled
if recipe.disabled == true then
return
end
local function getAmount()
if isint(recipe[2][1]) then
local q = recipe[2][1]
recipe[2][1] = nil
return q
else return 1 end
end
local function isint(n)
return n==math.floor(n)
end
local function register(amount, recipe)
minetest.register_craft({
output = output.." "..amount,
recipe = recipe,
})
end
local function get_amount(_)
if isint(recipe[_][1]) then
return recipe[_][1]
else return 1 end
end
local function single()
register(getAmount(), recipe[2])
end
local function get_type(_)
if type(recipe[_][2]) == "string" then
return recipe[_][2]
end
end
local function multiple()
for i, item in ipairs(recipe) do
if i == 0 then return end
register(getAmount(), recipe[i])
end
end
local function register(_)
local def = {
type = get_type(_),
output = output.." "..tostring(get_amount(_)),
recipe = recipe[_][3] or recipe[_][2]
}
minetest.register_craft(def)
end
-- Check type
if recipe[1] == "single" then single()
elseif recipe[1] == "multiple" then multiple()
else return microexpansion.log("invalid recipe for definition "..output..". "..dump(recipe[2])) end
for _, i in ipairs(recipe) do
-- Check if disabled
if recipe.disabled == true then
return
end
register(_)
end
end
-- [function] Register oredef
function microexpansion.register_oredef(ore, def)
-- Check if disabled
if def.disabled == true then
return
end
local function register(_)
local def = def[_]
def.ore = "microexpansion:"..ore
minetest.register_ore(def)
end
for _, i in ipairs(def) do
-- Check if disabled
if def.disabled == true then
return
end
register(_)
end
end
-- [local function] Choose description colour
local function desc_colour(status, desc)
if status == "unstable" then
return minetest.colorize("orange", desc)
elseif status == "no" then
return minetest.colorize("red", desc)
else
return minetest.colorize("white", desc)
end
end
-- [function] Register Item
function microexpansion.register_item(itemstring, def)
-- Set usedfor
if def.usedfor then
def.description = def.description .. "\n"..minetest.colorize("grey", def.usedfor)
end
-- Update inventory image
if def.inventory_image then
def.inventory_image = BASENAME.."_"..def.inventory_image..".png"
else
def.inventory_image = BASENAME.."_"..itemstring..".png"
end
-- Check if disabled
if def.disabled == true then
return
end
-- Set usedfor
if def.usedfor then
def.description = def.description .. "\n"..minetest.colorize("grey", def.usedfor)
end
-- Update inventory image
if def.inventory_image then
def.inventory_image = BASENAME.."_"..def.inventory_image..".png"
else
def.inventory_image = BASENAME.."_"..itemstring..".png"
end
-- Colour description
def.description = desc_colour(def.status, def.description)
-- Register craftitem
minetest.register_craftitem(BASENAME..":"..itemstring, def)
-- Register craftitem
minetest.register_craftitem(BASENAME..":"..itemstring, def)
-- if recipe, Register recipe
if def.recipe then
microexpansion.register_recipe(BASENAME..":"..itemstring, def.recipe)
end
-- if recipe, Register recipe
if def.recipe then
microexpansion.register_recipe(BASENAME..":"..itemstring, def.recipe)
end
end
-- [function] Register Node
function microexpansion.register_node(itemstring, def)
-- Set usedfor
if def.usedfor then
def.description = def.description .. "\n"..minetest.colorize("grey", def.usedfor)
end
-- Update texture
if auto_complete ~= false then
for _,i in ipairs(def.tiles) do
def.tiles[_] = BASENAME.."_"..i..".png"
end
end
-- Check if disabled
if def.disabled == true then
return
end
-- Set usedfor
if def.usedfor then
def.description = def.description .. "\n"..minetest.colorize("grey", def.usedfor)
end
-- Update texture
--if auto_complete ~= false then
if true then
for _,i in ipairs(def.tiles) do
if #def.tiles[_]:split("^") <= 1 then
local prefix = ""
if def.type == "ore" then
prefix = "ore_"
end
-- register craftitem
minetest.register_node(BASENAME..":"..itemstring, def)
def.tiles[_] = BASENAME.."_"..prefix..i..".png"
end
end
end
-- Colour description
def.description = desc_colour(def.status, def.description)
-- Update connect_sides
if def.connect_sides == "nobottom" then
def.connect_sides = { "top", "front", "left", "back", "right" }
elseif def.connect_sides == "machine" then
def.connect_sides = { "top", "bottom", "left", "back", "right" }
end
-- if recipe, register recipe
if def.recipe then
microexpansion.register_recipe(BASENAME..":"..itemstring, def.recipe)
end
-- Register node
minetest.register_node(BASENAME..":"..itemstring, def)
-- if recipe, Register recipe
if def.recipe then
microexpansion.register_recipe(BASENAME..":"..itemstring, def.recipe)
end
-- if oredef, Register oredef
if def.oredef then
microexpansion.register_oredef(BASENAME..":"..itemstring, def.oredef)
end
end

View File

@ -1,49 +1,59 @@
# Core API
The core API is composed of several functions to make registering new items, nodes, and recipes for items and nodes more efficient and intuitive. Code for this public API is in `./api.lua`. This documentation is divided up per function.
__Note:__ Any definition table for registering anything using the ME API allow a `disabled` property to be specified. If set to `false`, the node/item will not be registered, if not set, it will.
#### `register_recipe(output, def)`
__Usage:__ `microexpansion.register_recipe(<output (string)>, <recipe (table)>)`
Though this may seem rather complex to understand, this is a very useful timesaving function when registering recipes. It allows registering multiple recipes at once in one table. The output must always remain the same as is specified as the first parameter, while the second parameter should be a table structured like one of the tables below.
Though this may seem rather complex to understand, this is a very useful timesaving function when registering recipes. It allows registering multiple recipes at once in one table. The output must always remain the same as is specified as the first parameter, while the second parameter should be a table structured like the table below.
__Single Recipe:__
__Example:__
```lua
microexpansion.register_recipe("default:steelblock", {
"single",
{
{ "default:steel_ingot", "default:steel_ingot", "default:steel_ingot" },
{ "default:steel_ingot", "default:steel_ingot", "default:steel_ingot" },
{ "default:steel_ingot", "default:steel_ingot", "default:steel_ingot" },
{ 1, {
{ "default:steel_ingot", "default:steel_ingot", "default:steel_ingot" },
{ "default:steel_ingot", "default:steel_ingot", "default:steel_ingot" },
{ "default:steel_ingot", "default:steel_ingot", "default:steel_ingot" },
},
},
{ 1, "shapeless", {
"default:steel_ingot", "default:obsidian_shard", "default:steel_ingot",
},
},
})
```
The above registers a single recipe for the item specified.
The above registers a two recipes for the item specified. The `1` specifies the output quantity. `shapeless` causes the second recipe to be of the `shapeless` type. After the first one or two definitions (amount, type), the recipe can be specified as normal inside another sub-table. You can have as many recipe sub-tables as you want.
#### `register_oredef(ore, def)`
__Usage:__ `microexpansion.register_oredef(<ore itemstring (string)>, <definition (table)>`
This custom API allows registering multiple ore definitions for a single node in one table. The table structure is quite simple, each definition is placed in an annonymous table in which the normal ore definitions are placed (excluding the ore itemstring). See below for a basic example.
__Multiple Recipes:__
```lua
microexpansion.register_recipe("default:steelblock", {
"multiple",
microexpansion.register_oredef("microexpansion:incranium", {
{
{ "default:steel_ingot", "default:steel_ingot", "default:steel_ingot" },
{ "default:steel_ingot", "default:steel_ingot", "default:steel_ingot" },
{ "default:steel_ingot", "default:steel_ingot", "default:steel_ingot" },
ore_type = "blob",
wherein = "default:stone",
clust_scarcity = 4*4*4,
clust_num_ores = 4,
clust_size = 3,
y_min = -300,
y_max = -90,
},
{
{ "default:steel_ingot", "default:steel_ingot" },
{ "default:steel_ingot", "default:steel_ingot" },
}
...
})
```
The above registers multiple recipes for the item specified.
See the [wiki documentation](http://dev.minetest.net/minetest.register_ore) for more information about the accepted or parameters.
#### `register_item(itemstring, def)`
__Usage:__ `microexpansion.register_item(<itemstring (string)>, <item definition (table)>`
This API function accepts the same parameters in the definition table as does `minetest.register_craftitem`, however, it makes several modifications to the parameters before passing them on. A new parameter, `usedfor`, is introduced, which if provided is appened on a new line in grey to the item description, a good way to specify what the item does or include more information about it. The `inventory_image` parameter is modified to enforce the naming style adding `microexpansion_` to the beginning of the specified path, and `.png` to the end. If not `inventory_image` is provided, the itemstring is used and then undergoes the above modification. This allows shortening and even removing the `inventory_image` code, while passing everything else (aside from `usedfor`) on to `minetest.register_craftitem`.
This API function accepts the same parameters in the definition table as does `minetest.register_craftitem`, however, it makes several modifications to the parameters before passing them on. A new parameter, `usedfor`, is introduced, which if provided is appened on a new line in grey to the item description, a good way to specify what the item does or include more information about it. The `inventory_image` parameter is modified to enforce the naming style adding `microexpansion_` to the beginning of the specified path, and `.png` to the end. If not `inventory_image` is provided, the itemstring is used and then undergoes the above modification. This allows shortening and even removing the `inventory_image` code, while passing everything else (aside from `usedfor`) on to `minetest.register_craftitem`. One final extra parameter is `status`, which if set to `no` the description is red, if set to `unstable` the description is `orange`, and if anything else the description is red. The recipe can be automatically registered and defined right in the item definition with the `recipe` table. See `microexpansion.register_recipe` for more information.
#### `register_node(itemstring, def)`
__Usage:__ `microexpansion.register_node(<itemstring (string)>, <item definition (table)>`
This API function accepts the same parameters in the definition table as does `minetest.register_craftitem`, however, it makes several modifications to the parameters before passing them on. A new parameter, `usedfor`, is introduced, which if provided is appened on a new line in grey to the item description, a good way to specify what the item does or include more information about it. The `tiles` table is modified so as to simplify the definition when registering the node. Each texture in the `tiles` table has `microexpansion_` added to the beginning and `.png` to the end. This means that rather than specifying something like `microexpansion_chest_top.png`, only `chest_top` is required. __Note:__ the texture path "autocomplete" functionality can be disabled by settings `auto_complete` to `false` in the definition (useful if using textures from another mod).
This API function accepts the same parameters in the definition table as does `minetest.register_craftitem`, however, it makes several modifications to the parameters before passing them on. A new parameter, `usedfor`, is introduced, which if provided is appened on a new line in grey to the item description, a good way to specify what the item does or include more information about it. The `tiles` table is modified so as to simplify the definition when registering the node. Each texture in the `tiles` table has `microexpansion_` added to the beginning and `.png` to the end. This means that rather than specifying something like `microexpansion_chest_top.png`, only `chest_top` is required. __Note:__ the texture path "autocomplete" functionality can be disabled by settings `auto_complete` to `false` in the definition (useful if using textures from another mod). One final extra parameter is `status`, which if set to `no` the description is red, if set to `unstable` the description is `orange`, and if anything else the description is red. The recipe can be automatically registered and defined right in the item definition with the `recipe` table. See `microexpansion.register_recipe` for more information. You can also automatically register ore definitions for the current node with `microexpansion.register_oredef`.

View File

@ -2,7 +2,7 @@
Non-API portions of MicroExpansion are loaded as modules to allow them to be easily enabled or disabled. Modules can be manually loaded or required from the API or from another module. Specific modules can be disabled using `modules.conf`, as documented below.
## Managing Modules
Modules listed in the configuration file are automatically loaded at startup unless specifically disabled. For the purpose of listing and/or disabling mods, we've introduced the `modules.conf` file.
Modules listed in the configuration file are automatically loaded at startup unless specifically disabled. For the purpose of listing and/or disabling mods, we've introduced the `modules.conf` file.
Each module is listed on a new line, as if setting a variable. A module can be disabled or enabled by setting this variable to `true` or `false`. If a module is not listed here, or is set to `false` (disabled), it will not be automatically loaded.
@ -32,4 +32,4 @@ Attempts to load a module. If the module path is `nil`, `nil` is returned to ind
#### `require_module(name)`
__Usage:__ `microexpansion.require_module(<module name (string)>)`
Passes name to `load_module` if the mod was not disabled in `modules.conf`. For further documentation, see `load_module`.
Passes name to `load_module` if the mod was not disabled in `modules.conf`. For further documentation, see `load_module`.

View File

@ -1,7 +1,11 @@
-- microexpansion/init.lua
microexpansion = {}
microexpansion.modpath = minetest.get_modpath("microexpansion") -- modpath
local modpath = microexpansion.modpath -- modpath pointer
microexpansion = {}
microexpansion.data = {}
microexpansion.modpath = minetest.get_modpath("microexpansion") -- Get modpath
microexpansion.worldpath = minetest.get_worldpath() -- Get worldpath
local modpath = microexpansion.modpath -- Modpath pointer
local worldpath = microexpansion.worldpath -- Worldpath pointer
-- Formspec GUI related stuff
microexpansion.gui_bg = "bgcolor[#080808BB;true]background[5,5;1,1;gui_formbg.png;true]"
@ -9,14 +13,45 @@ microexpansion.gui_slots = "listcolors[#00000069;#5A5A5A;#141318;#30434C;#FFF]"
-- logger
function microexpansion.log(content, log_type)
if not content then return false end
if log_type == nil then log_type = "action" end
minetest.log(log_type, "[MicroExpansion] "..content)
assert(content, "microexpansion.log: missing content")
if not content then return false end
if log_type == nil then log_type = "action" end
minetest.log(log_type, "[MicroExpansion] "..content)
end
-- Load API
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 -----
-------------------
@ -27,40 +62,40 @@ local settings = Settings(modpath.."/modules.conf"):to_table()
-- [function] Get module path
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
return module_path
end
if io.open(module_path.."/init.lua") then
return module_path
end
end
-- [function] Load module (overrides modules.conf)
function microexpansion.load_module(name)
if loaded_modules[name] ~= false then
local module_init = microexpansion.get_module_path(name).."/init.lua"
if loaded_modules[name] ~= false then
local module_init = microexpansion.get_module_path(name).."/init.lua"
if module_init then
dofile(module_init)
loaded_modules[name] = true
return true
else
microexpansion.log("Invalid module \""..name.."\". The module either does not exist "..
"or is missing an init.lua file.", "error")
end
else
return true
end
if module_init then
dofile(module_init)
loaded_modules[name] = true
return true
else
microexpansion.log("Invalid module \""..name.."\". The module either does not exist "..
"or is missing an init.lua file.", "error")
end
else
return true
end
end
-- [function] Require module (does not override modules.conf)
function microexpansion.require_module(name)
if settings[name] and settings[name] ~= false then
return microexpansion.load_module(name)
end
if settings[name] and settings[name] ~= false then
return microexpansion.load_module(name)
end
end
for name,enabled in pairs(settings) do
if enabled ~= false then
microexpansion.load_module(name)
end
if enabled ~= false then
microexpansion.load_module(name)
end
end

View File

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

45
modules/ores/init.lua Normal file
View File

@ -0,0 +1,45 @@
-- ores/init.lua
local me = microexpansion
-- [register] Incranium Ore
me.register_node("incranium", {
description = "Incranium Ore",
tiles = { "incranium" },
is_ground_content = true,
groups = { cracky=3, stone=1 },
type = "ore",
oredef = {
{
ore_type = "blob",
wherein = "default:stone",
clust_scarcity = 4*4*4,
clust_num_ores = 4,
clust_size = 3,
y_min = -300,
y_max = -90,
},
},
disabled = true,
})
-- "Supernatet", pronounced "Super-nat-et" is Latin for "float", this ore will
-- float up if there are no blocks above it, so be careful!
-- Supernatet ore will be used to craft wings of flight
me.register_node("supernatet", {
description = "Supernatant Ore",
tiles = { "default_stone.png^microexpansion_ore_supernatet.png" },
is_ground_content = true,
type = "ore",
groups = { cracky=3, stone=1 },
oredef = {
ore_type = "blob",
wherein = "default:stone",
clust_scarcity = 4*4*4,
clust_num_ores = 4,
clust_size = 3,
y_min = -300,
y_max = -90,
},
status = "unstable",
})

96
modules/power/ctrl.lua Normal file
View File

@ -0,0 +1,96 @@
-- power/ctrl.lua
local me = microexpansion
-- [register node] Controller
me.register_node("ctrl", {
description = "Power Controller",
tiles = {
"ctrl_sides",
"ctrl_bottom",
"ctrl_sides",
"ctrl_sides",
"ctrl_sides",
"ctrl_sides"
},
drawtype = "nodebox",
paramtype = "light",
node_box = {
type = "fixed",
fixed = {
{-0.375, -0.375, -0.375, 0.375, 0.375, 0.375}, -- Core
{0.1875, -0.5, -0.5, 0.5, 0.5, -0.1875}, -- Corner1
{-0.5, -0.5, -0.5, -0.1875, 0.5, -0.1875}, -- Corner2
{-0.5, -0.5, 0.1875, -0.1875, 0.5, 0.5}, -- Corner3
{0.1875, -0.5, 0.1875, 0.5, 0.5, 0.5}, -- Corner4
{-0.5, -0.4375, -0.5, 0.5, -0.1875, 0.5}, -- Bottom
{-0.5, 0.1875, -0.5, 0.5, 0.5, -0.1875}, -- Top1
{0.1875, 0.1875, -0.5, 0.5, 0.5, 0.5}, -- Top2
{-0.5, 0.1875, -0.5, -0.1875, 0.5, 0.5}, -- Top3
{-0.5, 0.1875, 0.1875, 0.5, 0.5, 0.5}, -- Top4
{-0.1875, -0.5, -0.1875, 0.1875, -0.25, 0.1875}, -- Bottom2
},
},
groups = { cracky = 1, me_connect = 1, },
connect_sides = "nobottom",
status = "unstable",
after_place_node = function(pos, player)
local name = player:get_player_name()
local meta = minetest.get_meta(pos)
local id = power.new_id()
meta:set_string("infotext", "Network Controller (owned by "..name..")"
.."\nNetwork ID: "..id)
meta:set_string("network_id", id)
meta:set_string("owner", name)
-- Initialize other meta
meta:set_int("input", 0)
meta:set_int("output", 0)
meta:set_int("storage", 0)
me.networks[id] = pos
-- Trace Network
power.trace(pos)
end,
on_destruct = function(pos, player)
local meta = minetest.get_meta(pos)
local id = meta:get_string("network_id")
me.networks[id] = nil
-- Remove unit from network
me.network_remove(pos)
-- Trace/clear network
power.trace(pos)
end,
machine = {
type = "transporter",
},
})
-- [register node] Cable
me.register_machine("cable", {
description = "ME Cable",
tiles = {
"cable",
},
drawtype = "nodebox",
node_box = {
type = "connected",
fixed = {-0.25, -0.25, -0.25, 0.25, 0.25, 0.25},
connect_top = {-0.25, -0.25, -0.25, 0.25, 0.5, 0.25}, -- y+
connect_bottom = {-0.25, -0.5, -0.25, 0.25, 0.25, 0.25}, -- y-
connect_front = {-0.25, -0.25, -0.5, 0.25, 0.25, 0.25}, -- z-
connect_back = {-0.25, -0.25, 0.25, 0.25, 0.25, 0.5 }, -- z+
connect_left = {-0.5, -0.25, -0.25, 0.25, 0.25, 0.25}, -- x-
connect_right = {-0.25, -0.25, -0.25, 0.5, 0.25, 0.25}, -- x+
},
paramtype = "light",
groups = { crumbly = 1, },
status = "unstable",
machine = {
type = "transporter",
},
})

89
modules/power/gen.lua Normal file
View File

@ -0,0 +1,89 @@
-- power/gen.lua
local me = microexpansion
-- [register node] Fuel Fired Generator
me.register_machine("fuel_fired_generator", {
description = "Fuel-Fired Generator",
tiles = {
"machine_sides",
"machine_sides",
"machine_sides",
"machine_sides",
"machine_sides",
"machine_sides",
"fuelgen_front",
},
recipe = {
{ 1, {
{ "default:steel_ingot", "default:furnace", "default:steel_ingot" },
{"default:steel_ingot", "microexpansion:machine_casing", "default:steel_ingot" },
{ "default:steel_ingot", "default:steel_ingot", "default:steel_ingot" },
},
}
},
groups = { cracky = 1 },
connect_sides = "machine",
paramtype2 = "facedir",
status = "unstable",
machine = {
type = "provider",
on_survey = function(pos)
return 5 -- Generate 5 ME/tick
end,
},
})
-- [register node] Super Smelter
me.register_node("super_smelter", {
description = "Super Smelter",
tiles = {
"machine_sides",
"machine_sides",
"machine_sides",
"machine_sides",
"machine_sides",
"super_smelter_front",
},
recipe = {
{ 1, {
{ "default:furnace", "default:furnace", "default:furnace" },
{ "default:steel_ingot", "microexpansion:machine_casing", "default:steel_ingot" },
{ "default:steel_ingot", "default:steel_ingot", "default:steel_ingot" },
},
},
},
groups = { cracky = 1, me_connect = 1, },
connect_sides = "machine",
paramtype2 = "facedir",
status = "unstable",
machine = {
type = "consumer",
on_survey = function(pos)
return 5 -- Consume 5 ME/tick
end,
},
})
-- [register item] Geothermal Generator
me.register_node("geo_generator", {
description = "Geothermal Generator",
tiles = {
"machine_sides",
"machine_sides",
"machine_sides",
"machine_sides",
"machine_sides",
"geogen_front",
},
groups = { cracky = 1, me_connect = 1, },
connect_sides = "machine",
paramtype2 = "facedir",
status = "unstable",
machine = {
type = "provider",
on_survey = function(pos)
return 10 -- Generate 10 ME/tick
end,
},
})

16
modules/power/init.lua Normal file
View File

@ -0,0 +1,16 @@
-- power/init.lua
local me = microexpansion
local networks = me.networks
local path = microexpansion.get_module_path("power")
me.power = {}
local power = me.power
-- Load Resources
dofile(path.."/network.lua") -- Network Management
dofile(path.."/register.lua") -- Machine Registration
dofile(path.."/ctrl.lua") -- Controller/wires
dofile(path.."/gen.lua") -- Generators

244
modules/power/network.lua Normal file
View File

@ -0,0 +1,244 @@
-- power/network.lua
local me = microexpansion
---
--- Helper Functions
---
-- [local function] Renumber table
local function renumber_table(t)
local result = {}
for _, value in pairs(t) do
result[#result+1] = value
end
return result
end
-- [local function] Get netitem by position
local function get_netitem_by_pos(list, pos)
for _, i in pairs(list) do
if vector.equals(pos, i.pos) then
return i
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 me.power.new_id()
local count = 1
for _, i in pairs(me.networks) do
count = count + 1
end
return "network_"..count
end
-- [function] Can connect
function me.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 me.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
-- [function] Add machine to network
function me.power.add_machine(pos, def)
end
-- [function] Remove machine from network
function me.power.remove_machine(pos)
local meta = minetest.get_meta(pos)
meta:set_string("network_ignore", "true")
end
-- [function] Trace network
function me.power.trace(pos)
local netpos = me.networks[minetest.get_meta(pos):get_string("network_id")]
-- if no network, return
if not netpos then
return
end
local meta = minetest.get_meta(netpos)
local netid = meta:get_string("network_id")
local list = {}
local demand
local delete = false
if meta:get_string("network_ignore") == "true" then
delete = true
end
-- [local function] Indexed
local function indexed(pos)
for _, i in pairs(list) do
if vector.equals(pos, i.pos) then
return true
end
end
end
-- [local function] Trace
local function trace(nodes)
for _, pos in pairs(nodes) do
if not indexed(pos) then
local machine = minetest.get_meta(pos)
if machine:get_string("network_ignore") ~= "true" then
local node = me.get_node(pos).name
local desc = minetest.registered_nodes[node].description
if delete then
machine:set_string("network_id", nil)
machine:set_string("infotext", desc.."\nNo Network")
me.network_set_demand(pos, 0)
else
machine:set_string("network_id", netid)
machine:set_string("infotext", desc.."\nNetwork ID: "..netid)
end
list[#list + 1] = { pos = pos, demand = machine:get_int("demand") }
trace(power.get_connected_nodes(pos, false))
end
end
end
end
trace(power.get_connected_nodes(netpos))
-- Check original list
local original = minetest.deserialize(meta:get_string("netitems"))
if original then
for _, i in pairs(original) do
if not indexed(i.pos) then
local node = me.get_node(i.pos).name
local desc = minetest.registered_nodes[node].description
local machine = minetest.get_meta(i.pos)
machine:set_string("network_id", nil)
machine:set_string("infotext", desc.."\nNo Network")
me.network_set_demand(pos, 0)
end
end
end
meta:set_string("netitems", minetest.serialize(list))
-- Update infotext
meta:set_string("infotext", "Network Controller (owned by "..
meta:get_string("owner")..")\nNetwork ID: "..meta:get_string("network_id")..
"\nDemand: "..dump(me.network_get_demand(netpos)))
end
---
--- Load Management
---
-- [function] Get load information
function me.network_get_load(pos)
local ctrl = me.networks[minetest.get_meta(pos):get_string("network_id")]
if ctrl then
local meta = minetest.get_meta(ctrl)
local list = minetest.deserialize(meta:get_string("netitems"))
end
end
---- Generators ----
---- Output ----
-- [function] Get total network demand
function me.network_get_demand(pos)
local ctrl = me.networks[minetest.get_meta(pos):get_string("network_id")]
-- if no network, return
if not ctrl then
return
end
local meta = minetest.get_meta(ctrl)
local list = minetest.deserialize(meta:get_string("netitems"))
local demand = 0
for _, i in pairs(list) do
if i.demand then
demand = demand + i.demand
end
end
return demand
end
-- [function] Set demand for machine
function me.network_set_demand(pos, demand)
-- Update original metadata
minetest.get_meta(pos):set_int("demand", demand)
local ctrl = me.networks[minetest.get_meta(pos):get_string("network_id")]
-- if no network, return
if not ctrl then
return
end
local meta = minetest.get_meta(ctrl)
local list = minetest.deserialize(meta:get_string("netitems"))
local item = get_netitem_by_pos(list, pos)
if not item then
return
end
item.demand = demand
meta:set_string("netitems", minetest.serialize(list))
-- Update infotext
meta:set_string("infotext", "Network Controller (owned by "..
meta:get_string("owner")..")\nNetwork ID: "..meta:get_string("network_id")..
"\nDemand: "..dump(me.network_get_demand(pos)))
end
---- Storage ----

View File

@ -0,0 +1,88 @@
-- power/register.lua
--[[ Machine Registration API ]]
local me = microexpansion
local power = me.power
-- [function] Register machine
function me.register_machine(itemstring, def)
-- Set after_place_node
def.after_place_node = function(pos, player)
if def.after_place_node then
def.after_place_node(pos, player)
end
local meta = minetest.get_meta(pos)
local nodes = me.get_connected_nodes(pos)
meta:set_string("infotext", def.description.."\nNo Network")
for _, pos2 in pairs(nodes) do
local id = minetest.get_meta(pos2):get_string("network_id")
if id ~= "" then
meta:set_string("infotext", def.description.."\nNetwork ID: "..id)
meta:set_string("network_id", id)
end
end
-- Trace Network
power.trace(pos)
-- Set demand
if def.demand then
me.network_set_demand(pos, def.demand)
end
if type(def.machine) == "table" then
power.add_machine(pos, def.machine)
end
end
-- Set on_destruct
def.on_destruct = function(pos, player)
if def.on_destruct then
def.on_destruct(pos, player)
end
local meta = minetest.get_meta(pos)
if meta:get_string("network_id") ~= "" then
-- Set demand
me.network_set_demand(pos, 0)
-- Remove item from network
me.network_remove(pos)
-- Retrace Network
power.trace(pos)
end
end
-- Set connects_to
def.connects_to = {"group:me_connect"}
-- Set me_connect group
def.groups = def.groups or {}
def.groups.me_connect = 1
me.register_node(itemstring, def)
end
-- [function] Get machine definition
function me.get_def(name, key)
if type(name) == "table" then
local node = me.get_node(name)
if node then
name = node.name
end
end
local def = minetest.registered_nodes[name]
-- Check name and if registered
if not name or not def then
return
end
if key then
return def[key]
else
return def
end
end

30
modules/shared/init.lua Normal file
View File

@ -0,0 +1,30 @@
-- shared/init.lua
local me = microexpansion
-- This mostly contains items that are used by multiple modules and
-- don't really fit with anything else.
-- [register item] Steel Infused Obsidian Ingot
me.register_item("steel_infused_obsidian_ingot", {
description = "Steel Infused Obsidian Ingot",
recipe = {
{ 1, {
{ "default:steel_ingot", "default:obsidian_shard", "default:steel_ingot" },
},
},
},
})
-- [register item] Machine Casing
me.register_item("machine_casing", {
description = "Machine Casing",
recipe = {
{ 1, {
{"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"},
{"default:steel_ingot", "default:copper_ingot", "default:steel_ingot"},
{"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"},
},
},
},
})

View File

@ -4,94 +4,97 @@ local BASENAME = "microexpansion"
-- [function] register cell
function microexpansion.register_cell(itemstring, def)
if not def.inventory_image then
def.inventory_image = itemstring
end
if not def.inventory_image then
def.inventory_image = itemstring
end
-- register craftitem
minetest.register_craftitem(BASENAME..":"..itemstring, {
description = def.description,
inventory_image = BASENAME.."_"..def.inventory_image..".png",
groups = {microexpansion_cell = 1},
stack_max = 1,
microexpansion = {
base_desc = def.description,
drive = {
capacity = def.capacity or 5000,
},
},
})
-- register craftitem
minetest.register_craftitem(BASENAME..":"..itemstring, {
description = def.description,
inventory_image = BASENAME.."_"..def.inventory_image..".png",
groups = {microexpansion_cell = 1},
stack_max = 1,
microexpansion = {
base_desc = def.description,
drive = {
capacity = def.capacity or 5000,
},
},
})
-- if recipe, register recipe
if def.recipe then
-- if recipe, register recipe
if def.recipe then
microexpansion.register_recipe(BASENAME..":"..itemstring, def.recipe)
end
end
-- if recipe, register recipe
if def.recipe then
-- if recipe, register recipe
if def.recipe then
microexpansion.register_recipe(BASENAME..":"..itemstring, def.recipe)
end
end
end
-- [function] Get cell size
function microexpansion.get_cell_size(name)
local item = minetest.registered_craftitems[name]
if item then
return item.microexpansion.drive.capacity
end
local item = minetest.registered_craftitems[name]
if item then
return item.microexpansion.drive.capacity
end
end
-- [function] Calculate max stacks
function microexpansion.int_to_stacks(int)
return math.floor(int / 99)
return math.floor(int / 99)
end
-- [function] Calculate number of pages
function microexpansion.int_to_pagenum(int)
return math.floor(microexpansion.int_to_stacks(int) / 32)
return math.floor(microexpansion.int_to_stacks(int) / 32)
end
-- [function] Move items from inv to inv
function microexpansion.move_inv(inv1, inv2)
local finv, tinv = inv1.inv, inv2.inv
local fname, tname = inv1.name, inv2.name
local finv, tinv = inv1.inv, inv2.inv
local fname, tname = inv1.name, inv2.name
for i,v in ipairs(finv:get_list(fname) or {}) do
if tinv and tinv:room_for_item(tname, v) then
local leftover = tinv:add_item( tname, v )
finv:remove_item(fname, v)
if leftover and not(leftover:is_empty()) then
finv:add_item(fname, v)
end
end
end
for i,v in ipairs(finv:get_list(fname) or {}) do
if tinv and tinv:room_for_item(tname, v) then
local leftover = tinv:add_item( tname, v )
finv:remove_item(fname, v)
if leftover and not(leftover:is_empty()) then
finv:add_item(fname, v)
end
end
end
end
-- [function] Update cell description
function microexpansion.cell_desc(inv, listname, spos)
local stack = inv:get_stack(listname, spos)
local stack = inv:get_stack(listname, spos)
if stack:get_name() ~= "" then
local meta = stack:get_meta()
local base_desc = minetest.registered_craftitems[stack:get_name()].microexpansion.base_desc
local max_slots = inv:get_size("main")
local max_items = math.floor(max_slots * 99)
if stack:get_name() ~= "" then
local meta = stack:get_meta()
local base_desc = minetest.registered_craftitems[stack:get_name()].microexpansion.base_desc
local max_slots = inv:get_size("main")
local max_items = math.floor(max_slots * 99)
local slots, items = 0, 0
-- Get amount of items in drive
for i = 1, max_items do
local stack = inv:get_stack("main", i)
local item = stack:get_name()
if item ~= "" then
slots = slots + 1
local num = stack:get_count()
if num == 0 then num = 1 end
items = items + num
end
end
local slots, items = 0, 0
-- Get amount of items in drive
for i = 1, max_items do
local stack = inv:get_stack("main", i)
local item = stack:get_name()
if item ~= "" then
slots = slots + 1
local num = stack:get_count()
if num == 0 then num = 1 end
items = items + num
end
end
-- Update description
meta:set_string("description", base_desc.."\n"..
minetest.colorize("grey", tostring(items).."/"..tostring(max_items).." Items"))
-- Update stack
inv:set_stack(listname, spos, stack)
-- Calculate Percentage
local percent = math.floor(items / max_items * 100)
-- Update description
meta:set_string("description", base_desc.."\n"..
minetest.colorize("grey", tostring(items).."/"..tostring(max_items).." Items ("..tostring(percent).."%)"))
-- Update stack
inv:set_stack(listname, spos, stack)
end
end

View File

@ -6,20 +6,29 @@ local me = microexpansion
local function chest_formspec(pos, start_id, listname, page_max, query)
local list
local page_number = ""
local to_chest = ""
local buttons = ""
local query = query or ""
if not listname then
list = "label[3,2;" .. minetest.colorize("red", "No cell!") .. "]"
else
list = "list[current_name;" .. listname .. ";0,0.3;8,4;" .. (start_id - 1) .. "]"
to_chest = [[
buttons = [[
button[3.56,4.35;1.8,0.9;tochest;To Drive]
tooltip[tochest;Move everything from your inventory to the ME drive.]
button[5.4,4.35;0.8,0.9;prev;<]
button[7.25,4.35;0.8,0.9;next;>]
tooltip[prev;Previous]
tooltip[next;Next]
field[0.29,4.6;2.2,1;filter;;]]..query..[[]
button[2.1,4.5;0.8,0.5;search;?]
button[2.75,4.5;0.8,0.5;clear;X]
tooltip[search;Search]
tooltip[clear;Reset]
]]
end
if page_max then
page_number = "label[6.05,4.5;" .. math.floor((start_id / 32)) + 1 ..
page_number = "label[6.15,4.5;" .. math.floor((start_id / 32)) + 1 ..
"/" .. page_max .."]"
end
@ -34,19 +43,12 @@ local function chest_formspec(pos, start_id, listname, page_max, query)
list[current_name;cells;8.06,1.8;1,1;]
list[current_player;main;0,5.5;8,1;]
list[current_player;main;0,6.73;8,3;8]
button[5.4,4.35;0.8,0.9;prev;<]
button[7.25,4.35;0.8,0.9;next;>]
field[0.3,4.6;2.2,1;filter;;]]..query..[[]
button[2.1,4.5;0.8,0.5;search;?]
button[2.75,4.5;0.8,0.5;clear;X]
tooltip[search;Search]
tooltip[clear;Reset]
listring[current_name;main]
listring[current_player;main]
field_close_on_enter[filter;false]
]]..
page_number ..
to_chest
buttons
end
-- [me chest] Register node

View File

@ -2,6 +2,24 @@
-- [drive] 8k
microexpansion.register_cell("cell_8k", {
description = "8k ME Storage Cell",
capacity = 8000,
description = "8k ME Storage Cell",
capacity = 8000,
})
-- [drive] 16k
microexpansion.register_cell("cell_16k", {
description = "16k ME Storage Cell",
capacity = 16000,
})
-- [drive] 32k
microexpansion.register_cell("cell_32k", {
description = "32k ME Storage Cell",
capacity = 32000,
})
-- [drive] 64k
microexpansion.register_cell("cell_64k", {
description = "64k ME Storage Cell",
capacity = 64000,
})

6
modules/tools/init.lua Normal file
View File

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

29
modules/tools/xtremo.lua Normal file
View File

@ -0,0 +1,29 @@
-- 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},
},
})

Binary file not shown.

Before

Width:  |  Height:  |  Size: 696 KiB

After

Width:  |  Height:  |  Size: 213 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 255 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 555 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 547 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 543 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 333 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 247 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 339 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 317 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 391 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 418 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 326 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 459 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 309 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 252 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 315 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 369 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 328 B