Index: mods/starlit-electronics/init.lua ================================================================== --- mods/starlit-electronics/init.lua +++ mods/starlit-electronics/init.lua @@ -1,9 +1,40 @@ local lib = starlit.mod.lib local E = {} starlit.mod.electronics = E + +-------------------------------- +-- software context interface -- +-------------------------------- --------------------------------------- +-- any time a program is run() or bgProc()eeded, a context argument MUST +-- be passed to the entry point. this argument must have at least the +-- following fields and functions: + +-- string context ('suit', 'device', etc) +-- names the context in which the program is being run +-- swCap program +-- a structure as returned from usableSoftware(), providing the +-- program with access to and information about its substrate +-- function verify() --> bool +-- return true if the chip the program was loaded from is still +-- accessible +-- function drawCurrent(power, time, whatFor, [min]) --> J +-- attempt to draw current from the power source of whatever core +-- the program is running on +-- function pullConf() --> () +-- updates the conf structure provided to the program as part of +-- its initial context +-- function saveConf([conf]) --> () +-- saves any changes made to the conf structure +-- function availableChips() --> inventory list +-- returns the list of chips that are available in the execution +-- context. needed to retrieve system files + +-- currently, this interface is implemented by +-- - starlit/interfaces.lua +-- - starlit/suit.lua --------------------- -- item registries -- --------------------- Index: mods/starlit-electronics/sw.lua ================================================================== --- mods/starlit-electronics/sw.lua +++ mods/starlit-electronics/sw.lua @@ -165,22 +165,43 @@ return end ::found:: local scm = starlit.item.sw.db[job.schematic] - job.cyclesLeft = math.max(0, job.cyclesLeft - ctx.comp.cycles) - if job.cyclesLeft == 0 then - job.timeLeft = math.max(0, job.timeLeft - interval) + local stages = { + {id = 'cyclesLeft', decr=ctx.comp.cycles}; + {id = 'powerLeft', decr=function(current) + return ctx.drawCurrent(current, interval, 'compile') + end}; + {id = 'timeLeft', decr=interval}; + {id = 'numinaLeft', decr=0}; -- FIXME + } + + for i,v in ipairs(stages) do + if job[v.id] > 0 then + local decr + if type(v.decr) == 'function' + then decr = v.decr(job[v.id]) + else decr = v.decr + end + job[v.id] = math.max(0, job[v.id] - decr) + goto incomplete + end end - if job.timeLeft == 0 and job.cyclesLeft == 0 then + + ::complete:: do table.remove(conf, jobSlot) user:give(scm.output) user:alarm(-2, 'item') - else + goto done + end + + ::incomplete:: do conf[jobSlot].value = job_t.enc(job) end + ::done:: ctx.saveConf() end; } end Index: mods/starlit-material/elements.lua ================================================================== --- mods/starlit-material/elements.lua +++ mods/starlit-material/elements.lua @@ -6,10 +6,16 @@ hydrogen = { name = 'hydrogen', sym = 'H', n = 1; density = 8.988e-5; gas = true; color = lib.color(1,0.8,.3); }; + lithium = { + name = 'lithium', sym = 'Li', n = 3; density = 0.534; + -- i think lithium is considered a metal but we don't mark it as + -- one here because making a 'lithium ingot' is insane (even possible?) + color = lib.color(1,0.8,.3); + }; beryllium = { name = 'beryllium', sym = 'Be', n = 4; density = 0; metal = true; -- rare emerald-stuff color = lib.color(0.2,1,0.2); }; @@ -20,19 +26,29 @@ }; carbon = { name = 'carbon', sym = 'C', n = 6, density = 2.266; -- g/cm³ color = lib.color(.7,.2,.1); }; + magnesium = { + name = 'magnesium', sym = 'Mg', n = 12, density = 1.738; + metal = true; + color = lib.color(0.7, 0.7, 0.7); + }; + aluminum = { + name = 'aluminum', sym = 'Al', n = 13; density = 2.7; + metal = true; + color = lib.color(0.5,.55,.6); + }; silicon = { name = 'silicon', sym = 'Si', n = 14, density = 2.329; metal = true; -- can be forged into an ingot color = lib.color(.6,.6,.4); }; - neodymium = { - name = 'neodymium', sym = 'Nd', n= 60, density = 7.01; - metal = true; - color = lib.color(1,1,1); + argon = { + name = 'argon', sym = 'Ar', n = 18; density = 0.001784; + gas = true; + color = lib.color(0,0.1,.9); }; potassium = { name = 'potassium', sym = 'K', n = 19, density = 0.862; -- potassium is technically a metal but it's so soft -- it can be easily nanoworked without high temps, so @@ -42,36 +58,10 @@ calcium = { name = 'calcium', sym = 'Ca', n = 20; density = 1.55; metal = true; color = lib.color(1,1,0.7); }; - magnesium = { - name = 'magnesium', sym = 'Mg', n = 12, density = 1.738; - metal = true; - color = lib.color(0.7, 0.7, 0.7); - }; - aluminum = { - name = 'aluminum', sym = 'Al', n = 13; density = 2.7; - metal = true; - color = lib.color(0.5,.55,.6); - }; - iron = { - name = 'iron', sym = 'Fe', n = 26; density = 7.874; - metal = true; - color = lib.color(.3,.3,.3); - }; - copper = { - name = 'copper', sym = 'Cu', n = 29; density = 8.96; - metal = true; - color = lib.color(.8,.4,.1); - }; - lithium = { - name = 'lithium', sym = 'Li', n = 3; density = 0.534; - -- i think lithium is considered a metal but we don't mark it as - -- one here because making a 'lithium ingot' is insane (even possible?) - color = lib.color(1,0.8,.3); - }; titanium = { name = 'titanium', sym = 'Ti', n = 22; density = 4.506; metal = true; color = lib.color(.7,.7,.7); }; @@ -78,24 +68,57 @@ vanadium = { name = 'vanadium', sym = 'V', n = 23; density = 6; metal = true; color = lib.color(.3,0.5,.3); }; + iron = { + name = 'iron', sym = 'Fe', n = 26; density = 7.874; + metal = true; + color = lib.color(.3,.3,.3); + }; nickel = { - name = 'nickel', sym = 'ni', n = 28, density = 8.908; + name = 'nickel', sym = 'Ni', n = 28, density = 8.908; metal = true; color = lib.color(.7,.7,.6); }; + copper = { + name = 'copper', sym = 'Cu', n = 29; density = 8.96; + metal = true; + color = lib.color(.8,.4,.1); + }; + rubidium = { + name = 'rubidium', sym = 'Rb', n = 37; density = 1.532; + color = lib.color(.8,.7,.7); + -- this is a metal, but it's liquid at the temperatures we care about, + -- so we don't set the metal flag + }; + technetium = { + name = 'technetium', sym = 'Tc', n = 43; density = 11; + desc = 'Prized by the higher Powers for subtle interactions that elude mere human scholars, technetium is of particular use in nuclear nanobatteries.'; + metal = true; + color = lib.color(.2,0.2,1); + }; + silver = { + name = 'silver', sym = 'Ag', n = 47; density = 10.49; + metal = true; + color = lib.color(.7,.7,.8); + }; xenon = { name = 'xenon', sym = 'Xe', n = 54; density = 0.005894; gas = true; color = lib.color(.5,.1,1); }; - argon = { - name = 'argon', sym = 'Ar', n = 18; density = 0.001784; - gas = true; - color = lib.color(0,0.1,.9); + cesium = { + name = 'cesium', sym = 'Cs', n = 55; density = 1.93; + color = lib.color(.5,.1,1); + -- this is a metal, but it's liquid at the temperatures we care about, + -- so we don't set the metal flag + }; + neodymium = { + name = 'neodymium', sym = 'Nd', n= 60, density = 7.01; + metal = true; + color = lib.color(1,1,1); }; osmium = { name = 'osmium', sym = 'Os', n = 76; density = 22.59; metal = true; color = lib.color(.8,.1,1); @@ -103,16 +126,10 @@ iridium = { name = 'iridium', sym = 'Ir', n = 77; density = 22.56; metal = true; color = lib.color(.8,0,.5); }; - technetium = { - name = 'technetium', sym = 'Tc', n = 43; density = 11; - desc = 'Prized by the higher Powers for subtle interactions that elude mere human scholars, technetium is of particular use in nuclear nanobatteries.'; - metal = true; - color = lib.color(.2,0.2,1); - }; uranium = { name = 'uranium', sym = 'U', n = 92; density = 19.1; desc = 'A weak but relatively plentiful nuclear fuel.'; metal = true; color = lib.color(.2,.7,0); @@ -121,16 +138,11 @@ name = 'thorium', sym = 'Th', n = 90; density = 11.7; desc = 'A frighteningly powerful nuclear fuel.'; metal = true; color = lib.color(.7,.3,.1); }; - silver = { - name = 'silver', sym = 'Ag', n = 47; density = 10.49; - metal = true; - color = lib.color(.7,.7,.8); - }; gold = { name = 'gold', sym = 'Au', n = 79; density = 19.30; metal = true; color = lib.color(1,.8,0); }; } Index: mods/starlit/compile.lua ================================================================== --- mods/starlit/compile.lua +++ mods/starlit/compile.lua @@ -29,10 +29,12 @@ table.insert(conf, { key='job', value=job_t.enc { schematic = scm.id; cyclesLeft = scm.sw.cost and scm.sw.cost.cycles or 0; timeLeft = (fab.time and fab.time.print or 0); + powerLeft = cost.power; + numinaLeft = cost.numina; } }) end local function compilerCanPrint(user, cpl, scm) @@ -46,15 +48,17 @@ local cost = { fab = fab, output = output; consume = consume, unsat = unsat, leftover = leftover, itemSpec = itemSpec; runtimeEstimate = scm.speed + cpl.speed + (fab.time and fab.time.print or 0); - power = cpl.powerCost + scm.powerCost; + power = cpl.powerCost + scm.powerCost + + (sw.input.cost and sw.input.cost.power); ram = (cpl.cost and cpl.cost.ram or 0) + (scm.cost and scm.cost.ram or 0); cycles = (cpl.cost and cpl.cost.cycles or 0) + (scm.cost and scm.cost.cycles or 0); + numina = fab.cost and fab.cost.numina or 0; } local userComp = E.chip.sumCompute( user.entity:get_inventory():get_list 'starlit_suit_chips' ) @@ -267,93 +271,99 @@ end end; render = function(state, user) - local sel, pgmSelector = state.select, {} + local sel, pgmSelector = state.select, {kind = 'vert'} state.fetch() state.ctx.pullConf() - local function pushSelector(id, item, label, desc, req) + local function pushSelector(tbl, id, item, label, desc, req, w) + w = w or 12 local rh = .5 - local label = {kind = 'text', w = 10-1.5, h=1.5; - text = ''..lib.str.htsan(label) } + local label = {kind = 'text', w = w-1.5, h=1.6; + text = ''..lib.str.htsan(label) } if req then label.h = label.h - rh - .2 local imgs = {} for ci,c in ipairs(req) do for ei, e in ipairs(c.list) do table.insert(imgs, {kind = 'img', w=rh, h=rh, img=e.img}) end end - label = {kind = 'vert', w = 10-1.5, h=1.5; + label = {kind = 'vert', w = w-1.5, h=1.8; label; - {kind ='hztl', w=10-1.5, h=rh; unpack(imgs); } + {kind ='hztl', w=w-1.5, h=rh; unpack(imgs); } } end - table.insert(pgmSelector, {kind = 'hztl', w=10,h=1.5; + table.insert(tbl, {kind = 'hztl', w=w,h=1.8; {kind = 'contact', id=id, w=1.5, h=1.5; item = item; color = {hue=220, sat=0, lum=0}; desc = desc; }; label; }) end - local back = {kind = 'button', id='back', label = '<- Back', w=10,h=1.2} + local back = {kind = 'button', id='back', label = '<- Back', w=12,h=1.2} if sel.chips == nil then table.insert(pgmSelector, {kind = 'img', img = 'starlit-ui-alert.png', w=2, h=2}) elseif sel.chip == nil then for i, c in ipairs(sel.chips.order) do -- TODO filter out chips without schematics? - pushSelector('chip_' .. c.data.uuid, c.stack, c.data.label) + pushSelector(pgmSelector, 'chip_' .. c.data.uuid, c.stack, c.data.label) end if next(sel.chips.order) then - table.insert(pgmSelector, {kind = 'hztl', w=10,h=1.5; - {kind = 'button', w=5,h=1.5; id='showAll', label='Show All'}; - {kind = 'button', w=5,h=1.5; id='find', label='Find'}; + table.insert(pgmSelector, {kind = 'hztl', w=12,h=1.5; + {kind = 'button', w=6,h=1.5; id='showAll', label='Show All'}; + {kind = 'button', w=6,h=1.5; id='find', label='Find'}; }) end else if sel.scm == nil then + -- l m a o +-- pgmSelector.kind = 'hwrap' +-- pgmSelector.cols = 2 + local wrap = {kind='hwrap',cols=2,w=12} for idx, ent in ipairs(sel.scms) do local fab = ent.sw.input if fab.flag and fab.flag.print then local req = fab:visualize() - pushSelector('scm_' .. idx, ent.sw.output, ent.sw.name, nil, req) + pushSelector(wrap,'scm_' .. idx, ent.sw.output, ent.sw.name, nil, req,6) end end + table.insert(pgmSelector, wrap) table.insert(pgmSelector, back) else local scm = sel.scms[sel.scm] local output = ItemStack(scm.sw.output):get_definition() local fab = scm.sw.input local sw = scm.sw local function unmet(str) return lib.color(1,.3,.3):fmt(str) end - table.insert(pgmSelector, {kind = 'hztl', w=10, h=1.2; + table.insert(pgmSelector, {kind = 'hztl', w=12, h=1.2; {kind = 'img', item = sw.output, w=1.2, h=1.2, desc=output.description}; - {kind = 'text', text = string.format('%s', lib.str.htsan(sw.name)), w=10-1.2,h=1.2}; + {kind = 'text', text = string.format('%s', lib.str.htsan(sw.name)), w=12-1.2,h=1.2}; }) - local inputTbl = {kind = 'vert', w=5,h=0; - {kind = 'hbar', w=5, h=.5, text=sel.input and 'Input Plan' or 'Input'}}; - local costTbl = {kind = 'vert', w=5,h=0; - {kind = 'hbar', w=5, h=.5, text=sel.input and 'Process Plan' or 'Process'}}; - local reqPane = {kind = 'pane', id='reqPane', w=10, h=7; - {kind = 'hztl', w=10,h=0; inputTbl, costTbl} + local inputTbl = {kind = 'vert', w=6,h=0; + {kind = 'hbar', w=6, h=.5, text=sel.input and 'Input Plan' or 'Input'}}; + local costTbl = {kind = 'vert', w=6,h=0; + {kind = 'hbar', w=6, h=.5, text=sel.input and 'Process Plan' or 'Process'}}; + local reqPane = {kind = 'pane', id='reqPane', w=12, h=8; + {kind = 'hztl', w=12,h=0; inputTbl, costTbl} } local function pushCost(x, t, val) - table.insert(costTbl, {kind='label', w=4.5,h=.5,x=x; + table.insert(costTbl, {kind='label', w=5.5,h=.5,x=x; text=string.format('%s: %s',t,val); }) end local function pushComputeCosts(header, p) if p then - table.insert(costTbl, {kind = 'label', w=5, h=.5, x=0; text=header}); + table.insert(costTbl, {kind = 'label', w=6, h=.5, x=0; text=header}); if p.cycles then pushCost(.5, 'Compute', lib.math.siUI({'cycle','cycles'}, p.cycles, true)) end if p.power then local str = lib.math.siUI('J', p.power) @@ -370,16 +380,16 @@ end end local function fabToUI(x, inputTbl, req) for ci,c in ipairs(req) do - table.insert(inputTbl, {kind = 'label', w=5-x, h=.5, x=x; + table.insert(inputTbl, {kind = 'label', w=6-x, h=.5, x=x; text=lib.str.capitalize(c.header)}); for ei,e in ipairs(c.list) do - table.insert(inputTbl, {kind = 'hztl', w=4.5-x, h=.5, x=x+.5; + table.insert(inputTbl, {kind = 'hztl', w=5.5-x, h=.5, x=x+.5; {kind='img', w=.5,h=.5, img=e.img}; - {kind='label', w=3.3,h=.5,x=.2, text=lib.str.capitalize(e.label)}; + {kind='label', w=4.3,h=.5,x=.2, text=lib.str.capitalize(e.label)}; }); end end end @@ -429,12 +439,12 @@ end if not ok then commitHue = 0 end end table.insert(pgmSelector, reqPane) table.insert(pgmSelector, {kind = 'hztl', w=10,h=1.2; - {kind = 'button', id='back', label = '← Back', w=5,h=1.2}; - {kind = 'button', id='commit', label = commitLabel .. ' →', w=5,h=1.2, color={hue=commitHue,sat=0,lum=0}}; + {kind = 'button', id='back', label = '← Back', w=6,h=1.2}; + {kind = 'button', id='commit', label = commitLabel .. ' →', w=6,h=1.2, color={hue=commitHue,sat=0,lum=0}}; }) end end local rec = getRecentJobs(state) @@ -444,51 +454,70 @@ local out = ItemStack(starlit.item.sw.db[id].output) table.insert(recentList, {kind='contact',w=1.5,h=1.5,id=string.format('recent_%s',i), item = out}) end end local queue = {kind='pane', w=5, h=9.5} + local cst = state.ctx.availableChips() for i,v in ipairs(state.pgm.file.body.conf) do if v.key == 'job' then local job = starlit.store.compilerJob.dec(v.value) - local scm = starlit.item.sw.db[job.schematic] - local cycTotal = (scm.cost and scm.cost.cycles or 0) - local secTotal = (scm.input.time and scm.input.time.print or 0) - local cycPct = cycTotal == 0 and 1 or (1 - job.cyclesLeft/cycTotal) - local secPct = secTotal == 0 and 1 or (1 - job.timeLeft/secTotal) - local out = ItemStack(scm.output) - local cycBar = {kind = 'hbar', fac = cycPct, w=5-1.5, h = .5; - color={hue=150,sat=0,lum=0}; text=string.format("Compute %s%%", math.floor(cycPct*100)); + local scm = starlit.mod.electronics.chip.usableSoftware(cst, {{ + id = job.schematic; + sw = starlit.item.sw.db[job.schematic]; + }})[1] + if scm == nil then goto badJob end + local steps = { + {label = 'Compute', n = job.cyclesLeft, color=lib.color(0,1,0); + total = scm.sw.cost and scm.sw.cost.cycles or 0}; + {label = 'Energize', n = job.powerLeft, color=lib.color(0,.5,1); + total = (scm.powerCost or 0) + + (state.pgm.powerCost or 0) + + (scm.sw.input.cost and scm.sw.input.cost.power or 0)}; + {label = 'Assemble', n = job.timeLeft, color=lib.color(1,.2,0); + total = scm.sw.input.time and scm.sw.input.time.print or 0}; + {label = 'Numenize', n = job.numinaLeft, color=lib.color(1,0,1); + total = scm.sw.cost and scm.sw.cost.numina or 0}; } - local secBar = {kind = 'hbar', fac = secPct, w=5-1.5, h = .5; - color={hue=50,sat=0,lum=0}; text=string.format("Assemble %s%%", math.floor(secPct*100)); - } - table.insert(queue, {kind='hztl'; w=5, h=1.5; + local bar = {kind = 'hbar', text = 'Complete', fac=1, w=5-1.5, h = .5} + for i, s in ipairs(steps) do + if s.n > 0 then + local pct = 1 - s.n/s.total + bar.color = s.color + bar.fac = pct + bar.text = string.format("%s %s%%", s.label, math.floor(pct*100)) + break + end + end + + local out = ItemStack(scm.sw.output) + table.insert(queue, {kind='hztl'; w=6, h=1.5; {kind = 'contact', w=1.5,h=1.5, id=string.format('cancel_%s', i), item = out}; - {kind = 'vert', w=5-1.5, h=1.5; - {kind = 'label', text=out:get_definition().short_description, w=5-1.5, h=.75}; - (cycPct < 1 and cycBar or secBar); + {kind = 'vert', w=6-1.5, h=1.5; + {kind = 'label', text=out:get_definition().short_description, w=6-1.5, h=.75}; + bar; } }) end + ::badJob:: end return starlit.ui.build { - kind = 'hztl', padding = 0.5; w = 20, h = 10, mode = 'sw'; - {kind = 'vert', w = 5, h = 5; + kind = 'hztl', padding = 0.5; w = 22, h = 11, mode = 'sw'; + {kind = 'vert', w = 5, h = 15; {kind = 'hbar', fac=0, w = 5, h = .5, text = 'Recent Prints'}; recentList; }; - {kind = 'vert', w = 10, h = 10; - {kind = 'hbar', fac=0, w = 10, h = .5, text = 'Program Select'}; - {kind = 'pane', w = 10, h = 9.5, id='pgmSelect'; - unpack(pgmSelector) + {kind = 'vert', w = 12, h = 11; + {kind = 'hbar', fac=0, w = 12, h = .5, text = 'Program Select'}; + {kind = 'pane', w = 12, h = 10.5, id='pgmSelect'; + pgmSelector }; }; - {kind = 'vert', w = 5, h = 10; + {kind = 'vert', w = 5, h = 11; {kind = 'hbar', fac=0, w = 5, h = .5, text = 'Print Queue'}; queue; }; } end; }; }; }) Index: mods/starlit/interfaces.lua ================================================================== --- mods/starlit/interfaces.lua +++ mods/starlit/interfaces.lua @@ -193,10 +193,16 @@ pullConf = function() local stack = inv:get_stack('starlit_suit_chips', pgm.chipSlot) pgm.fd.chip=stack pgm.file = pgm.fd:read() end; + availableChips = function() + return inv:get_list('starlit_suit_chips') + end; + drawCurrent = function(...) + return user:suitDrawCurrent(...) + end; } end if pgm.sw.powerKind == 'active' then if cfg then @@ -380,10 +386,11 @@ padding = 0.5; } end; }; body = { + refresh = true; render = function(state, user) local barh = .75 local tb = { kind = 'vert', mode = 'sw'; padding = 0.5, Index: mods/starlit/store.lua ================================================================== --- mods/starlit/store.lua +++ mods/starlit/store.lua @@ -25,10 +25,12 @@ starlit.store.compilerJob = G.struct { schematic = T.str; cyclesLeft = T.u64; timeLeft = T.decimal; + powerLeft = T.decimal; + numinaLeft = T.decimal; } starlit.store.persona = G.struct { name = T.str; species = T.str; Index: mods/starlit/suit.lua ================================================================== --- mods/starlit/suit.lua +++ mods/starlit/suit.lua @@ -402,11 +402,11 @@ slotChange(p.from_list, 'take', item) slotChange(p.to_list, 'put', item) end end) -local suitInterval = 2.0 +local suitInterval = 1.0 starlit.startJob('starlit:suit-software', suitInterval, function(delta) local runState = { pgmsRun = {}; flags = {}; } @@ -439,12 +439,18 @@ function prop.pullConf() local stack = inv:get_stack('starlit_suit_chips', suitprog.chipSlot) prop.fd.chip=stack prop.file = prop.fd:read() end + function prop.availableChips() + return inv:get_list('starlit_suit_chips') + end function prop.giveItem(st) u:thrustUpon(st) + end + function prop.drawCurrent(...) + return u:suitDrawCurrent(...) end if enabled and fn(u, prop, suitInterval, runState) then runState.pgmsRun[s] = true end Index: mods/starlit/ui.lua ================================================================== --- mods/starlit/ui.lua +++ mods/starlit/ui.lua @@ -163,11 +163,11 @@ local maxX = startX for _, w in ipairs(def) do idx = idx + 1 local src, st = starlit.ui.build(w, state) -- TODO alignments rowH = math.max(rowH, st.h) - if idx > cols or def.w and (state.x + state.spacing + st.w > def.w) then + if idx > cols or (def.w and (state.x + state.spacing + st.w > def.w)) then totalH = totalH + rowH state.x = startX rowH,idx = 0,0 state.y = state.y + state.spacing + st.h end @@ -291,11 +291,11 @@ elseif def.kind == 'text' then -- TODO paragraph formatter widget('hypertext[%s,%s;%s,%s;%s;%s]', state.x, state.y, def.w, def.h, E(def.id), E(def.text)) elseif def.kind == 'hbar' or def.kind == 'vbar' then -- TODO fancy image bars - local cl = lib.color(state.color) + local cl = lib.color(def.color or state.color) local fg = state.fg or cl:readable(.8,1) local wfac, hfac = 1,1 local clamp = math.min(math.max(def.fac or 0, 0), 1) if def.kind == 'hbar' then wfac = wfac * clamp Index: mods/starlit/user.lua ================================================================== --- mods/starlit/user.lua +++ mods/starlit/user.lua @@ -711,20 +711,20 @@ end inv:set_list(lst, {}) end dropInv 'main' dropInv 'starlit_suit' - self:statDelta('psi', 0, 'death', true) - self:statDelta('nutrition', 1500, 'death', true) - self:statDelta('hydration', 2, 'death', true) - self:statDelta('fatigue', 0, 'death', true) - self:statDelta('stamina', 0, 'death', true) self:updateSuit() end; onRespawn = function(self) local meta = self.entity:get_meta() self.entity:set_pos(vector.from_string(meta:get_string'starlit_spawn')) + self:statDelta('psi', 0, 'death', true) + self:statDelta('nutrition', 1500, 'death', true) + self:statDelta('hydration', 2, 'death', true) + self:statDelta('fatigue', 0, 'death', true) + self:statDelta('stamina', 0, 'death', true) self:updateSuit() return true end; onJoin = function(self) local me = self.entity