Skip to content

Commit

Permalink
Merge pull request #14 from mt-mods/feature-update
Browse files Browse the repository at this point in the history
Add enough features to allow "playing" technic
  • Loading branch information
S-S-X authored Mar 14, 2021
2 parents dc879ea + 72cbede commit 237fe13
Show file tree
Hide file tree
Showing 12 changed files with 636 additions and 117 deletions.
13 changes: 13 additions & 0 deletions .github/workflows/mineunit.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@

name: mineunit

on: [push, pull_request]

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: mt-mods/mineunit-actions@badger
with:
badge-secret: ${{ secrets.MineunitBadgesAPIKey }}
112 changes: 112 additions & 0 deletions assert.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@

local function round(value)
return (value < 0) and math.ceil(value - 0.5) or math.floor(value + 0.5)
end

local function sequential(t)
local p = 1
for i,_ in pairs(t) do
if i ~= p then return false end
p = p + 1
end
return true
end

local function count(t)
if type(t) == "table" or type(t) == "userdata" then
local c = 0
for a,b in pairs(t) do
c = c + 1
end
return c
end
mineunit:warning("count(t)", "invalid value", type(t))
end

local function tabletype(t)
if type(t) == "table" or type(t) == "userdata" then
if count(t) == #t and sequential(t) then
return "array"
else
return "hash"
end
end
mineunit:warning("tabletype(t)", "invalid value", type(t))
end

local function in_array(value, t)
for _, v in ipairs(t) do
if v == value then
return true
end
end
return false
end

local lua_type = type

local function mineunit_type(obj)
return lua_type(obj) == "table" and lua_type(obj._mineunit_typename) == "string" and obj._mineunit_typename
end

function type(value)
return mineunit_type(value) and "userdata" or lua_type(value)
end

-- Mineunit luassert extensions

local assert = require('luassert.assert')
local say = require("say")

local function is_table(_,args) return lua_type(args[1]) == "table" end
say:set("assertion.is_table.negative", "Expected %s to be table")
assert:register("assertion", "is_table", is_table, "assertion.is_table.negative")

local function is_array(_,args) return tabletype(args[1]) == "array" end
say:set("assertion.is_indexed.negative", "Expected %s to be indexed array")
assert:register("assertion", "is_indexed", is_array, "assertion.is_indexed.negative")

local function is_hash(_,args) return tabletype(args[1]) == "hash" end
say:set("assertion.is_hashed.negative", "Expected %s to be hash table")
assert:register("assertion", "is_hashed", is_hash, "assertion.is_hashed.negative")

local function more(_,args) return args[1] > args[2] end
say:set("assertion.more.negative", "Expected %s to be more than %s")
assert:register("assertion", "more", more, "assertion.more.negative")

local function less(_,args) return args[1] < args[2] end
say:set("assertion.less.negative", "Expected %s to be less than %s")
assert:register("assertion", "less", less, "assertion.less.negative")

local function check_in_array(_,args) return in_array(args[1], args[2]) end
say:set("assertion.in_array.negative", "Expected %s to be in array %s")
assert:register("assertion", "in_array", check_in_array, "assertion.in_array.negative")

local mineunit_types = {
"ItemStack",
"InvList",
"InvRef",
"MetaDataRef",
"NodeMetaRef",
"Player"
}
for _, typename in ipairs(mineunit_types) do
local assertname = "is_" .. typename
local function checktype(_,args) return mineunit_type(args[1]) == typename end
say:set("assertion."..assertname..".negative", "Expected %s to be "..typename)
assert:register("assertion", assertname, checktype, "assertion."..assertname..".negative")
end

-- Replace builtin assert with luassert

_G.assert = assert

-- TODO: Something wrong with this

