Compare commits

...

5 Commits

Author SHA1 Message Date
rubenwardy 297352dcdc Add date time mod 2019-07-25 13:01:24 +01:00
rubenwardy 5bd40f6d62 Add prices to land debug GUI 2019-07-25 12:01:14 +01:00
rubenwardy 004604d036 Add property tax calculation 2019-07-23 19:29:27 +01:00
rubenwardy c577db0481 Add land valuation 2019-07-21 12:48:49 +01:00
rubenwardy 3c962d0f47 Adopt real_coordinates[] 2019-07-21 11:58:18 +01:00
22 changed files with 562 additions and 69 deletions

View File

@ -4,6 +4,7 @@ allow_defined_top = true
exclude_files = {
"mods/mtg",
"mods/libs/lib_chatcmdbuilder",
"mods/libs/lib_utils/vector.lua",
"mods/mechanics",
"mods/areas",
"mods/craftguide",
@ -13,7 +14,8 @@ globals = {
"minetest", "company",
"areas", "sfinv",
"shop",
ChatCmdBuilder = {fields = {"types"}}
ChatCmdBuilder = {fields = {"types"}},
vector = { fields = {"sqdist"}},
}
read_globals = {

View File

@ -7,7 +7,6 @@ graph LR
CementChunk[Cement chunk]
ConcreteBlock[Concrete block]
Sand -- Furnace --> Glass
Sand -- Furnace --> Silicon

View File

@ -7,6 +7,6 @@ company.register_panel({
title = "Finance",
bgcolor = "#DAA520",
get = function(_, _, comp, _)
return "label[0.2,0.2;" .. minetest.formspec_escape("Balance: " .. banking.get_balance(comp)) .. "]"
return "label[0,0.3;" .. minetest.formspec_escape("Balance: " .. banking.get_balance(comp)) .. "]"
end,
})

View File

@ -16,13 +16,15 @@ company.show_company_select_dialog = lib_quickfs.register("company:set_company",
if #comps == 0 then
formspec = {
"size[4,5]",
"label[0,-0.1;You're not a member of any companies]",
"real_coordinates[true]",
"label[0.3,0.3;You're not a member of any companies]",
}
else
formspec = {
"size[4,5]",
"label[0,-0.1;Select a Company]",
"textlist[-0.1,0.5;4,4;companies;",
"size[5.5,6.75]",
"real_coordinates[true]",
"label[0.375,0.375;Select a Company]",
"textlist[0.375,0.75;4.75,4.75;companies;",
table.concat(_.map(comps, function(comp)
if comp:get_ceo_name() == pname then
return minetest.formspec_escape(comp.title)
@ -31,8 +33,8 @@ company.show_company_select_dialog = lib_quickfs.register("company:set_company",
end
end), ","),
";1;false]",
"button[0,4.5;2,1;back;Back]",
"button[2,4.5;2,1;switch;Switch]",
"button[0.375,5.875;2.1875,0.5;back;Back]",
"button[2.9375,5.875;2.1875,0.5;switch;Switch]",
}
end
@ -54,7 +56,7 @@ company.show_company_select_dialog = lib_quickfs.register("company:set_company",
local comp_name = context.comps[context.idx or 1]
company.set_active(name, comp_name)
ret(player)
elseif not (fields.quit ~= "" or fields.back) then
elseif fields.quit ~= "" or fields.back then
ret(player)
return
end
@ -83,16 +85,18 @@ company.show_company_house = lib_quickfs.register("company:house", {
end
local fs = {
"size[6,5.1]",
company.get_company_header(pname, 6, 4.1),
"field[0.3,2.1;6,1;title;Title;", minetest.formspec_escape(data.title), "]",
"button[1,3.5;2,1;cancel;Cancel]",
"button[3,3.5;2,1;save;Save]",
"size[6,4.5]",
"real_coordinates[true]",
company.get_company_header(pname, 6, 3.5),
"field[0.375,1.8;5.25,0.5;title;Title;", minetest.formspec_escape(data.title), "]",
"button[0.625,2.675;2,0.5;cancel;Cancel]",
"button[3.375,2.675;2,0.5;save;Save]",
}
context.error = "incorrect thing"
if context.error then
fs[#fs + 1] = "box[-0.3,3.05;6.4,0.4;#f00]"
fs[#fs + 1] = "label[0,3;"
fs[#fs + 1] = "box[0,0;6,0.4;#f00]"
fs[#fs + 1] = "label[0.3,0.11;"
fs[#fs + 1] = minetest.formspec_escape(context.error)
fs[#fs + 1] = "]"
@ -100,26 +104,23 @@ company.show_company_house = lib_quickfs.register("company:house", {
end
if context.is_new then
fs[#fs + 1] = "field[0.3,0.6;6,1;name;Name;"
fs[#fs + 1] = "field[0.375,0.375;5.25,0.5;name;Name;"
fs[#fs + 1] = minetest.formspec_escape(data.name)
fs[#fs + 1] = "]"
else
fs[#fs + 1] = "label[0,0;Name]"
fs[#fs + 1] = "label[0.05,0.5;"
fs[#fs + 1] = "label[0.6,0.5;Name]"
fs[#fs + 1] = "label[0.6,0.575;"
fs[#fs + 1] = minetest.formspec_escape(data.name)
fs[#fs + 1] = "]"
fs[#fs + 1] = "box[0,0.4;5.8,0.66;#111]"
fs[#fs + 1] = "box[0.375,0.375;5.25,1;#111]"
end
return table.concat(fs, "")
end,
on_receive_fields = function(context, player, fields, comp)
if fields.switch then
company.show_company_select_dialog(player:get_player_name(), function(player2)
local pname = player2:get_player_name()
company.show_company_house(pname, comp and company.get_active(pname))
end)
if fields.cancel then
sfinv.set_page_and_show(player, "company:company")
return false
end
@ -153,17 +154,17 @@ function company.get_company_header(pname, width, y, snippet)
end
return table.concat({
"container[0,", tostring(y + 0.45), "]",
"box[-0.3,-0.1;", tostring(width + 0.4), ",1.1;#222]",
"label[0.1,0.0;",
"container[0,", tostring(y), "]",
"box[0,0;", tostring(width), ",1;#222]",
"label[0.375,0.33;",
minetest.formspec_escape(comp and comp.title or "No active company"),
"]",
"label[0.1,0.4;",
"label[0.375,0.66;",
snippet_text,
"]",
"button[",
tostring(width - 2),
",0;2,1;switch;Switch]",
tostring(width - 2.25),
",0.25;2,0.5;switch;Switch]",
"container_end[]",
}, "")
end
@ -176,7 +177,8 @@ sfinv.register_page("company:company", {
-- Using an array to build a formspec is considerably faster
local formspec = {
company.get_company_header(pname, 8, 7.6)
"real_coordinates[true]",
company.get_company_header(pname, 10.5, 9),
}
if comp then
@ -184,21 +186,28 @@ sfinv.register_page("company:company", {
for _, panel in pairs(company.registered_panels) do
if not panel.show_to or panel:show_to(player, comp, context) then
formspec[#formspec + 1] = "container["
formspec[#formspec + 1] = tostring((i % 2) * 4)
formspec[#formspec + 1] = tostring((i % 2) * 5.0625 + 0.375)
formspec[#formspec + 1] = ","
formspec[#formspec + 1] = tostring(math.floor(i / 2) * 2)
formspec[#formspec + 1] = tostring(math.floor(i / 2) * 2.15625 + 0.375)
formspec[#formspec + 1] = ".3]"
formspec[#formspec + 1] = "label[1.5,-0.3;"
formspec[#formspec + 1] = "style[title_"
formspec[#formspec + 1] = panel.name
formspec[#formspec + 1] = ";border=false;bgimg=;bgimg_pressed=]"
formspec[#formspec + 1] = "button[0,0;4.6875,0.5;title_"
formspec[#formspec + 1] = panel.name
formspec[#formspec + 1] = ";"
formspec[#formspec + 1] = panel.title
formspec[#formspec + 1] = "]"
formspec[#formspec + 1] = "box[0,-0.3;3.8,1.8;"
formspec[#formspec + 1] = "box[0,0;4.6875,1.78125;"
formspec[#formspec + 1] = panel.bgcolor
formspec[#formspec + 1] = "]"
formspec[#formspec + 1] = "container[0.25,0.25]"
formspec[#formspec + 1] = panel:get(player, comp, context)
formspec[#formspec + 1] = "container_end[]"
formspec[#formspec + 1] = "container_end[]container_end[]"
i = i + 1
end
@ -206,10 +215,10 @@ sfinv.register_page("company:company", {
while i < 2*4 do
formspec[#formspec + 1] = "box["
formspec[#formspec + 1] = tostring((i % 2) * 4)
formspec[#formspec + 1] = tostring((i % 2) * 5.0625 + 0.375)
formspec[#formspec + 1] = ","
formspec[#formspec + 1] = tostring(math.floor(i / 2) * 2)
formspec[#formspec + 1] = ";3.8,1.8;#111]"
formspec[#formspec + 1] = tostring(math.floor(i / 2) * 2.15625 + 0.375)
formspec[#formspec + 1] = ";4.6875,1.78125;#111]"
i = i + 1
end
@ -255,7 +264,7 @@ company.register_panel({
title = "Company House",
bgcolor = "#369",
get = function(_, _, _, _)
return "button[1,0.6;2,1;edit_details;Edit Details]"
return "button[1.05,0.75;2,0.5;edit_details;Edit Details]"
end,
on_player_receive_fields = function(player, context, fields)
if fields.edit_details then
@ -278,7 +287,7 @@ company.register_panel({
memcount = memcount + 1
end
return "label[0.2,0.2;" .. memcount .. " members]"
return "label[0,0.3;" .. memcount .. " members]"
end,
})

View File

@ -0,0 +1,80 @@
function gametime.get()
local days = minetest.get_day_count()
local years = math.floor(days / 360)
days = days - years * 360
local months = math.floor(days / 12)
days = days - months * 12
assert(days < 30)
return {
year = years + 1900,
month = months + 1,
day = days + 1,
}
end
local MONTH_NAMES = {
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December",
}
function gametime.get_formatted()
local date = gametime.get()
local month_name = MONTH_NAMES[date.month]
return ("%02d-%s-%04d"):format(date.day, month_name, date.year)
end
local _registered_on_day_change = {}
local _registered_on_month_change = {}
local _registered_on_year_change = {}
function gametime.register_on_day_change(func)
table.insert(_registered_on_day_change, func)
end
function gametime.register_on_month_change(func)
table.insert(_registered_on_month_change, func)
end
function gametime.register_on_year_change(func)
table.insert(_registered_on_year_change, func)
end
local _lastcount = minetest.get_day_count()
local function on_interval()
local cur = minetest.get_day_count()
if _lastcount == cur then
return
end
_lastcount = cur
local curdate = gametime.get()
for i=1, #_registered_on_day_change do
_registered_on_day_change[i](cur, curdate)
end
if curdate.day == 1 then
for i=1, #_registered_on_month_change do
_registered_on_month_change[i](cur, curdate)
end
if curdate.month == 1 then
for i=1, #_registered_on_year_change do
_registered_on_year_change[i](cur, curdate)
end
end
end
end
lib_utils.interval(2, on_interval)

View File

@ -0,0 +1,31 @@
local hud = hudkit()
local function update_datetime(player)
local date = gametime.get_formatted()
local tod = minetest.get_timeofday()
local hours = math.floor(tod * 24)
local minutes = math.floor(tod * 1440 - hours * 60)
local datetime = ("%s %02d:%02d"):format(date, hours, minutes)
if not hud:exists(player, "gametime:datetime") then
hud:add(player, "gametime:datetime", {
hud_elem_type = "text",
position = {x = 0.5, y = 0},
scale = {x = 100, y = 100},
text = datetime,
number = 0xFFFFFF,
offset = {x = 0, y = 20},
alignment = {x = 0, y = 0}
})
else
hud:change(player, "gametime:datetime", "text", datetime)
end
end
minetest.register_on_joinplayer(update_datetime)
lib_utils.interval(1, function()
local players = minetest.get_connected_players()
for i=1, #players do
update_datetime(players[i])
end
end)

View File

@ -0,0 +1,6 @@
gametime = {}
dofile(minetest.get_modpath("gametime") .. "/api.lua")
dofile(minetest.get_modpath("gametime") .. "/gui.lua")
minetest.settings:set("time_speed", "51.429")

View File

@ -0,0 +1,2 @@
name = gametime
depends = lib_utils, hudkit

View File

@ -136,6 +136,26 @@ function land.get_by_area_id(id)
end
--- Get zone for a plot
--
-- Gets the base zone for a particular area
function land.get_zone(area)
assert(type(area) == "table")
local zone = area
while zone do
local next = areas.areas[zone.parent]
if next and next.land_type ~= area.land_type then
return zone
end
zone = next
end
return nil
end
--- Transfers a plot between two owners, after checking relevant permissions.
--
-- @int id
@ -259,6 +279,57 @@ function land.set_price(area, pname, price)
end
--- Calculates a recommended value for the lot, based on the position and more.
--
-- @tparam table area
-- @treturn number value
function land.calc_value(area)
assert(type(area) == "table")
-- Calculate a weighted metric based on volume of area
local pos1, pos2 = vector.sort(area.pos1, area.pos2)
local size = vector.subtract(pos2, pos1)
local value = 200 * (size.x * size.z * 0.33 * size.y)
-- Find distance to zone center
local zone = land.get_zone(area)
if zone then
local zone_center = zone.spawn_point or zone.pos1
local area_center = vector.divide(vector.add(area.pos1, area.pos2), 2)
local dist = vector.sqdist(zone_center, area_center)
value = value + (zone.land_value or 1000000) * 1 / (dist*0.1 + 2)
end
area.land_value = value
return value
end
--- Gets plot value, calcs it if needed.
--
-- @tparam table area
-- @treturn number value
function land.get_value(area)
if area.land_value then
return area.land_value
else
return land.calc_value(area)
end
end
--- Work out the amount of tax that should be paid monthly
--
-- @tparam table area
-- @treturn number value
function land.get_tax(area)
local value = land.get_value(area)
local zone = land.get_zone(area)
return value * (zone.property_tax_rate or 0.1)
end
--- Whether a user can buy a plot
--
-- @tparam table area

View File

@ -31,7 +31,7 @@ land.show_debug_to = lib_quickfs.register("land:debug", {
get = function(context, player)
local fs = {
"size[7,6]",
"tablecolumns[color;tree;text,width=10;text]",
"tablecolumns[color;tree;text,width=10;text;text,align=right]",
-- "tableoptions[background=#00000000;border=false]",
"table[0,0;4.8,6;list_areas;"
}
@ -66,7 +66,8 @@ land.show_debug_to = lib_quickfs.register("land:debug", {
fs[#fs + 1] = area.level .. "," ..
minetest.formspec_escape(area.name .. " [id=" .. area.id .. "]") .. "," ..
minetest.formspec_escape(area.owner)
minetest.formspec_escape(area.owner) .. "," ..
(math.floor(land.get_value(area)*10)/10)
end
fs[#fs + 1] = ";"
@ -76,15 +77,12 @@ land.show_debug_to = lib_quickfs.register("land:debug", {
fs[#fs + 1] = "]"
if context.selected then
-- local area = list[context.selected]
-- fs[#fs + 1] = "box[5,1;1.8,0.8;#222]"
fs[#fs + 1] = "button[5,0;2,1;to_comm;Commercial]"
fs[#fs + 1] = "button[5,1;2,1;to_inds;Industrial]"
fs[#fs + 1] = "button[5,2;2,1;to_resd;Residential]"
fs[#fs + 1] = "button[5,3;2,1;to_clear;Clear]"
fs[#fs + 1] = "button[5,4;2,1;set_owner;Set Owner]"
fs[#fs + 1] = "box[5,3;1.8,0.8;#222]"
fs[#fs + 1] = "button[5,5;2,1;delete;Delete]"
else
fs[#fs + 1] = "label[0.1,6.1;No area selected]"
end
@ -122,6 +120,8 @@ land.show_debug_to = lib_quickfs.register("land:debug", {
return do_set("industrial")
elseif fields.to_resd then
return do_set("residential")
elseif fields.to_clear then
return do_set(nil)
elseif fields.unzone then
local area = context.list[context.selected]
land.remove_zone(area.id)
@ -140,7 +140,7 @@ land.show_set_price_to = lib_quickfs.register("land:set_price", {
assert(area.owner and area.pos2)
local fs = {
"size[3,2]",
"field[0.3,0.5;3,1;price;Price;", tostring(area.land_sale), "]",
"field[0.3,0.5;3,1;price;Price;", tostring(area.land_sale or area.land_value or 100000), "]",
"button_exit[1,1.2;1,1;set;Set]"
}
@ -150,7 +150,7 @@ land.show_set_price_to = lib_quickfs.register("land:set_price", {
on_receive_fields = function(context, player, fields, area)
if fields.set then
land.set_price(area, player:get_player_name(),
tonumber(fields.price) or 100000)
tonumber(fields.price) or area.land_value)
end
end,
})
@ -358,6 +358,6 @@ company.register_panel({
text = text .. "\n" .. key .. ": " .. value
end
return "label[0.2,0.2;" .. minetest.formspec_escape(text) .. "]"
return "label[0,0.3;" .. minetest.formspec_escape(text) .. "]"
end,
})

View File

@ -7,6 +7,9 @@ _G.audit = function()
return { post = function() end }
end
_G.vector = {}
require("libs/lib_utils/vector")
require("capitalism/land/api")
_G.company = {}
@ -153,4 +156,21 @@ describe("land", function()
assert.is_true(suc)
assert.equals(area.land_sale, 100)
end)
it("calc_value", function()
local function v(x, y, z)
return { x=x, y=y, z=z }
end
areas.areas = {
{ owner="c:government", id=1, name="Root", pos1=v(0,0,0), pos2=v(100,100,100), parent=nil },
{ owner="c:government", id=2, name="City", pos1=v(0,0,0), pos2=v(100,100,100), parent=1 },
{ owner="c:government", id=3, name="Commercial", land_type="commercial", pos1=v(10,10,10), pos2=v(50,50,50),
parent=2, land_value=1000000 },
{ owner="c:test", id=4, name="Mall", land_type="commercial", pos1=v(10,10,10), pos2=v(30,30,30), parent=3 },
{ owner="c:test", id=5, name="Shop", land_type="commercial", pos1=v(10,10,10), pos2=v(20,13,20), parent=4 },
}
assert.equals(land.calc_value(areas.areas[5]), 200*(10*10*3*0.33) + 1000000 * 1 / (52.25*0.1 + 2))
end)
end)

View File

@ -0,0 +1,7 @@
minetest.register_on_joinplayer(function(player)
player:set_formspec_prepend([[
bgcolor[#080808BB;true]
background[5,5;1,1;theme_formbg.png;true;10]
listcolors[#00000069;#5A5A5A;#141318;#30434C;#FFF]
style_type[button;bgimg=theme_button.png;bgimg_pressed=theme_button_pressed.png] ]])
end)

View File

@ -0,0 +1,2 @@
name = theme
depends = default

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 862 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

89
mods/libs/hudkit/init.lua Normal file
View File

@ -0,0 +1,89 @@
function hudkit()
return {
players = {},
-- set = function(self, player, id, def)
-- local name = player:get_player_name()
-- local elements = self.players[name]
-- if not elements then
-- self.players[name] = {}
-- elements = self.players[name]
-- end
-- if elements[id] then
-- for key, value in pairs(def) do
-- if elements[id].def[key] ~= value then
-- end
-- end
-- else
-- self:add(self, player, id, def)
-- end
-- end,
add = function(self, player, id, def)
local name = player:get_player_name()
local elements = self.players[name]
if not elements then
self.players[name] = {}
elements = self.players[name]
end
elements[id] = {
id = player:hud_add(def),
def = def
}
return true
end,
exists = function(self, player, id)
if not player then
return false
end
local name = player:get_player_name()
local elements = self.players[name]
if not elements or not elements[id] then
return false
end
return true
end,
change = function(self, player, id, stat, value)
if not player then
return false
end
local name = player:get_player_name()
local elements = self.players[name]
if not elements or not elements[id] or not elements[id].id then
return false
end
if elements[id].def[stat] ~= value then
elements[id].def[stat] = value
player:hud_change(elements[id].id, stat, value)
end
return true
end,
remove = function(self, player, id)
local name = player:get_player_name()
local elements = self.players[name]
if not elements or not elements[id] or not elements[id].id then
return false
end
player:hud_remove(elements[id].id)
elements[id] = nil
return true
end,
}
end

View File

@ -1,5 +1,13 @@
lib_utils = {}
function lib_utils.interval(time, func, ...)
local function tick(...)
func(...)
minetest.after(time, tick, ...)
end
minetest.after(time, tick, ...)
end
function lib_utils.make_saveload(tab, storage, itemarraykey, registername, class)
assert(tab)
assert(storage)
@ -57,3 +65,10 @@ function lib_utils.make_saveload(tab, storage, itemarraykey, registername, class
tab.dirty = false
end
end
function vector.sqdist(a, b)
local x = a.x - b.x
local y = a.y - b.y
local z = a.z - b.z
return x*x + y*y + z*z
end

View File

@ -0,0 +1,149 @@
vector = {}
function vector.new(a, b, c)
if type(a) == "table" then
assert(a.x and a.y and a.z, "Invalid vector passed to vector.new()")
return {x=a.x, y=a.y, z=a.z}
elseif a then
assert(b and c, "Invalid arguments for vector.new()")
return {x=a, y=b, z=c}
end
return {x=0, y=0, z=0}
end
function vector.equals(a, b)
return a.x == b.x and
a.y == b.y and
a.z == b.z
end
function vector.length(v)
return math.hypot(v.x, math.hypot(v.y, v.z))
end
function vector.normalize(v)
local len = vector.length(v)
if len == 0 then
return {x=0, y=0, z=0}
else
return vector.divide(v, len)
end
end
function vector.floor(v)
return {
x = math.floor(v.x),
y = math.floor(v.y),
z = math.floor(v.z)
}
end
function vector.round(v)
return {
x = math.floor(v.x + 0.5),
y = math.floor(v.y + 0.5),
z = math.floor(v.z + 0.5)
}
end
function vector.apply(v, func)
return {
x = func(v.x),
y = func(v.y),
z = func(v.z)
}
end
function vector.distance(a, b)
local x = a.x - b.x
local y = a.y - b.y
local z = a.z - b.z
return math.hypot(x, math.hypot(y, z))
end
function vector.direction(pos1, pos2)
return vector.normalize({
x = pos2.x - pos1.x,
y = pos2.y - pos1.y,
z = pos2.z - pos1.z
})
end
function vector.angle(a, b)
local dotp = vector.dot(a, b)
local cp = vector.cross(a, b)
local crossplen = vector.length(cp)
return math.atan2(crossplen, dotp)
end
function vector.dot(a, b)
return a.x * b.x + a.y * b.y + a.z * b.z
end
function vector.cross(a, b)
return {
x = a.y * b.z - a.z * b.y,
y = a.z * b.x - a.x * b.z,
z = a.x * b.y - a.y * b.x
}
end
function vector.add(a, b)
if type(b) == "table" then
return {x = a.x + b.x,
y = a.y + b.y,
z = a.z + b.z}
else
return {x = a.x + b,
y = a.y + b,
z = a.z + b}
end
end
function vector.subtract(a, b)
if type(b) == "table" then
return {x = a.x - b.x,
y = a.y - b.y,
z = a.z - b.z}
else
return {x = a.x - b,
y = a.y - b,
z = a.z - b}
end
end
function vector.multiply(a, b)
if type(b) == "table" then
return {x = a.x * b.x,
y = a.y * b.y,
z = a.z * b.z}
else
return {x = a.x * b,
y = a.y * b,
z = a.z * b}
end
end
function vector.divide(a, b)
if type(b) == "table" then
return {x = a.x / b.x,
y = a.y / b.y,
z = a.z / b.z}
else
return {x = a.x / b,
y = a.y / b,
z = a.z / b}
end
end
function vector.sort(a, b)
return {x = math.min(a.x, b.x), y = math.min(a.y, b.y), z = math.min(a.z, b.z)},
{x = math.max(a.x, b.x), y = math.max(a.y, b.y), z = math.max(a.z, b.z)}
end
function vector.sqdist(a, b)
local x = a.x - b.x
local y = a.y - b.y
local z = a.z - b.z
return x*x + y*y + z*z
end

View File

@ -20,10 +20,14 @@ minetest.register_on_joinplayer(function(player)
listcolors[#00000069;#5A5A5A;#141318;#30434C;#FFF] ]])
end)
function default.get_hotbar_bg(x,y)
function default.get_hotbar_bg(x, y, real_coordinates)
local out = ""
local spacing = real_coordinates and (5/4) or 0
local padding = real_coordinates and (3/8) or 0
local iy = y + (y + 1)*spacing + padding
for i=0,7,1 do
out = out .."image["..x+i..","..y..";1,1;gui_hb_bg.png]"
local ix = x + i + (x + i + 1)*spacing + padding
out = out .."image["..ix..","..y..";1,1;gui_hb_bg.png]"
end
return out
end

View File

@ -36,15 +36,29 @@ function sfinv.get_nav_fs(player, context, nav, current_idx)
end
end
function sfinv.get_hotbar_bg(x, y, real_coordinates)
local out = ""
local spacing = real_coordinates and 0.25 or 0
for i=0,7,1 do
local ix = x + i + i*spacing
out = out .."image["..ix..","..y..";1,1;gui_hb_bg.png]"
end
return out
end
local theme_inv = [[
list[current_player;main;0,4.7;8,1;]
list[current_player;main;0,5.85;8,3;8]
]]
list[current_player;main;0.375,4.7;8,1;]
list[current_player;main;0.375,6.1;8,3;8]
]] .. sfinv.get_hotbar_bg(0.375, 4.7, true)
function sfinv.make_formspec(player, context, content, show_inv, size)
local tmp = {
size or "size[8,8.6]",
size or "size[10.5,10]",
"real_coordinates[true]",
sfinv.get_nav_fs(player, context, context.nav_titles, context.nav_idx),
"real_coordinates[false]",
content
}
if show_inv then

View File

@ -4,19 +4,12 @@ sfinv.register_page("sfinv:crafting", {
title = "Crafting",
get = function(self, player, context)
return sfinv.make_formspec(player, context, [[
list[current_player;craft;1.75,0.5;3,3;]
list[current_player;craftpreview;5.75,1.5;1,1;]
image[4.75,1.5;1,1;gui_furnace_arrow_bg.png^[transformR270]
real_coordinates[true]
list[current_player;craft;2.3,0.375;3,3;]
list[current_player;craftpreview;7.5,1.675;1,1;]
image[6.2,1.675;1,1;gui_furnace_arrow_bg.png^[transformR270]
listring[current_player;main]
listring[current_player;craft]
image[0,4.75;1,1;gui_hb_bg.png]
image[1,4.75;1,1;gui_hb_bg.png]
image[2,4.75;1,1;gui_hb_bg.png]
image[3,4.75;1,1;gui_hb_bg.png]
image[4,4.75;1,1;gui_hb_bg.png]
image[5,4.75;1,1;gui_hb_bg.png]
image[6,4.75;1,1;gui_hb_bg.png]
image[7,4.75;1,1;gui_hb_bg.png]
]], true)
end
})