plan generation finished, selection by dropdown
npc destination search optimizations for cleanup tasks
This commit is contained in:
parent
b4f23d2b02
commit
1f12549e65
75
chest.lua
75
chest.lua
@ -16,14 +16,12 @@ local __get = function(pos)
|
|||||||
local this = nil
|
local this = nil
|
||||||
if townchest.chest.list[key] then
|
if townchest.chest.list[key] then
|
||||||
this = townchest.chest.list[key]
|
this = townchest.chest.list[key]
|
||||||
dprint("get key from list", this)
|
|
||||||
else
|
else
|
||||||
this = townchest.chest.new()
|
this = townchest.chest.new()
|
||||||
this.key = key
|
this.key = key
|
||||||
this.pos = pos
|
this.pos = pos
|
||||||
this.meta = minetest.env:get_meta(pos) --just pointer
|
this.meta = minetest.env:get_meta(pos) --just pointer
|
||||||
townchest.chest.list[key] = this
|
townchest.chest.list[key] = this
|
||||||
dprint("get new key", this)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- update chest info
|
-- update chest info
|
||||||
@ -114,9 +112,16 @@ townchest.chest.new = function()
|
|||||||
-- Create the task that should be managed by chest
|
-- Create the task that should be managed by chest
|
||||||
--------------------------------------
|
--------------------------------------
|
||||||
function chest.set_rawdata(this, taskname)
|
function chest.set_rawdata(this, taskname)
|
||||||
if taskname == "file" then
|
this.plan = townchest.plan.new(this)
|
||||||
|
local we = {}
|
||||||
|
|
||||||
|
if taskname then
|
||||||
|
this.info.taskname = taskname
|
||||||
|
end
|
||||||
|
|
||||||
|
if this.info.taskname == "file" then
|
||||||
-- check if file could be read
|
-- check if file could be read
|
||||||
local we = townchest.files.readfile(this.info.filename)
|
we = townchest.files.readfile(this.info.filename)
|
||||||
if not we or #we == 0 then
|
if not we or #we == 0 then
|
||||||
this.infotext = "No building found in ".. this.info.filename
|
this.infotext = "No building found in ".. this.info.filename
|
||||||
this:set_form("status")
|
this:set_form("status")
|
||||||
@ -126,39 +131,59 @@ townchest.chest.new = function()
|
|||||||
minetest.after(3, this.set_form, this, "file_open") --back to file selection
|
minetest.after(3, this.set_form, this, "file_open") --back to file selection
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
this.rawdata = we
|
|
||||||
|
|
||||||
elseif taskname == "generate" then
|
elseif this.info.taskname == "generate" then
|
||||||
local we = {}
|
if this.info.genblock.variant == 1 then
|
||||||
if this.info.genblock.fill == "true" then
|
-- Fill with air
|
||||||
--[[ for x = -math.floor(this.info.genblock.x/2), math.floor(this.info.genblock.x/2) do
|
for x = 0, this.info.genblock.x-1 do
|
||||||
for y = -1, this.info.genblock.y -2 do -- 1 under the chest
|
for y = 0, this.info.genblock.y-1 do
|
||||||
for z = -math.floor(this.info.genblock.z/2), math.floor(this.info.genblock.z/2) do
|
for z = 0, this.info.genblock.z-1 do
|
||||||
|
table.insert(we, {x=x,y=y,z=z, name = "air"})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elseif this.info.genblock.variant == 2 then
|
||||||
|
-- Fill with stone
|
||||||
|
for x = 0, this.info.genblock.x-1 do
|
||||||
|
for y = 0, this.info.genblock.y-1 do
|
||||||
|
for z = 0, this.info.genblock.z-1 do
|
||||||
table.insert(we, {x=x,y=y,z=z, name = "default:cobble"})
|
table.insert(we, {x=x,y=y,z=z, name = "default:cobble"})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
]]
|
|
||||||
for x = -math.floor(this.info.genblock.x/2), math.floor(this.info.genblock.x/2) do
|
elseif this.info.genblock.variant == 3 then
|
||||||
for y = -1, this.info.genblock.y -2 do -- 1 under the chest
|
-- Build a box
|
||||||
for z = -math.floor(this.info.genblock.z/2), math.floor(this.info.genblock.z/2) do
|
for x = 0, this.info.genblock.x-1 do
|
||||||
if x == -math.floor(this.info.genblock.x/2) or x == math.floor(this.info.genblock.x/2) or
|
for y = 0, this.info.genblock.y-1 do
|
||||||
y == -1 or y == this.info.genblock.y -2 or
|
for z = 0, this.info.genblock.z-1 do
|
||||||
z == -math.floor(this.info.genblock.z/2) or z == math.floor(this.info.genblock.z/2) then
|
if x == 0 or x == this.info.genblock.x-1 or
|
||||||
|
y == 0 or y == this.info.genblock.y-1 or
|
||||||
|
z == 0 or z == this.info.genblock.z-1 then
|
||||||
table.insert(we, {x=x,y=y,z=z, name = "default:cobble"})
|
table.insert(we, {x=x,y=y,z=z, name = "default:cobble"})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
|
||||||
table.insert(we, {x=-math.floor(this.info.genblock.x/2),y=0,z=-math.floor(this.info.genblock.z/2), name = "air"})
|
-- build ground level under chest
|
||||||
table.insert(we, {x=math.floor(this.info.genblock.x/2),y=this.info.genblock.y -1,z=math.floor(this.info.genblock.z/2), name = "air"})
|
this.plan.relative.ground_y = 1
|
||||||
|
|
||||||
|
-- Build a plate
|
||||||
|
elseif this.info.genblock.variant == 4 then
|
||||||
|
local y = 0
|
||||||
|
for x = 0, this.info.genblock.x-1 do
|
||||||
|
for z = 0, this.info.genblock.z-1 do
|
||||||
|
table.insert(we, {x=x,y=y,z=z, name = "default:cobble"})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- build ground level under chest
|
||||||
|
this.plan.relative.ground_y = 1
|
||||||
end
|
end
|
||||||
this.rawdata = we
|
|
||||||
end
|
end
|
||||||
|
|
||||||
this.info.taskname = taskname
|
this.rawdata = we
|
||||||
this.plan = townchest.plan.new(this)
|
|
||||||
chest:run_async(this.prepare_building_plan_chain)
|
chest:run_async(this.prepare_building_plan_chain)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -300,7 +325,7 @@ townchest.chest.new = function()
|
|||||||
dprint("restoral info", dump(chestinfo))
|
dprint("restoral info", dump(chestinfo))
|
||||||
if chestinfo.taskname and not this.current_stage then -- file selected but no plan. Restore the plan
|
if chestinfo.taskname and not this.current_stage then -- file selected but no plan. Restore the plan
|
||||||
this.current_stage = "restore"
|
this.current_stage = "restore"
|
||||||
chest:set_rawdata(this.info.taskname)
|
chest:set_rawdata(chestinfo.taskname)
|
||||||
elseif not chestinfo.filename then
|
elseif not chestinfo.filename then
|
||||||
this:set_form("file_open")
|
this:set_form("file_open")
|
||||||
end
|
end
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
local dprint = townchest.dprint --debug
|
local dprint = townchest.dprint --debug
|
||||||
|
|
||||||
local MAX_SPEED = 5
|
local MAX_SPEED = 5
|
||||||
|
local BUILD_DISTANCE = 3
|
||||||
|
|
||||||
|
|
||||||
townchest.npc = {
|
townchest.npc = {
|
||||||
@ -54,8 +55,6 @@ local select_chest = function(self)
|
|||||||
self.chest = nil
|
self.chest = nil
|
||||||
self.chestpos = nil
|
self.chestpos = nil
|
||||||
end
|
end
|
||||||
else
|
|
||||||
dprint("Chest ok:",self.chest)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -122,12 +121,12 @@ local function prefer_target(npc, t1, t2)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local npcpos = npc.object:getpos()
|
local npcpos = npc.object:getpos()
|
||||||
|
-- npc is 1.5 blocks over the work
|
||||||
|
npcpos.y = npcpos.y - 1.5
|
||||||
|
|
||||||
-- variables for vectors based preference manipulation
|
-- variables for preference manipulation
|
||||||
local t1_c = {x=t1.pos.x, y=t1.pos.y, z=t1.pos.z}
|
local t1_c = {x=t1.pos.x, y=t1.pos.y, z=t1.pos.z}
|
||||||
local t2_c = {x=t2.pos.x, y=t2.pos.y, z=t2.pos.z}
|
local t2_c = {x=t2.pos.x, y=t2.pos.y, z=t2.pos.z}
|
||||||
|
|
||||||
-- variable for value based preference manipulation
|
|
||||||
local prefer = 0
|
local prefer = 0
|
||||||
|
|
||||||
--prefer same items in building order
|
--prefer same items in building order
|
||||||
@ -140,37 +139,56 @@ local function prefer_target(npc, t1, t2)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- note: npc is higher by y+1.5
|
-- prefer the last target node
|
||||||
-- in case of clanup task prefer higher node
|
if npc.targetnode then
|
||||||
|
if t1.x == npc.targetnode.pos.x and
|
||||||
|
t1.y == npc.targetnode.pos.y and
|
||||||
|
t1.z == npc.targetnode.pos.z then
|
||||||
|
prefer = prefer + BUILD_DISTANCE
|
||||||
|
end
|
||||||
|
if t2.x == npc.targetnode.pos.x and
|
||||||
|
t2.y == npc.targetnode.pos.y and
|
||||||
|
t2.z == npc.targetnode.pos.z then
|
||||||
|
prefer = prefer - BUILD_DISTANCE
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- prefer air in general
|
||||||
|
if t1.name == "air" then
|
||||||
|
prefer = prefer + 2
|
||||||
|
end
|
||||||
|
if t2.name == "air" then
|
||||||
|
prefer = prefer - 2
|
||||||
|
end
|
||||||
|
|
||||||
|
-- prefer lower node if not air
|
||||||
if t1.name ~= "air" then
|
if t1.name ~= "air" then
|
||||||
-- calculate as over the npc by additional 1.5. no change means lower then npc by 1.5
|
t1_c.y = t1_c.y + 1
|
||||||
t1_c.y = t1_c.y + 3
|
elseif math.abs(npcpos.y - t1.pos.y) <= BUILD_DISTANCE then
|
||||||
else
|
-- prefer higher node if air in reachable distance
|
||||||
-- prefer air
|
t1_c.y = t1_c.y - 4
|
||||||
t1_c.y = t1_c.y - 2
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- prefer lower node if not air
|
||||||
if t2.name ~= "air" then
|
if t2.name ~= "air" then
|
||||||
-- calculate as over the npc by additional 1.5. no change means lower then npc by 1.5
|
t2_c.y = t2_c.y + 1
|
||||||
t2_c.y = t2_c.y + 3
|
elseif math.abs(npcpos.y - t1.pos.y) <= BUILD_DISTANCE then
|
||||||
else
|
-- prefer higher node if air in reachable distance
|
||||||
-- prefer air
|
t2_c.y = t2_c.y - 4
|
||||||
t2_c.y = t2_c.y - 2
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- avoid build directly under or over the npc. No extra bonus for air in this case
|
-- avoid build directly under or in the npc
|
||||||
if math.abs(npcpos.x - t1.pos.x) < 1 and math.abs(npcpos.z - t1.pos.z) < 1 then
|
if math.abs(npcpos.x - t1.pos.x) < 0.5 and
|
||||||
prefer = prefer-2
|
math.abs(npcpos.y - t1.pos.y) < 2 and
|
||||||
elseif t1.name == "air" then
|
math.abs(npcpos.z - t1.pos.z) < 0.5 then
|
||||||
prefer = prefer+2
|
prefer = prefer-1.5
|
||||||
end
|
end
|
||||||
if math.abs(npcpos.x - t2.pos.x) < 1 and math.abs(npcpos.z - t2.pos.z) < 1 then
|
if math.abs(npcpos.x - t2.pos.x) < 0.5 and
|
||||||
prefer = prefer+2
|
math.abs(npcpos.y - t1.pos.y) < 2 and
|
||||||
elseif t2.name == "air" then
|
math.abs(npcpos.z - t2.pos.z) < 0.5 then
|
||||||
prefer = prefer-2
|
prefer = prefer+1.5
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- compare
|
-- compare
|
||||||
if vector.distance(npcpos, t1_c) - prefer > vector.distance(npcpos, t2_c) then
|
if vector.distance(npcpos, t1_c) - prefer > vector.distance(npcpos, t2_c) then
|
||||||
return t2
|
return t2
|
||||||
@ -303,7 +321,7 @@ npcf:register_npc("townchest:npcf_builder" ,{
|
|||||||
|
|
||||||
yaw = npcf:get_face_direction(pos, self.targetnode.pos)
|
yaw = npcf:get_face_direction(pos, self.targetnode.pos)
|
||||||
-- target reached build
|
-- target reached build
|
||||||
if target_distance < 3 and self.dest_type == "build" then
|
if target_distance <= BUILD_DISTANCE and self.dest_type == "build" then
|
||||||
-- do the build
|
-- do the build
|
||||||
local soundspec
|
local soundspec
|
||||||
if minetest.registered_items[self.targetnode.name].sounds then
|
if minetest.registered_items[self.targetnode.name].sounds then
|
||||||
@ -332,13 +350,6 @@ npcf:register_npc("townchest:npcf_builder" ,{
|
|||||||
if target_distance > 2 then
|
if target_distance > 2 then
|
||||||
speed = 1
|
speed = 1
|
||||||
state = NPCF_ANIM_WALK_MINE
|
state = NPCF_ANIM_WALK_MINE
|
||||||
|
|
||||||
-- jump
|
|
||||||
if self.targetnode.name ~= "air" and (self.targetnode.pos.y -(pos.y-1.5)) > 0 and (self.targetnode.pos.y -(pos.y-1.5)) < 2 then
|
|
||||||
acceleration = {x=0, y=0, z=0}
|
|
||||||
pos = {x=pos.x, y=self.targetnode.pos.y + 1.5, z=pos.z}
|
|
||||||
self.object:setpos(pos)
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
speed = 0
|
speed = 0
|
||||||
state = NPCF_ANIM_MINE
|
state = NPCF_ANIM_MINE
|
||||||
@ -359,14 +370,15 @@ npcf:register_npc("townchest:npcf_builder" ,{
|
|||||||
--target not reached
|
--target not reached
|
||||||
state = NPCF_ANIM_WALK
|
state = NPCF_ANIM_WALK
|
||||||
-- Big jump / teleport upsite
|
-- Big jump / teleport upsite
|
||||||
if (self.targetnode.pos.y -(pos.y-1.5)) > 0 and
|
if (self.targetnode.pos.y -(pos.y-1.5)) > BUILD_DISTANCE and
|
||||||
math.abs(self.targetnode.pos.x - pos.x) <= 3 and
|
math.abs(self.targetnode.pos.x - pos.x) <= 0.5 and
|
||||||
math.abs(self.targetnode.pos.z - pos.z) <= 3 then
|
math.abs(self.targetnode.pos.z - pos.z) <= 0.5 then
|
||||||
acceleration = {x=0, y=0, z=0}
|
acceleration = {x=0, y=0, z=0}
|
||||||
pos = {x=pos.x, y=self.targetnode.pos.y + 1.5, z=pos.z}
|
pos = {x=pos.x, y=self.targetnode.pos.y + 1.5, z=pos.z}
|
||||||
self.object:setpos(pos)
|
self.object:setpos(pos)
|
||||||
target_distance = 0 -- to skip the next part and set speed to 0
|
target_distance = 0 -- to skip the next part and set speed to 0
|
||||||
local state = NPCF_ANIM_STAND
|
state = NPCF_ANIM_STAND
|
||||||
|
dprint("Big jump to"..minetest.pos_to_string(pos))
|
||||||
end
|
end
|
||||||
|
|
||||||
-- teleport in direction in case of stucking
|
-- teleport in direction in case of stucking
|
||||||
@ -379,6 +391,9 @@ npcf:register_npc("townchest:npcf_builder" ,{
|
|||||||
end
|
end
|
||||||
self.object:setpos(pos)
|
self.object:setpos(pos)
|
||||||
acceleration = {x=0, y=0, z=0}
|
acceleration = {x=0, y=0, z=0}
|
||||||
|
target_distance = 0 -- to skip the next part and set speed to 0
|
||||||
|
state = NPCF_ANIM_STAND
|
||||||
|
dprint("Teleport to"..minetest.pos_to_string(pos))
|
||||||
end
|
end
|
||||||
self.var.last_pos = pos
|
self.var.last_pos = pos
|
||||||
speed = get_speed(target_distance)
|
speed = get_speed(target_distance)
|
||||||
|
@ -1,16 +1,15 @@
|
|||||||
local dprint = townchest.dprint_off --debug
|
local dprint = townchest.dprint_off --debug
|
||||||
|
|
||||||
|
|
||||||
townchest.specwidgets = {}
|
townchest.specwidgets = {}
|
||||||
|
|
||||||
|
|
||||||
--- temporary provide smartfs as builtin, till the needed changes are upstream
|
--- temporary provide smartfs as builtin, till the needed changes are upstream
|
||||||
local smartfs = townchest.smartfs
|
local smartfs = townchest.smartfs
|
||||||
--- temporary end
|
--- temporary end
|
||||||
|
|
||||||
|
-----------------------------------------------
|
||||||
|
-- file open dialog form / (tabbed)
|
||||||
|
-----------------------------------------------
|
||||||
local _file_open_dialog = function(state)
|
local _file_open_dialog = function(state)
|
||||||
|
|
||||||
--connect to chest object for data
|
--connect to chest object for data
|
||||||
local chest = townchest.chest.get(state.location.pos)
|
local chest = townchest.chest.get(state.location.pos)
|
||||||
|
|
||||||
@ -42,7 +41,9 @@ local _file_open_dialog = function(state)
|
|||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
|
|
||||||
-- file selection tab button
|
-----------------------------------------------
|
||||||
|
-- file selection tab
|
||||||
|
-----------------------------------------------
|
||||||
local tab1 = {}
|
local tab1 = {}
|
||||||
tab1.button = state:button(0,0,2,1,"tab1_btn","Buildings")
|
tab1.button = state:button(0,0,2,1,"tab1_btn","Buildings")
|
||||||
tab1.button:onClick(function(self)
|
tab1.button:onClick(function(self)
|
||||||
@ -58,20 +59,29 @@ local _file_open_dialog = function(state)
|
|||||||
end
|
end
|
||||||
tab_controller:tab_add("tab1", tab1)
|
tab_controller:tab_add("tab1", tab1)
|
||||||
|
|
||||||
|
-----------------------------------------------
|
||||||
|
-- Simple form building tab
|
||||||
|
-----------------------------------------------
|
||||||
-- Tasks tab button
|
-- Tasks tab button
|
||||||
local tab2 = {}
|
local tab2 = {}
|
||||||
tab2.button = state:button(2,0,2,1,"tab2_btn","Tasks")
|
tab2.button = state:button(2,0,2,1,"tab2_btn","Tasks")
|
||||||
tab2.button:onClick(function(self)
|
tab2.button:onClick(function(self)
|
||||||
tab_controller:set_active("tab2")
|
tab_controller:set_active("tab2")
|
||||||
end)
|
end)
|
||||||
tab2.view = state:view(0.5,1,"tab2_view")
|
tab2.view = state:view(0,1,"tab2_view")
|
||||||
tab2.viewstate = tab2.view:getViewState()
|
tab2.viewstate = tab2.view:getViewState()
|
||||||
-- Tasks tab view state
|
-- Tasks tab view state
|
||||||
tab2.viewstate:label(0,0,"header","Free place for a build")
|
tab2.viewstate:label(0,0.2,"header","Build simple form")
|
||||||
|
local variant = tab2.viewstate:dropdown(3.5,0.2,4,0.5,"variant", 1)
|
||||||
|
variant:addItem("Fill with air") -- 1
|
||||||
|
variant:addItem("Fill with stone") -- 2
|
||||||
|
variant:addItem("Build a box") -- 3
|
||||||
|
variant:addItem("Build a plate") -- 4
|
||||||
|
|
||||||
local field_x = tab2.viewstate:field(0,2,2,0.5,"x","width (x)")
|
local field_x = tab2.viewstate:field(0,2,2,0.5,"x","width (x)")
|
||||||
local field_y = tab2.viewstate:field(2,2,2,0.5,"y","high (y)")
|
local field_y = tab2.viewstate:field(2,2,2,0.5,"y","high (y)")
|
||||||
local field_z = tab2.viewstate:field(4,2,2,0.5,"z","width (y)")
|
local field_z = tab2.viewstate:field(4,2,2,0.5,"z","width (y)")
|
||||||
local fill_chk = tab2.viewstate:checkbox(0,3,"fill", "Fill place with stone")
|
|
||||||
tab_controller:tab_add("tab2", tab2)
|
tab_controller:tab_add("tab2", tab2)
|
||||||
|
|
||||||
--process all inputs
|
--process all inputs
|
||||||
@ -79,7 +89,8 @@ local _file_open_dialog = function(state)
|
|||||||
chest.info.genblock.x = tonumber(field_x:getText())
|
chest.info.genblock.x = tonumber(field_x:getText())
|
||||||
chest.info.genblock.y = tonumber(field_y:getText())
|
chest.info.genblock.y = tonumber(field_y:getText())
|
||||||
chest.info.genblock.z = tonumber(field_z:getText())
|
chest.info.genblock.z = tonumber(field_z:getText())
|
||||||
chest.info.genblock.fill = fill_chk:getValue()
|
chest.info.genblock.variant = variant:getSelected()
|
||||||
|
chest.info.genblock.variant_name = variant:getSelectedItem()
|
||||||
chest:persist_info()
|
chest:persist_info()
|
||||||
end)
|
end)
|
||||||
|
|
||||||
@ -108,9 +119,10 @@ local _file_open_dialog = function(state)
|
|||||||
field_x:setText(tostring(chest.info.genblock.x or 1))
|
field_x:setText(tostring(chest.info.genblock.x or 1))
|
||||||
field_y:setText(tostring(chest.info.genblock.y or 1))
|
field_y:setText(tostring(chest.info.genblock.y or 1))
|
||||||
field_z:setText(tostring(chest.info.genblock.z or 1))
|
field_z:setText(tostring(chest.info.genblock.z or 1))
|
||||||
fill_chk:setValue(chest.info.genblock.fill)
|
variant:setSelected(chest.info.genblock.variant or 1)
|
||||||
|
|
||||||
return true --successfull build, update needed
|
--successfull build, update needed
|
||||||
|
return true
|
||||||
end
|
end
|
||||||
smartfs.create("file_open", _file_open_dialog)
|
smartfs.create("file_open", _file_open_dialog)
|
||||||
|
|
||||||
@ -165,7 +177,7 @@ local _build_status = function(state)
|
|||||||
if chest.info.taskname == "file" then
|
if chest.info.taskname == "file" then
|
||||||
l1:setText("Building "..chest.info.filename.." selected")
|
l1:setText("Building "..chest.info.filename.." selected")
|
||||||
elseif chest.info.taskname == "generate" then
|
elseif chest.info.taskname == "generate" then
|
||||||
l1:setText("Simple task")
|
l1:setText("Simple task: "..chest.info.genblock.variant_name)
|
||||||
end
|
end
|
||||||
l2:setText("Size: "..(relative.max_x-relative.min_x).." x "..(relative.max_z-relative.min_z))
|
l2:setText("Size: "..(relative.max_x-relative.min_x).." x "..(relative.max_z-relative.min_z))
|
||||||
l3:setText("Building high: "..(relative.max_y-relative.min_y).." Ground high: "..(relative.ground_y-relative.min_y))
|
l3:setText("Building high: "..(relative.max_y-relative.min_y).." Ground high: "..(relative.ground_y-relative.min_y))
|
||||||
|
103
smartfs.lua
103
smartfs.lua
@ -742,6 +742,14 @@ function smartfs._makeState_(form, newplayer, params, is_inv, nodepos)
|
|||||||
transparent = transparent
|
transparent = transparent
|
||||||
})
|
})
|
||||||
end,
|
end,
|
||||||
|
dropdown = function(self, x, y, w, h, name, selected)
|
||||||
|
return self:element("dropdown", {
|
||||||
|
pos = {x=x, y=y},
|
||||||
|
size = {w=w, h=h},
|
||||||
|
name = name,
|
||||||
|
selected = selected
|
||||||
|
})
|
||||||
|
end,
|
||||||
inventory = function(self, x, y, w, h, name)
|
inventory = function(self, x, y, w, h, name)
|
||||||
return self:element("inventory", {
|
return self:element("inventory", {
|
||||||
pos = {x=x, y=y},
|
pos = {x=x, y=y},
|
||||||
@ -1002,7 +1010,6 @@ smartfs.element("list", {
|
|||||||
assert(self.data.size and self.data.size.w and self.data.size.h, "list needs valid size")
|
assert(self.data.size and self.data.size.w and self.data.size.h, "list needs valid size")
|
||||||
assert(self.name, "list needs name")
|
assert(self.name, "list needs name")
|
||||||
self.data.value = minetest.is_yes(self.data.value)
|
self.data.value = minetest.is_yes(self.data.value)
|
||||||
self.data.label = self.data.label or ""
|
|
||||||
self.data.items = self.data.items or {}
|
self.data.items = self.data.items or {}
|
||||||
end,
|
end,
|
||||||
build = function(self)
|
build = function(self)
|
||||||
@ -1041,27 +1048,17 @@ smartfs.element("list", {
|
|||||||
self._doubleClick = func
|
self._doubleClick = func
|
||||||
end,
|
end,
|
||||||
addItem = function(self, item)
|
addItem = function(self, item)
|
||||||
if not self.data.items then
|
|
||||||
self.data.items = {}
|
|
||||||
end
|
|
||||||
table.insert(self.data.items, item)
|
table.insert(self.data.items, item)
|
||||||
|
-- return the index of item. It is the last one
|
||||||
|
return #self.data.items
|
||||||
end,
|
end,
|
||||||
removeItem = function(self,idx)
|
removeItem = function(self,idx)
|
||||||
if not self.data.items then
|
|
||||||
self.data.items = {}
|
|
||||||
end
|
|
||||||
table.remove(self.data.items,idx)
|
table.remove(self.data.items,idx)
|
||||||
end,
|
end,
|
||||||
getItem = function(self, idx)
|
getItem = function(self, idx)
|
||||||
if not self.data.items then
|
|
||||||
self.data.items = {}
|
|
||||||
end
|
|
||||||
return self.data.items[idx]
|
return self.data.items[idx]
|
||||||
end,
|
end,
|
||||||
popItem = function(self)
|
popItem = function(self)
|
||||||
if not self.data.items then
|
|
||||||
self.data.items = {}
|
|
||||||
end
|
|
||||||
local item = self.data.items[#self.data.items]
|
local item = self.data.items[#self.data.items]
|
||||||
table.remove(self.data.items)
|
table.remove(self.data.items)
|
||||||
return item
|
return item
|
||||||
@ -1080,6 +1077,75 @@ smartfs.element("list", {
|
|||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
smartfs.element("dropdown", {
|
||||||
|
onCreate = function(self)
|
||||||
|
assert(self.data.pos and self.data.pos.x and self.data.pos.y, "dropdown needs valid pos")
|
||||||
|
assert(self.data.size and self.data.size.w and self.data.size.h, "dropdown needs valid size")
|
||||||
|
assert(self.name, "dropdown needs name")
|
||||||
|
self.data.items = self.data.items or {}
|
||||||
|
self.data.selected = self.data.selected or 1
|
||||||
|
self.data.value = ""
|
||||||
|
end,
|
||||||
|
build = function(self)
|
||||||
|
return "dropdown["..
|
||||||
|
self:getPosString()..";"..
|
||||||
|
self:getSizeString()..";"..
|
||||||
|
self:getAbsName()..";"..
|
||||||
|
table.concat(self.data.items, ",")..";"..
|
||||||
|
tostring(self:getSelected()).."]"..
|
||||||
|
self:getBackgroundString()
|
||||||
|
end,
|
||||||
|
submit = function(self, field, player)
|
||||||
|
self:getSelected()
|
||||||
|
if self._select then
|
||||||
|
self:_select(self.root, field, player)
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
onSelect = function(self, func)
|
||||||
|
self._select = func
|
||||||
|
end,
|
||||||
|
addItem = function(self, item)
|
||||||
|
table.insert(self.data.items, item)
|
||||||
|
if #self.data.items == self.data.selected then
|
||||||
|
self.data.value = item
|
||||||
|
end
|
||||||
|
-- return the index of item. It is the last one
|
||||||
|
return #self.data.items
|
||||||
|
end,
|
||||||
|
removeItem = function(self,idx)
|
||||||
|
table.remove(self.data.items,idx)
|
||||||
|
end,
|
||||||
|
getItem = function(self, idx)
|
||||||
|
return self.data.items[idx]
|
||||||
|
end,
|
||||||
|
popItem = function(self)
|
||||||
|
local item = self.data.items[#self.data.items]
|
||||||
|
table.remove(self.data.items)
|
||||||
|
return item
|
||||||
|
end,
|
||||||
|
clearItems = function(self)
|
||||||
|
self.data.items = {}
|
||||||
|
end,
|
||||||
|
setSelected = function(self,idx)
|
||||||
|
self.data.selected = idx
|
||||||
|
self.data.value = self:getItem(idx) or ""
|
||||||
|
end,
|
||||||
|
getSelected = function(self)
|
||||||
|
self.data.selected = 1
|
||||||
|
if #self.data.items > 1 then
|
||||||
|
for i = 1, #self.data.items do
|
||||||
|
if self.data.items[i] == self.data.value then
|
||||||
|
self.data.selected = i
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return self.data.selected
|
||||||
|
end,
|
||||||
|
getSelectedItem = function(self)
|
||||||
|
return self.data.value
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
smartfs.element("inventory", {
|
smartfs.element("inventory", {
|
||||||
onCreate = function(self)
|
onCreate = function(self)
|
||||||
assert(self.data.pos and self.data.pos.x and self.data.pos.y, "list needs valid pos")
|
assert(self.data.pos and self.data.pos.x and self.data.pos.y, "list needs valid pos")
|
||||||
@ -1157,6 +1223,7 @@ smartfs.element("view", {
|
|||||||
onCreate = function(self)
|
onCreate = function(self)
|
||||||
assert(self.data.pos and self.data.pos.x and self.data.pos.y, "view needs valid pos")
|
assert(self.data.pos and self.data.pos.x and self.data.pos.y, "view needs valid pos")
|
||||||
assert(self.name, "view needs name")
|
assert(self.name, "view needs name")
|
||||||
|
self._state = smartfs._makeState_(self, nil, self.root.param)
|
||||||
end,
|
end,
|
||||||
-- redefinitions. The size is not handled by data.size but by view-state:size
|
-- redefinitions. The size is not handled by data.size but by view-state:size
|
||||||
setSize = function(self,w,h)
|
setSize = function(self,w,h)
|
||||||
@ -1167,17 +1234,9 @@ smartfs.element("view", {
|
|||||||
end,
|
end,
|
||||||
-- element interface methods
|
-- element interface methods
|
||||||
build = function(self)
|
build = function(self)
|
||||||
if not self:getIsHiddenOrCutted() == true then
|
return self:getViewState():_buildFormspec_(false)..self:getBackgroundString()
|
||||||
return self:getViewState():_buildFormspec_(false)..self:getBackgroundString()
|
|
||||||
else
|
|
||||||
print("SmartFS - (Warning): view outside or hidden")
|
|
||||||
return ""
|
|
||||||
end
|
|
||||||
end,
|
end,
|
||||||
getViewState = function(self)
|
getViewState = function(self)
|
||||||
if not self._state then
|
|
||||||
self._state = smartfs._makeState_(self, nil, self.root.param)
|
|
||||||
end
|
|
||||||
return self._state
|
return self._state
|
||||||
end
|
end
|
||||||
-- submit is handled by framework for elements with getViewState
|
-- submit is handled by framework for elements with getViewState
|
||||||
|
Loading…
x
Reference in New Issue
Block a user