return {
sequential = sequential,
count = count,
tabletype = tabletype,
round = round,
type = mineunit_type
}
2 changes: 2 additions & 0 deletions bin/mineunit
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,8 @@ do -- Parse cli args
args.report = true
elseif v == "-v" or v == "--verbose" then
args.verbose = true
elseif v == "-q" or v == "--quiet" then
mineunit_conf_override = { print = false, verbose = 1 }
elseif v == "-x" or v == "--exclude" then
i = i + 1
if not arg[i] then
Expand Down
19 changes: 10 additions & 9 deletions common/misc_helpers.lua
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ local function basic_dump(o)
-- dump's output is intended for humans.
--elseif tp == "function" then
-- return string.format("loadstring(%q)", string.dump(o))
elseif tp == "userdata" then
return tostring(o)
else
return string.format("<%s>", tp)
end
Expand Down Expand Up @@ -290,7 +292,8 @@ if INIT == "game" then
return
end
local undef = core.registered_nodes[unode.name]
if undef and undef.on_rightclick then
local sneaking = placer and placer:get_player_control().sneak
if undef and undef.on_rightclick and not sneaking then
return undef.on_rightclick(pointed_thing.under, unode, placer,
itemstack, pointed_thing)
end
Expand Down Expand Up @@ -344,18 +347,12 @@ if INIT == "game" then
--Wrapper for rotate_and_place() to check for sneak and assume Creative mode
--implies infinite stacks when performing a 6d rotation.
--------------------------------------------------------------------------------
local creative_mode_cache = core.settings:get_bool("creative_mode")
local function is_creative(name)
return creative_mode_cache or
core.check_player_privs(name, {creative = true})
end

core.rotate_node = function(itemstack, placer, pointed_thing)
local name = placer and placer:get_player_name() or ""
local invert_wall = placer and placer:get_player_control().sneak or false
return core.rotate_and_place(itemstack, placer, pointed_thing,
is_creative(name),
{invert_wall = invert_wall}, true)
core.is_creative_enabled(name),
{invert_wall = invert_wall}, true)
end
end

Expand Down Expand Up @@ -700,3 +697,7 @@ function core.privs_to_string(privs, delim)
end
return table.concat(list, delim)
end

