Comment: | add storage crate & generic interface for, add LED for print completion, add program tooltips, disfuckulate some longstanding idiot bugs |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
4b3aa092f85aebb8f99a8b846efc0ce4 |
User & Date: | lexi on 2024-05-06 20:58:38 |
Other Links: | manifest | tags |
2024-05-06
| ||
21:29 | fix image regression check-in: 108df84ed3 user: lexi tags: trunk | |
20:58 | add storage crate & generic interface for, add LED for print completion, add program tooltips, disfuckulate some longstanding idiot bugs check-in: 4b3aa092f8 user: lexi tags: trunk | |
16:20 | complete (-ish) matter compiler UI (power drain still missing), add printable chemical light check-in: 3df08bd5ac user: lexi tags: trunk | |
Modified mods/starlit-electronics/init.lua from [6d0114ddbf] to [6f6bfb54e1].
233 233 --[[if not how.gift then -- cheap hack to make starting batteries fully charged 234 234 E.battery.setCharge(st, 0) 235 235 end]] 236 236 E.battery.update(st) 237 237 end; 238 238 }; 239 239 fab = def.fab; 240 + reverseEngineer = def.reverseEngineer; 240 241 dynamo = { 241 242 vtable = E.dynamo.kind.battery; 242 243 }; 243 244 battery = def; 244 245 }; 245 246 }) 246 247 end) ................................................................................ 484 485 return fab.size and fab.size.print or 1 485 486 else 486 487 return bType[s] * (bTier[s] or 1) * (bSize[s] or 1) 487 488 end 488 489 end 489 490 490 491 local swID = 'starlit_electronics:schematic_'..baseID 491 - fab.reverseEngineer = { 492 - complexity = bTier.complexity * bSize.complexity * bType.complexity; 493 - sw = swID; 494 - } 495 492 fab.flag = {print=true} 496 493 497 494 starlit.item.battery.link(id, { 498 495 name = name; 499 496 desc = table.concat({ 500 497 bType.desc or ''; 501 498 bTier.desc or ''; 502 499 bSize.desc or ''; 503 500 }, ' '); 504 501 505 502 fab = fab; 503 + reverseEngineer = { 504 + complexity = bTier.complexity * bSize.complexity * bType.complexity; 505 + sw = swID; 506 + }; 506 507 507 508 capacity = batStat 'capacity'; 508 509 dischargeRate = batStat 'dischargeRate'; 509 510 leak = batStat 'leak'; 510 511 decay = batStat 'decay'; 511 512 }) 512 513 ................................................................................ 540 541 -- chips -- 541 542 ----------- 542 543 543 544 E.sw = {} 544 545 function E.sw.findSchematicFor(item) 545 546 local id = ItemStack(item):get_name() 546 547 local fm = minetest.registered_items[id]._starlit 547 - if not (fm and fm.fab and fm.fab.reverseEngineer) then return nil end 548 - local id = fm.fab.reverseEngineer.sw 548 + if not (fm and fm.reverseEngineer) then return nil end 549 + local id = fm.reverseEngineer.sw 549 550 return id, starlit.item.sw.db[id] 550 551 end 551 552 552 553 E.chip = { file = {} } 553 554 do local T,G = lib.marshal.t, lib.marshal.g 554 555 -- love too reinvent unions from first principles 555 556 E.chip.data = G.struct { ................................................................................ 612 613 elseif file.kind == 'note' then 613 614 local sz = 0x10 + #file.body.author 614 615 for _, e in pairs(file.body.entries) do 615 616 sz = sz + #e.title + #e.body + 0x10 -- header overhead 616 617 end 617 618 return sz 618 619 elseif file.kind == 'research' then 619 - local re = assert(minetest.registered_items[file.body.itemId]._starlit.fab.reverseEngineer) 620 + local re = assert(minetest.registered_items[file.body.itemId]._starlit.reverseEngineer) 620 621 return starlit.item.sw.db[re.sw].size * file.body.progress 621 622 elseif file.kind == 'sw' then 622 623 return starlit.item.sw.db[file.body.pgmId].size 623 624 elseif file.kind == 'genome' then 624 625 return 0 -- TODO 625 626 end 626 627 end ................................................................................ 853 854 } 854 855 local n = 0 855 856 for _, e in pairs(chips) do 856 857 n = n + 1 857 858 if not e:is_empty() then 858 859 local ch = e:get_definition()._starlit.chip 859 860 c.cycles = c.cycles + ch.clockRate 860 - c.ram = c.ram + ch.clockRate 861 + c.ram = c.ram + ch.ram 861 862 c.flashFree = c.flashFree + E.chip.freeSpace(e) 862 863 c.powerEfficiency = c.powerEfficiency + ch.powerEfficiency 863 864 end 864 865 end 865 866 if n > 0 then c.powerEfficiency = c.powerEfficiency / n end 866 867 return c 867 868 end
Modified mods/starlit-electronics/sw.lua from [1f9bdf2a9e] to [f5ad2a2c21].
170 170 job.cyclesLeft = math.max(0, job.cyclesLeft - ctx.comp.cycles) 171 171 if job.cyclesLeft == 0 then 172 172 job.timeLeft = math.max(0, job.timeLeft - interval) 173 173 end 174 174 if job.timeLeft == 0 and job.cyclesLeft == 0 then 175 175 table.remove(conf, jobSlot) 176 176 user:give(scm.output) 177 + user:alarm(-2, 'item') 177 178 else 178 179 conf[jobSlot].value = job_t.enc(job) 179 180 end 180 181 181 182 ctx.saveConf() 182 183 end; 183 184 } ................................................................................ 325 326 size = 1e9; 326 327 cost = { 327 328 cycles = 700e6; 328 329 ram = 1e9; 329 330 }; 330 331 run = pasv_heal(4, 50, .7); 331 332 }) 333 + 334 +starlit.item.sw.link('starlit_electronics:battle_buddy_extreme', { 335 + name = 'BattleBuddy XTREME'; 336 + kind = 'suitPower', powerKind = 'passive'; 337 + desc = "Who needs a unit medic when you've got BattleBuddy XTREME Edition! BattleBuddy XTREME Edition is fully loaded with emergency response protocols for wounds of every caliber, and is GUARANTEED* to keep you alive as long as you can still crawl to safety. BattleBuddy XTREME is not intended for civilian use. By using BattleBuddy XTREME, you commit to unbind House Vacsatar, its subcontractors, and cadet houses from all liability for product failure, intracellular mutilation, transcription drift, runaway prion cascades, or military defeat.\n*Guarantees not legally binding."; 338 + size = 4e9; 339 + cost = { 340 + cycles = 2000e6; 341 + ram = 8e9; 342 + }; 343 + run = pasv_heal(4, 50, .7); 344 +}) 345 +
Modified mods/starlit-scenario/init.lua from [98f93d94ac] to [739d68f851].
30 30 end))) 31 31 local r = E.chip.read(chip) 32 32 r.label = label 33 33 r.files = files 34 34 E.chip.write(chip, r) 35 35 return chip 36 36 end 37 + 38 +local survivalBasics = { 39 + {'starlit_tech:chem_lamp', 0}; 40 + {'starlit_tech:crate', 0}; 41 +} 37 42 38 43 local chipLibrary = { 39 - compendium = makeChip('The Gentleman Adventurer\'s Compleat Wilderness Compendium', { 44 + compendium = makeChip('The Gentleman Adventurer\'s Compleat Wilderness Compendium', lib.tbl.append(survivalBasics, { 40 45 {'starlit_electronics:battery_chemical_imperial_small', 0}; 41 - }, { 46 + }), { 42 47 {'starlit_electronics:shred', 0}; 43 - --{'starlit_electronics:compile_empire', 0}; 48 + {'starlit_electronics:compile_imperial', 0}; 44 49 {'starlit_electronics:autodoc_deluxe', 1}; 45 50 --{'starlit_electronics:driver_compiler_empire', 0}; 46 51 }); 47 - survivalware = makeChip('Emergency Survivalware', { 52 + survivalware = makeChip('Emergency Survivalware', lib.tbl.append(survivalBasics, { 48 53 {'starlit_electronics:battery_chemical_commune_small', 0}; 49 - {'starlit_tech:chem_lamp', 0}; 50 - }, { 54 + }), { 51 55 {'starlit_electronics:shred', 0}; 52 56 {'starlit_electronics:compile_commune', 0}; 53 57 {'starlit_electronics:nanomed', 0}; 54 58 {'starlit_electronics:driver_compiler_commune', 0}; 55 59 }); 56 60 misfortune = makeChip("Sold1er0fMisf0rtune TOP Schematic Crackz REPACK", { 61 + {'starlit_tech:chem_lamp', 0}; 57 62 {'starlit_electronics:battery_chemical_usukwinya_mid', 0}; 58 63 {'starlit_electronics:battery_hybrid_imperial_small', 0}; 59 64 -- ammunition 60 - }, {}); 65 + }, { 66 + {'starlit_electronics:battle_buddy_extreme', 1}; -- 67 + }); 61 68 } 62 69 63 70 local battery = function(name) 64 71 local s = ItemStack(name) 65 72 starlit.mod.electronics.battery.setChargeF(s, 1.0) 66 73 return s 67 74 end
Modified mods/starlit-scenario/mod.conf from [8a1ae19f59] to [6a41220601].
1 1 name = starlit_scenario 2 2 title = starlit scenarios 3 3 description = built-in scenarios for Starsoul 4 -depends = starlit, starlit_suit, starlit_electronics, starlit_building, starlit_material 4 +depends = vtlib, starlit, starlit_suit, starlit_electronics, starlit_building, starlit_material, starlit_tech 5 5 # be sure to add any mods from which you list new starting items!
Modified mods/starlit-tech/init.lua from [2a09a8ef6e] to [c5d4cbc341].
11 11 return string.format('starlit_tech:chem_lamp_%s',n) 12 12 end 13 13 local fab = starlit.type.fab { 14 14 element = { carbon = 8, magnesium = 2 }; 15 15 cost = { power = 100 }; 16 16 flag = { print = true }; 17 17 time = { print = 5 }; 18 - reverseEngineer = { 19 - complexity = 1; 20 - sw = 'starlit_tech:schematic_chem_lamp'; 21 - }; 22 18 }; 23 19 for i = stages, 0, -1 do 24 20 minetest.register_node(chemLampID(i), { 25 21 short_description = 'Chem Lamp'; 26 22 description = starlit.ui.tooltip { 27 23 title = 'Chem Lamp'; 28 24 desc = "A simple carbon-frame chemical light source powered by ambient oxygen. Cheap, quick to print, and biodedragable, without any need for an electric grid or complex power storage mechanism. However, the light only lasts a few days, after which the lamp must be recycled or discarded."; ................................................................................ 30 26 props = { 31 27 {title = 'Burn Remaining', desc=lib.math.timespec(stageTimeout * i), affinity=i > 4 and 'good' or 'bad'}; 32 28 {title = 'Mass', desc='10g', affinity='info'}; 33 29 }; 34 30 }; 35 31 drawtype = 'nodebox'; 36 32 groups = { 37 - object = 2; 33 + object = 1; 38 34 attached_node = 1; 39 35 }; 40 36 node_box = { 41 37 type = 'fixed'; 42 38 fixed = { 43 39 -.4, -.5, -.20; 44 40 .4, -.3, .20; ................................................................................ 61 57 on_timer = i ~= 0 and function(pos) 62 58 local me = minetest.get_node(pos) 63 59 minetest.swap_node(pos, {name=chemLampID(i-1), param2=me.param2}) 64 60 return i > 1 65 61 end or nil; 66 62 _starlit = { 67 63 mass = 10; 68 - fab = fab; 64 + reverseEngineer = { 65 + complexity = 1; 66 + sw = 'starlit_tech:schematic_chem_lamp'; 67 + }; 69 68 recover = starlit.type.fab { 70 69 element = { 71 70 carbon = 8; 72 71 magnesium = math.floor(lib.math.lerp(i/stages, 0, 2)); 73 72 }; 74 73 time = { 75 74 shred = .5; ................................................................................ 89 88 cost = { 90 89 cycles = 8e9; 91 90 ram = 16e6; 92 91 }; 93 92 rarity = 1; 94 93 }) 95 94 end 95 + 96 + 97 +minetest.register_node('starlit_tech:crate', { 98 + short_description = 'Crate'; 99 + description = starlit.ui.tooltip { 100 + title = 'Crate'; 101 + desc = 'A sturdy but lightweight storage crate made from solid carbon polymer.'; 102 + props = { {title='Mass', affinity='info', desc='100g'} }; 103 + }; 104 + drawtype = 'nodebox'; 105 + node_box = { 106 + type = 'fixed'; 107 + fixed = { 108 + .4, .2, .4; 109 + -.4, -.5, -.2; 110 + }; 111 + }; 112 + groups = { 113 + object = 3; 114 + attached_node = 3; 115 + }; 116 + paramtype2 = 'facedir'; 117 + tiles = { 118 + 'starlit-tech-crate-top.png'; 119 + 'starlit-tech-crate-bottom.png'; 120 + 121 + 'starlit-tech-crate-side.png^[transformFX'; 122 + 'starlit-tech-crate-side.png'; 123 + 124 + 'starlit-tech-crate-back.png'; 125 + 'starlit-tech-crate-front.png'; 126 + }; 127 + _starlit = { 128 + mass = 100; 129 + reverseEngineer = { 130 + complexity = 1; 131 + sw = 'starlit_tech:schematic_crate'; 132 + }; 133 + recover = starlit.type.fab { 134 + element = { carbon = 100; }; 135 + time = { 136 + shred = 1; 137 + shredPower = 3; 138 + }; 139 + }; 140 + }; 141 + on_construct = function(pos) 142 + local m = minetest.get_meta(pos) 143 + local inv = m:get_inventory() 144 + inv:set_size('starlit:contents', 12) 145 + end; 146 + on_rightclick = function(pos, node, luser) 147 + if not luser then return end 148 + local user = starlit.activeUsers[luser:get_player_name()] 149 + user:openUI('starlit:box', 'index', { 150 + inv={ 151 + {id = 'starlit:contents', pos=pos}; 152 + }; 153 + }) 154 + end; 155 +}) 156 + 157 +starlit.item.sw.link('starlit_tech:schematic_crate', { 158 + name = 'Crate Schematic'; 159 + kind = 'schematic'; 160 + input = starlit.type.fab { 161 + element = { carbon = 100; }; 162 + flag = {print = true}; 163 + time = {print = 25}; 164 + cost = {power = 250}; 165 + }; 166 + output = 'starlit_tech:crate'; 167 + size = 48e6; 168 + cost = { 169 + cycles = 12e9; 170 + ram = 16e6; 171 + }; 172 + rarity = 1; 173 +})
Modified mods/starlit/compile.lua from [8a9b22510e] to [5db02bfe42].
314 314 {kind = 'button', w=5,h=1.5; id='showAll', label='Show All'}; 315 315 {kind = 'button', w=5,h=1.5; id='find', label='Find'}; 316 316 }) 317 317 end 318 318 else 319 319 if sel.scm == nil then 320 320 for idx, ent in ipairs(sel.scms) do 321 - local fab = ItemStack(ent.sw.output):get_definition()._starlit.fab 321 + local fab = ent.sw.input 322 322 if fab.flag and fab.flag.print then 323 323 local req = fab:visualize() 324 324 pushSelector('scm_' .. idx, ent.sw.output, ent.sw.name, nil, req) 325 325 end 326 326 end 327 327 table.insert(pgmSelector, back) 328 328 else
Modified mods/starlit/init.lua from [a5bde19f07] to [df4ee2ddd8].
399 399 }) 400 400 minetest.register_item("starlit:_hand_dig", { 401 401 type = "none", 402 402 wield_image = "wieldhand.png", 403 403 wield_scale = {x=1,y=1,z=2.5}, 404 404 tool_capabilities = { 405 405 groupcaps = { 406 - object = {maxlevel=1, times = {.20,.10}}; 406 + object = {maxlevel=1, times = {.10,.20,.40}}; 407 407 plant = {maxlevel=1, times = {.50}}; 408 408 409 409 -- sand, dirt, gravel 410 410 looseClump = {maxlevel=1, times = {1.5, 2.5}}; 411 411 }; 412 412 } 413 413 })
Modified mods/starlit/interfaces.lua from [ddaa1e9478] to [39c7d68ac6].
93 93 kind = i.img and 'contact' or 'button', close = i.close; 94 94 color = i.color; 95 95 fg = i.fg; 96 96 label = i.label; 97 97 img = i.img; 98 98 id = i.id; 99 99 w = bw, h = rh; 100 + desc = i.desc; 100 101 }) 101 102 if i.cfg then 102 103 table.insert(bar, { 103 104 kind = 'button'; 104 105 color = i.color; 105 106 fg = i.fg; 106 107 label = "CFG"; ................................................................................ 306 307 if e.key == 'disable' and e.value == 'yes' then 307 308 color.lum = -.2 308 309 fg = lib.color {hue=color.hue,sat=0.7,lum=0.7} 309 310 break 310 311 end 311 312 end 312 313 end 313 - if tbl then table.insert(tbl, { 314 - color = color, fg = fg; 315 - label = r.sw.label or r.sw.name; 316 - id = string.format('suit_pgm_%s_', id); 317 - cfg = cfg, close = close; 318 - }) end 314 + if tbl then 315 + local props = { 316 + {title = "Size", desc=lib.math.siUI('B', r.sw.size), affinity='info'}; 317 + } 318 + if r.sw.cost and r.sw.cost.ram then 319 + table.insert(props, {title = "Memory Usage", desc=lib.math.siUI('B', r.sw.cost.ram), affinity='info'}) 320 + end 321 + if r.sw.cost and r.sw.cost.cycles then 322 + table.insert(props, {title = "Compute Usage", desc=lib.math.siUI('cycles',r.sw.cost.cycles,true), affinity='info'}) 323 + end 324 + if r.powerCost then 325 + table.insert(props, {title = "Power Draw", desc=lib.math.siUI('W', r.powerCost), affinity='info'}) 326 + end 327 + if r.speed then 328 + table.insert(props, {title = "Minimum Runtime", desc=lib.math.timespec(r.speed), affinity='info'}) 329 + end 330 + table.insert(tbl, { 331 + color = color, fg = fg; 332 + label = r.sw.label or r.sw.name; 333 + id = string.format('suit_pgm_%s_', id); 334 + desc = starlit.ui.tooltip { 335 + title = r.sw.name; 336 + desc = r.sw.desc; 337 + color = lib.color(1,0,.8); 338 + props = props; 339 + }; 340 + cfg = cfg, close = close; 341 + }) 342 + end 319 343 end 320 344 end 321 345 local menu = { kind = 'vert', mode = 'sw', padding = 0.5 } 322 346 if swm then table.insert(menu, abilityMenu(swm)) end 323 347 324 348 local inv = user.entity:get_inventory() 325 349 --[[ ................................................................................ 515 539 user:suitPowerStateSet(suitMode) 516 540 return true 517 541 end 518 542 end; 519 543 }; 520 544 }; 521 545 }) 546 + 547 +starlit.interface.install(starlit.type.ui { 548 + id = 'starlit:box'; 549 + pages = { 550 + index = { 551 + setupState = function(state, user, ctx) 552 + state.ctx = ctx 553 + end; 554 + handle = function(state, user, q) 555 + if q.quit then 556 + user:suitSound 'starlit-quit' -- TODO better sound 557 + end 558 + end; 559 + render = function(state, user) 560 + local body = {kind='vert', w=6; mode='hw', spacing=.5, padding=1 } 561 + for i, l in ipairs(state.ctx.inv) do 562 + local inv = minetest.get_meta(l.pos):get_inventory() 563 + local w = l.w or 6 564 + if l.label then 565 + table.insert(body, {kind = 'hbar'; text = l.label, w=w+.5, h = .5}) 566 + end 567 + table.insert(body, {kind = 'list'; 568 + w = w, h = inv:get_size(l.id)/w; 569 + node = l.pos, inv = l.id; 570 + spacing = .1; 571 + }) 572 + end 573 + table.insert(body, {kind = 'list'; 574 + target = 'current_player', inv = 'main'; 575 + w = 6, h = 1, spacing = 0.1; 576 + }) 577 + return starlit.ui.build(body) 578 + end; 579 + } 580 + } 581 +})
Modified mods/starlit/ui.lua from [16bf595c8c] to [5149fd5b74].
131 131 return climg('', 'starlit-ui-button-sw.png') .. 132 132 climg(':hovered', 'starlit-ui-button-sw-hover.png') .. 133 133 climg(':pressed', 'starlit-ui-button-sw-press.png') 134 134 end 135 135 local function widget(...) 136 136 table.insert(lines, string.format(...)) 137 137 end 138 + local specializedTooltip = false 138 139 if def.kind == 'vert' then 139 140 for _, w in ipairs(def) do 140 141 local src, st = starlit.ui.build(w, state) 141 142 widget('container[%s,%s]%scontainer_end[]', state.x, state.y, src) 142 143 state.y=state.y + state.spacing + st.h 143 144 state.w = math.max(state.w, st.w) 144 145 end 146 + state.y = state.y - state.spacing 145 147 state.w = state.w + state.padding 146 148 state.h = state.y + state.padding/2 147 149 elseif def.kind == 'hztl' then 148 150 for _, w in ipairs(def) do 149 151 local src, st = starlit.ui.build(w, state) 150 152 widget('container[%s,%s]%scontainer_end[]', state.x, state.y, src) 151 153 -- TODO alignments ................................................................................ 195 197 def.id) 196 198 end 197 199 state.w = state.w + state.padding 198 200 state.h = state.h + state.padding/2 199 201 elseif def.kind == 'list' then 200 202 local slotTypes = { 201 203 plain = {hue = 200, sat = -.1, lum = 0}; 202 - element = {hue = 20, sat = -.3, lum = 0}; 204 +-- element = {hue = 20, sat = -.3, lum = 0}; 203 205 chip = {hue = 0, sat = -1, lum = 0}; 204 - psi = {hue = 300, sat = 0, lum = 0}; 206 +-- psi = {hue = 300, sat = 0, lum = 0}; 205 207 power = {hue = 50, sat = 0, lum = .2}; 206 208 } 207 209 local img 208 210 if state.mode == 'hw' then 209 211 img = lib.image('starlit-ui-slot-physical.png'); 210 212 else 211 213 img = lib.image('starlit-ui-slot.png'):shift(slotTypes[def.listContent or 'plain']); 212 214 end 213 215 local spac = state.spacing 216 + local target = def.target 217 + if not target and def.node then 218 + target=string.format('nodemeta:%s,%s,%s', def.node.x,def.node.y,def.node.z) 219 + end 214 220 widget('style_type[list;spacing=%s,%s]',spac,spac) 215 221 assert(def.w and def.h, 'ui-lists require a fixed size') 216 222 for lx = 0, def.w-1 do 217 223 for ly = 0, def.h-1 do 218 224 local ox, oy = state.x + lx*(1+spac), state.y + ly*(1+spac) 219 225 table.insert(lines, string.format('image[%s,%s;1.1,1.1;%s]', ox-0.05,oy-0.05, img:render())) 220 226 end end 221 227 table.insert(lines, string.format('listcolors[#00000000;#ffffff10]')) -- FIXME 222 228 table.insert(lines, string.format('list[%s;%s;%s,%s;%s,%s;%s]', 223 - E(def.target), E(def.inv), 229 + E(target), E(def.inv), 224 230 state.x, state.y, 225 231 def.w, def.h, 226 232 def.idx)) 227 233 local sm = 1 228 234 state.w = def.w * sm + (spac * (def.w - 1)) 229 235 state.h = def.h * sm + (spac * (def.h - 1)) 230 236 elseif def.kind == 'contact' then ................................................................................ 231 237 if def.color then table.insert(lines, btnColorDef(def.id)) end 232 238 local img = def.img 233 239 local desc 234 240 if def.item then 235 241 img = ItemStack(def.item):get_name() 236 242 desc = ItemStack(def.item):get_description() 237 243 end 244 + desc = def.desc or desc 238 245 widget('%simage_button%s[%s,%s;%s,%s;%s;%s;%s]', 239 246 def.item and 'item_' or '', 240 247 def.close and '_exit' or '', 241 248 state.x, state.y, def.w, def.h, 242 249 E(img), E(def.id), E(def.label or '')) 243 - if desc and not def.desc then 250 + if desc then 244 251 widget('tooltip[%s;%s]', E(def.id), E(desc)) 252 + specializedTooltip = true 245 253 end 246 254 elseif def.kind == 'button' then 247 255 if def.color then table.insert(lines, btnColorDef(def.id)) end 248 256 local label = E(def.label or '') 249 257 if state.fg then label = lib.color(state.fg):fmt(label) end 250 258 widget('button%s[%s,%s;%s,%s;%s;%s]', 251 259 def.close and '_exit' or '', 252 260 state.x, state.y, def.w, def.h, 253 261 E(def.id), label) 262 + if def.desc then 263 + widget('tooltip[%s;%s]', E(def.id), E(def.desc)) 264 + specializedTooltip = true 265 + end 254 266 elseif def.kind == 'img' then 255 267 widget('%s[%s,%s;%s,%s;%s]', 256 268 def.item and 'item_image' or 'image', 257 269 state.x, state.y, def.w, def.h, E(def.item or def.img)) 258 270 elseif def.kind == 'label' then 259 271 local txt = E(def.text) 260 272 if state.fg then txt = lib.color(state.fg):fmt(txt) end ................................................................................ 283 295 if def.text then 284 296 widget('hypertext[%s,%s;%s,%s;;%s]', 285 297 state.x, state.y, def.w, def.h, 286 298 string.format('<global halign=center valign=middle color=%s>%s', fg:hex(), E(def.text))) 287 299 end 288 300 end 289 301 290 - if def.desc then 302 + if def.desc and not specializedTooltip then 291 303 local coord 292 304 if def.id then 293 305 coord = E(def.id) 294 306 else 295 307 coord = string.format("%s,%s;%s,%s", state.x, state.y, def.w, def.h) 296 308 end 297 309 widget('tooltip[%s;%s;#000000;#ffffff]', coord, E(def.desc))
Modified mods/starlit/user.lua from [aa3a95c242] to [d58ed76b59].
52 52 side = 'right'; 53 53 }; 54 54 fatigue = { 55 55 icon = lib.image('starlit-ui-alert-fatigue.png'); 56 56 bg = lib.image('starlit-ui-alert-bg-fatigue.png'); 57 57 side = 'right'; 58 58 }; 59 + item = { 60 + icon = lib.image('starlit-ui-alert-item.png'); 61 + bg = lib.image('starlit-ui-alert-bg-success.png'); 62 + side = 'right'; 63 + }; 59 64 } 60 65 61 66 starlit.type.user = lib.class { 62 67 name = 'starlit:user'; 63 68 leds = leds; 64 69 construct = function(ident) 65 70 local name, luser ................................................................................ 289 294 local v,txt,color,txtcolor,hl,hlcolor = def.measure(luser,def) 290 295 v = math.max(0, math.min(1, v)) 291 296 local n = math.floor(v*16) + 1 292 297 local function adjust(img) 293 298 return hudAdjustBacklight(lib.image(img)):shift(color or def.color) 294 299 end 295 300 local img = adjust 'starlit-ui-meter.png' 296 - if def.flipX then 297 - img = img:transform 'FX' 298 - end 299 301 img = img:render() 300 302 img = img .. '^[verticalframe:17:' .. tostring(17 - n) 301 303 if hl then 302 304 hl = math.floor(hl*16) + 1 303 305 local hi = hudAdjustBacklight(lib.image 'starlit-ui-meter-hl.png') 304 306 :shift(hlcolor or def.color) 305 307 :render() 306 308 hi = hi .. '^[verticalframe:17:' .. tostring(17 - hl) 307 309 img = string.format('%s^(%s)', img, hi) 308 310 end 309 311 img = string.format('%s^(%s)', img, adjust 'starlit-ui-meter-readout.png':render()) 312 + if def.flipX then 313 + img = img .. '^[transformFX' 314 + end 310 315 luser:hud_change(m.meter, 'text', img) 311 316 if txt then 312 317 luser:hud_change(m.readout, 'text', txt) 313 318 end 314 319 if txtcolor then 315 320 luser:hud_change(m.readout, 'number', txtcolor:hex()) 316 321 end
Modified mods/vtlib/image.lua from [33182947e9] to [a9a0d17ab5].
11 11 local bracket = false 12 12 if self.combine then 13 13 str = string.format('[combine:%sx%s', self.w, self.h) 14 14 for _,i in pairs(self.atop) do 15 15 str = str .. string.format(':%s,%s=(%s)', i.at.x, i.at.y, i.img:render()) 16 16 end 17 17 else 18 - for _,i in pairs(self.atop) do 19 - str = '(' .. i.img:render() .. ')^' .. str 20 - end 21 18 if str ~= '' then 22 19 str = str .. '(' 23 20 bracket = true 24 21 end 22 + for _,i in pairs(self.atop) do 23 + str = '(' .. i.img:render() .. ')^' .. str 24 + end 25 25 str = str .. self.string 26 26 end 27 27 for _,e in pairs(self.fx) do 28 28 str = str .. '^[' .. e 29 29 -- be sure to escape ones that take arguments 30 30 -- correctly! 31 31 end
Modified mods/vtlib/math.lua from [557fe13815] to [276f7a5d6e].
77 77 return string.format("%s%s%s", 78 78 vd, (full and (' ' .. pmin) or smin), unitForAmt(vd)) 79 79 end 80 80 end 81 81 end 82 82 end 83 83 84 + if prec then val = lib.math.trim(val,prec) end 84 85 return string.format("%s%s", val, unitForAmt(val)) 85 86 end 86 87 function fn.siUI(u,v,f,us,...) return fn.si(u,v,f,us,2,...) end 87 88 88 89 function fn.lerp(t, a, b) return (1-t)*a + t*b end 89 90 function fn.gradient(grad, pos) 90 91 local n = #grad ................................................................................ 154 155 end; 155 156 } 156 157 -- function fn.vlerp 157 158 158 159 function fn.timespec(n) 159 160 if n == 0 then return '0s' end 160 161 if n < 0 then return '-' .. fn.timespec(n*-1) end 162 + if n < 1 then return fn.siUI('s', n) end 161 163 162 164 local sec = math.floor(n % 60) 163 165 local min = math.floor(n / 60) 164 166 local hr = math.floor(min / 60) 165 167 min = min % 60 166 168 local spec = {} 167 169 168 170 if hr ~= 0 then table.insert(spec, string.format("%shr", hr)) end 169 171 if min ~= 0 then table.insert(spec, string.format("%sm", min)) end 170 172 if sec ~= 0 then table.insert(spec, string.format("%ss", sec)) end 171 173 return table.concat(spec, ' ') 172 174 end 173 175 return fn