function core.is_nan(number)
return number ~= number
end
4 changes: 4 additions & 0 deletions core.lua
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ local noop_object = {

_G.world = mineunit("world")

_G.core.set_node = world.set_node
_G.core.swap_node = world.swap_node

_G.core.get_worldpath = function(...) return _G.mineunit:get_worldpath(...) end
_G.core.get_modpath = function(...) return _G.mineunit:get_modpath(...) end
_G.core.get_current_modname = function(...) return _G.mineunit:get_current_modname(...) end
Expand Down Expand Up @@ -60,6 +63,7 @@ end

_G.minetest.after = noop

_G.minetest.find_nodes_with_meta = _G.world.find_nodes_with_meta
_G.minetest.get_node_or_nil = function(pos)
local hash = minetest.hash_node_position(pos)
return world.nodes[hash]
Expand Down
114 changes: 100 additions & 14 deletions globals.lua
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,31 @@

-- Data

local registered_crafts = {}
function mineunit.registered_craft_recipe(key)
return registered_crafts[key] and registered_crafts[key].recipe
local registered_crafts = {
normal = {},
cooking = {},
fuel = {}
}
function mineunit.registered_craft_recipe(output, method)
local crafts = registered_crafts[method or "normal"][output]
return crafts and crafts[1] and crafts[1].recipe
end

local function push_craft(method, output, data)
if not registered_crafts[method][output] then
registered_crafts[method][output] = {}
end
table.insert(registered_crafts[method][output], data)
end

local function recipe_to_craft(method, recipe)
for output, crafts in pairs(registered_crafts[method]) do
for _, craft in ipairs(crafts) do
if craft.recipe == recipe then
return craft
end
end
end
end

-- Libraries
Expand All @@ -23,52 +45,116 @@ DIR_DELIM = "/"

-- Engine API

_G.core = {}
_G.core.log = function(...) mineunit:info(...) end
_G.core.request_http_api = function(...) end
local core = {}
_G.core = core

function core.log(...) mineunit:info(...) end
function core.request_http_api(...) end

_G.core.register_craft = function(t)
function core.get_timeofday()
return 0.5
end

function core.get_node_light(pos, timeofday)
timeofday = timeofday or 0.5
return mineunit.utils.round(math.sin(timeofday * 3.14) * 15)
end

function core.register_craft(t)
assert.is_table(t, "core.register_craft: table expected, got " .. type(t))
if t.type == nil then
assert.is_string(t.output, "core.register_craft: t.output string expected, got " .. type(t.output))
assert.is_indexed(t.recipe, "core.register_craft: t.recipe indexed array expected, got " .. type(t.recipe))
registered_crafts[t.output] = t
push_craft("normal", t.output, t)
elseif t.type == "shapeless" then
assert.is_string(t.output, "core.register_craft: t.output string expected, got " .. type(t.output))
assert.is_indexed(t.recipe, "core.register_craft: t.recipe indexed array expected, got " .. type(t.recipe))
registered_crafts[t.output] = t
push_craft("normal", t.output, t)
elseif t.type == "toolrepair" then
if t.additional_wear ~= nil then
assert.is_number(t.additional_wear, "core.register_craft: t.additional_wear number expected, got " .. type(t.additional_wear))
end
mineunit:warning("RECIPE TYPE toolrepair NOT SAVED", dump(t))
-- TODO: Store registered toolrepair recipes
elseif t.type == "cooking" then
assert.is_string(t.output, "core.register_craft: t.output string expected, got " .. type(t.output))
assert.is_string(t.recipe, "core.register_craft: t.recipe string expected, got " .. type(t.recipe))
if t.cooktime ~= nil then
assert.is_number(t.cooktime, "core.register_craft: t.cooktime number expected, got " .. type(t.cooktime))
end
t.cooktime = t.cooktime or 3
if t.replacements then
assert.is_indexed(t.replacements, "core.register_craft: t.replacements indexed table expected, got " .. type(t.replacements))
end
-- TODO: Store registered cooking recipes
push_craft("cooking", t.output, t)
elseif t.type == "fuel" then
assert.is_string(t.recipe, "core.register_craft: t.recipe string expected, got " .. type(t.recipe))
if t.burntime ~= nil then
assert.is_number(t.burntime, "core.register_craft: t.burntime number expected, got " .. type(t.burntime))
end
-- TODO: Store registered fuel recipes
t.burntime = t.burntime or 1
push_craft("fuel", t.burntime, t)
else
error("Recipe type not supported: " .. tostring(t.type))
end
end

_G.core.clear_craft = function(t)
function core.clear_craft(t)
assert.is_table(t, "core.clear_craft: table expected, got " .. type(t))
assert.not_nil(t.recipe or t.output, "core.clear_craft: recipe or output required")
assert.is_nil(t.recipe and t.output, "core.clear_craft: please specify only recipe or output but not both")
end

local function is_ItemStack(obj)
return mineunit.utils.type(obj) == "ItemStack"
end

function core.get_craft_result(t)
assert.is_hashed(t, "core.get_craft_result: hash table expected, got " .. type(t))
if t.method ~= nil then
assert.in_array(t.method, {"normal","cooking","fuel"}, "core.get_craft_result: t.method invalid value")
end
t.method = t.method or "normal"
assert.is_table(t.items, "core.get_craft_result: t.items table expected, got " .. type(t.items))
if not is_ItemStack(t.items) then
assert(#t.items > 0, "core.get_craft_result: t.items is empty")
for k, v in ipairs(t.items) do
assert.is_ItemStack(v, "core.get_craft_result: t.items["..k.."] ItemStack expected")
end
end
local items = is_ItemStack(t.items) and {t.items} or t.items
for _, item in ipairs(items) do
assert.is_ItemStack(item, "core.get_craft_result: invalid item type in items, ItemStack expected")
local craft = recipe_to_craft(t.method, item:get_name())
if craft then
local new_input = ItemStack(item)
new_input:set_count(new_input:get_count()-1)
return
{
item = ItemStack(craft.output),
time = craft.cooktime,
replacements = craft.replacements or {},
},
{
items = {
new_input
},
method = t.method,
width = 1
}
end
end
error("FAILED")
return {
item = ItemStack(),
time = 0,
replacements = nil,
decremented_input = {
items = ItemStack()
}
}
end

local origin
_G.core.get_last_run_mod = function() return origin end
_G.core.set_last_run_mod = function(v) origin = v end
function core.get_last_run_mod() return origin end
function core.set_last_run_mod(v) origin = v end
Loading

0 comments on commit 237fe13

Please sign in to comment.