Comment: | cleanups, fixes, begin canister rework, begin ecology |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
a810a756ce2ab6fe9009feee5e363470 |
User & Date: | lexi on 2024-05-01 13:46:45 |
Other Links: | manifest | tags |
2024-05-01
| ||
16:25 | fixes, sounds; add license info check-in: 0e67c606c9 user: lexi tags: trunk | |
13:46 | cleanups, fixes, begin canister rework, begin ecology check-in: a810a756ce user: lexi tags: trunk | |
2024-04-29
| ||
22:49 | rename again check-in: 187bf04c87 user: lexi tags: trunk | |
Modified mods/starlit-electronics/sw.lua from [288b4b5859] to [d777bc86b5].
3 3 -- 🄯 EUPL v1.2 4 4 -- ? 5 5 6 6 ------------------------------- 7 7 -- basic suit nano abilities -- 8 8 ------------------------------- 9 9 local function shredder(prop) 10 - local function getItemsForFab(fab) 10 + local function fabToItemsAndCharges(fab) 11 11 local elt 12 12 if fab then 13 13 elt = fab:elementalize() 14 14 else 15 15 elt = {} 16 16 end 17 - local items = {} 17 + local items,charges = {},{} 18 18 if elt.element then 19 19 for k,v in pairs(elt.element) do 20 - local st = ItemStack { 21 - name = starlit.world.material.element.db[k].form.element; 22 - count = v; 23 - } 24 - table.insert(items, st) 20 + local forms = starlit.world.material.element.db[k].form 21 + if forms.brick then 22 + local st = ItemStack { 23 + name = forms.brick; 24 + count = math.floor(v); 25 + } 26 + table.insert(items, st) 27 + else -- gas, liquid 28 + table.insert(charges, {id = k, mass = v}) 29 + end 25 30 end 26 31 end 27 - return items 32 + print(dump(items)) 33 + return items, charges 28 34 end 29 35 30 36 return function(user, ctx) 31 37 local function cleanup() 32 38 user.action.prog.shred = nil 33 39 if user.action.sfx.shred then 34 40 minetest.sound_fade(user.action.sfx.shred, 1, 0) ................................................................................ 101 107 user:suitSound 'starlit-success' 102 108 if fab then 103 109 local vf = fab 104 110 if vary then 105 111 local rng = (starlit.world.seedbank+0xa891f62)[minetest.hash_node_position(what)] 106 112 vf = vf + vary(rng, {}) 107 113 end 108 - local items = getItemsForFab(vf) 114 + local items, charges = fabToItemsAndCharges(vf) 109 115 for i, it in ipairs(items) do user:give(it) end 116 + -- TODO give gasses, liquids 110 117 end 111 118 else 112 119 user:suitSound 'starlit-error' 113 120 end 114 121 cleanup() 115 122 end 116 123 elseif ctx.how.state == 'halt' then
Modified mods/starlit-material/elements.lua from [5740080b38] to [2a0859e47b].
1 1 local lib = starlit.mod.lib 2 2 local W = starlit.world 3 3 local M = W.material 4 4 5 5 M.element.meld { 6 6 hydrogen = { 7 - name = 'hydrogen', sym = 'H', n = 1; 7 + name = 'hydrogen', sym = 'H', n = 1; density = 8.988e-5; 8 8 gas = true; 9 9 color = lib.color(1,0.8,.3); 10 10 }; 11 11 beryllium = { 12 - name = 'Beryllium', sym = 'Be', n = 4; 12 + name = 'beryllium', sym = 'Be', n = 4; density = 0; 13 13 metal = true; -- rare emerald-stuff 14 14 color = lib.color(0.2,1,0.2); 15 15 }; 16 16 oxygen = { 17 - name = 'oxygen', sym = 'O', n = 8; 17 + name = 'oxygen', sym = 'O', n = 8; density = 0.001429; 18 18 gas = true; 19 19 color = lib.color(.2,1,.2); 20 20 }; 21 21 carbon = { 22 - name = 'carbon', sym = 'C', n = 6; 22 + name = 'carbon', sym = 'C', n = 6, density = 2.266; -- g/cm³ 23 23 color = lib.color(.7,.2,.1); 24 24 }; 25 25 silicon = { 26 - name = 'silicon', sym = 'Si', n = 14; 26 + name = 'silicon', sym = 'Si', n = 14, density = 2.329; 27 27 metal = true; -- can be forged into an ingot 28 28 color = lib.color(.6,.6,.4); 29 29 }; 30 30 potassium = { 31 - name = 'potassium', sym = 'K', n = 19; 31 + name = 'potassium', sym = 'K', n = 19, density = 0.862; 32 32 -- potassium is technically a metal but it's so soft 33 33 -- it can be easily nanoworked without high temps, so 34 34 -- ingots make no sense 35 35 color = lib.color(1,.8,0.1); 36 36 }; 37 37 calcium = { 38 - name = 'calcium', sym = 'Ca', n = 20; 38 + name = 'calcium', sym = 'Ca', n = 20; density = 1.55; 39 39 metal = true; 40 40 color = lib.color(1,1,0.7); 41 41 }; 42 42 aluminum = { 43 - name = 'aluminum', sym = 'Al', n = 13; 43 + name = 'aluminum', sym = 'Al', n = 13; density = 2.7; 44 44 metal = true; 45 45 color = lib.color(0.9,.95,1); 46 46 }; 47 47 iron = { 48 - name = 'iron', sym = 'Fe', n = 26; 48 + name = 'iron', sym = 'Fe', n = 26; density = 7.874; 49 49 metal = true; 50 50 color = lib.color(.3,.3,.3); 51 51 }; 52 52 copper = { 53 - name = 'copper', sym = 'Cu', n = 29; 53 + name = 'copper', sym = 'Cu', n = 29; density = 8.96; 54 54 metal = true; 55 55 color = lib.color(.8,.4,.1); 56 56 }; 57 57 lithium = { 58 - name = 'lithium', sym = 'Li', n = 3; 58 + name = 'lithium', sym = 'Li', n = 3; density = 0.534; 59 59 -- i think lithium is considered a metal but we don't mark it as 60 60 -- one here because making a 'lithium ingot' is insane (even possible?) 61 61 color = lib.color(1,0.8,.3); 62 62 }; 63 63 titanium = { 64 - name = 'titanium', sym = 'Ti', n = 22; 64 + name = 'titanium', sym = 'Ti', n = 22; density = 4.506; 65 65 metal = true; 66 66 color = lib.color(.7,.7,.7); 67 67 }; 68 68 vanadium = { 69 - name = 'vanadium', sym = 'V', n = 23; 69 + name = 'vanadium', sym = 'V', n = 23; density = 6; 70 70 metal = true; 71 71 color = lib.color(.3,0.5,.3); 72 72 }; 73 73 xenon = { 74 - name = 'xenon', sym = 'Xe', n = 54; 74 + name = 'xenon', sym = 'Xe', n = 54; density = 0.005894; 75 75 gas = true; 76 76 color = lib.color(.5,.1,1); 77 77 }; 78 78 argon = { 79 - name = 'argon', sym = 'Ar', n = 18; 79 + name = 'argon', sym = 'Ar', n = 18; density = 0.001784; 80 80 gas = true; 81 81 color = lib.color(0,0.1,.9); 82 82 }; 83 83 osmium = { 84 - name = 'osmium', sym = 'Os', n = 76; 84 + name = 'osmium', sym = 'Os', n = 76; density = 22.59; 85 85 metal = true; 86 86 color = lib.color(.8,.1,1); 87 87 }; 88 88 iridium = { 89 - name = 'iridium', sym = 'Ir', n = 77; 89 + name = 'iridium', sym = 'Ir', n = 77; density = 22.56; 90 90 metal = true; 91 91 color = lib.color(.8,0,.5); 92 92 }; 93 93 technetium = { 94 - name = 'technetium', sym = 'Tc', n = 43; 94 + name = 'technetium', sym = 'Tc', n = 43; density = 11; 95 95 desc = 'Prized by the higher Powers for subtle interactions that elude mere human scholars, technetium is of particular use in nuclear nanobatteries.'; 96 96 metal = true; 97 97 color = lib.color(.2,0.2,1); 98 98 }; 99 99 uranium = { 100 - name = 'uranium', sym = 'U', n = 92; 100 + name = 'uranium', sym = 'U', n = 92; density = 19.1; 101 101 desc = 'A weak but relatively plentiful nuclear fuel.'; 102 102 metal = true; 103 103 color = lib.color(.2,.7,0); 104 104 }; 105 105 thorium = { 106 - name = 'thorium', sym = 'Th', n = 90; 106 + name = 'thorium', sym = 'Th', n = 90; density = 11.7; 107 107 desc = 'A frighteningly powerful nuclear fuel.'; 108 108 metal = true; 109 109 color = lib.color(.7,.3,.1); 110 110 }; 111 111 silver = { 112 - name = 'silver', sym = 'Ag', n = 47; 112 + name = 'silver', sym = 'Ag', n = 47; density = 10.49; 113 113 metal = true; 114 114 color = lib.color(.7,.7,.8); 115 115 }; 116 116 gold = { 117 - name = 'gold', sym = 'Au', n = 79; 117 + name = 'gold', sym = 'Au', n = 79; density = 19.30; 118 118 metal = true; 119 119 color = lib.color(1,.8,0); 120 120 }; 121 121 }
Modified mods/starlit-material/init.lua from [fffa847df5] to [b9ae2a76fd].
2 2 local M = { 3 3 canisterSizes = lib.registry.mk 'starlit_material:canister-size'; 4 4 } 5 5 M.canisterSizes.foreach('starlit_material:canister_link', {}, function(id, sz) 6 6 starlit.item.canister.link(minetest.get_current_modname() .. ':canister_' .. id, { 7 7 name = sz.name; 8 8 slots = sz.slots; 9 - vol = 0.1; -- too big for suit? 9 + vol = sz.vol; -- too big for suit? 10 10 desc = sz.desc; 11 11 }) 12 12 end) 13 13 M.canisterSizes.meld { 14 - tiny = {name = 'Tiny Canister', slots = 1, vol = 0.05}; 15 - small = {name = 'Small Canister', slots = 3, vol = 0.2}; 16 - mid = {name = 'Canister', slots = 5, vol = 0.5}; 17 - large = {name = 'Large Canister', slots = 10, vol = 1.0}; 18 - storage = {name = 'Storage Canister', slots = 50, vol = 5.0}; 14 + tiny = {name = 'Tiny Canister', vol = 1.0}; 15 + small = {name = 'Small Canister', vol = 2.0}; 16 + mid = {name = 'Canister', vol = 4.0}; 17 + large = {name = 'Large Canister', vol = 8.0}; 18 + storage = {name = 'Storage Canister', vol = 16.0}; 19 19 } 20 + 21 +starlit.mod.material = M 20 22 21 23 starlit.include 'elements' 24 +starlit.include 'liquids' 22 25
Modified mods/starlit-scenario/init.lua from [bf764e9a62] to [2d3d2d3760].
1 1 local lib = starlit.mod.lib 2 2 local scenario = starlit.world.scenario 3 +local log = starlit.logger 'scenario' 3 4 4 5 local function makeChip(label, schem, sw) 5 6 local E = starlit.mod.electronics 6 7 local files = {} 7 8 local sz = 0 8 9 for _, e in ipairs(schem) do 9 10 local p = E.sw.findSchematicFor(e[1]) 10 11 if p then 11 12 local file = { 12 13 kind = 'sw', name = '', drm = e[2]; 13 - body = {pgmId = p}; 14 + body = {pgmId = p, conf = {}}; 14 15 } 15 16 table.insert(files, file) 16 17 sz = sz + E.chip.fileSize(file) 17 18 end 18 19 end 19 20 for _, e in ipairs(sw) do 20 21 local file = { 21 22 kind = 'sw', name = '', drm = e[2]; 22 - body = {pgmId = e[1]}; 23 + body = {pgmId = e[1], conf = {}}; 23 24 } 24 25 table.insert(files, file) 25 26 sz = sz + E.chip.fileSize(file) 26 27 end 27 28 local chip = ItemStack(assert(E.chip.findBest(function(c) 28 29 return c.flash >= sz, c.ram + c.clockRate 29 30 end))) ................................................................................ 60 61 61 62 local battery = function(name) 62 63 local s = ItemStack(name) 63 64 starlit.mod.electronics.battery.setChargeF(s, 1.0) 64 65 return s 65 66 end 66 67 68 +local function volume(kind,name,mass) 69 + local sorted = {} 70 + for k,v in pairs(starlit.item.canister.db) do 71 + table.insert(sorted, {id=k, can=v}) 72 + end 73 + table.sort(sorted, function(a,b) return a.can.vol < b.can.vol end) 74 + 75 + local liq = starlit.world.material[kind].db[name] 76 + 77 + local can 78 + for i, v in ipairs(sorted) do 79 + if v.can.vol <= liq.density * mass then 80 + can = ItemStack(i) 81 + break 82 + end 83 + end 84 + if can == nil then log.fatal('failed to find canister size for gift %s', kind) end 85 + 86 + local st = starlit.item.canister.meta(can) 87 + st.write('contents', {kind = kind, id = name, mass = mass}) 88 + 89 + return can 90 +end 91 + 67 92 68 93 table.insert(scenario, { 69 94 id = 'starlit_scenario:imperialExpat'; 70 95 name = 'Imperial Expat'; 71 96 desc = "Hoping to escape a miserable life deep in the grinding gears of the capitalist machine for the bracing freedom of the frontier, you sought entry as a colonist to the new Commune world of Thousand Petal. Fate -- which is to say, terrorists -- intervened, and you wound up stranded on Farthest Shadow with little more than the nanosuit on your back, ship blown to tatters and your soul thoroughly mauled by the explosion of a twisted alien artifact -- which SOMEONE neglected to inform you your ride would be carrying.\nAt least you got some nifty psionic powers out of this whole clusterfuck. Hopefully they're safe to use."; 72 97 73 98 species = 'human'; ................................................................................ 91 116 -- came with this chip already plugged in. it's apparently true 92 117 -- what they say: the Commune is always prepared for everything. 93 118 -- E V E R Y T H I N G. 94 119 }; 95 120 suitGuns = {}; 96 121 suitAmmo = {}; 97 122 suitCans = { 98 - ItemStack('starlit_material:canister_small'); 123 +-- ItemStack('starlit_material:canister_small'); 124 + volume('liquid', 'water', 5); 99 125 }; 100 126 carry = { 101 127 chipLibrary.compendium; 102 128 -- you bought this on a whim before you left the Empire, and 103 129 -- just happened to still have it on your person when everything 104 130 -- went straight to the Wild Gods' privy 105 131 };
Modified mods/starlit-secrets/init.lua from [0a228a51be] to [50a2d37741].
38 38 'the firstborn smonked hella weed'; 39 39 }; 40 40 -- body can also be a function(user,secret) 41 41 } 42 42 } 43 43 } 44 44 45 -TODO would it be useful to impl horn clauses and a general fact database? 46 - is that level of flexibility meaningful? or are simply flags better 47 - 48 45 a secret can be a single piece of information predicated 49 46 on a fact, in which case the secret and fact should share 50 47 the same ID. the ID should be as non-indicative as possible 51 48 to avoid spoilers for devs of unrelated code. 52 49 53 50 a secret can also be manually unlocked e.g. by using an item 54 51 55 52 ]==]-- 56 53 57 54 function sec.prereqCheck(user, pr) 58 55 end
Modified mods/starlit/effect.lua from [eed7790b6a] to [9a580a99bf].
307 307 s.queue(spec.stop, function() 308 308 for _,snd in pairs(snds) do s.silence(snd) end 309 309 end) 310 310 end 311 311 end) 312 312 end 313 313 s.silence = function(sound) 314 + if not sound.handle then return end 314 315 if sound.ctl.fade == 0 then minetest.sound_stop(sound.handle) 315 316 else minetest.sound_fade(sound.handle,sound.ctl.fade or 1,0) end 316 317 end 317 318 local startqueued, termqueued = false, false 318 319 local myid = #starlit.effect.active+1 319 320 s.cancel = function() 320 321 s.abort()
Modified mods/starlit/element.lua from [db8d1e2ad1] to [e6ca28c621].
12 12 -- for the object in question; e.g a normal chunk will be 13 13 -- 100 $element, an ingot will be 1000 $element 14 14 }) 15 15 elseif m.gas then 16 16 M.gas.link(id, { 17 17 name = m.name; 18 18 composition = starlit.type.fab{element = {[id] = 1}}; 19 + density = m.density; 19 20 }) 20 21 elseif m.liquid then 21 22 M.liquid.link(id, { 22 23 name = m.name; 23 24 composition = starlit.type.fab{element = {[id] = 1}}; 25 + density = m.density; 24 26 }) 25 27 end 26 28 end) 27 29 28 30 local F = string.format 29 31 30 32 local function mkEltIndicator(composition) ................................................................................ 63 65 props = { 64 66 {title = 'Mass', desc = lib.math.si('g', g), affinity='info'} 65 67 } 66 68 } 67 69 end 68 70 local comp = {[id] = 1} 69 71 local iblit = mkEltIndicator(comp) 72 + local function img(s) 73 + return iblit(s:colorize(m.color):render()) 74 + end 75 + 70 76 m.form = m.form or {} 71 - m.form.element = eltID 72 77 73 - local powder = F('starlit-element-%s-powder.png', id); 78 + 79 + if not (m.gas or m.liquid) then 80 + local brickID = eltID .. '_brick' 81 + local brickName = F('%s Brick', lib.str.capitalize(m.name)) 82 + m.form.brick = brickID 83 + minetest.register_craftitem(brickID, { 84 + short_description = brickName; 85 + description = tt(brickName, F('A small brick of %s, ready to be worked by a matter compiler', m.name), 1); 86 + inventory_image = img(lib.image 'starlit-item-brick.png'); 87 + wield_image = lib.image 'starlit-item-brick.png':colorize(m.color):render(); 88 + stack_max = 500; 89 + groups = {element=1, brick=1}; 90 + _starlit = { 91 + mass = 1; 92 + material = { 93 + kind = 'element'; 94 + element = id; 95 + }; 96 + fab = starlit.type.fab { 97 + element = comp; 98 + }; 99 + }; 100 + }); 101 + end 102 + 103 + --[[ 104 + local chunk = F('starlit-element-%s-powder.png', id); 74 105 minetest.register_craftitem(eltID, { 75 106 short_description = eltName; 76 - description = tt(eltName, F('Elemental %s kept in suspension by a nanide storage system, ready to be worked by a cold matter compiler', m.name), 1); 77 - inventory_image = iblit(powder); 107 + description = tt(eltName, F('A 1g chunk of elemental %s, ready to be worked by a cold matter compiler', m.name), 1); 108 + inventory_image = iblit(chunk); 78 109 wield_image = powder; 79 110 stack_max = 1000; -- 1kg 80 - groups = {element = 1, powder = 1, specialInventory = 1}; 111 + groups = {element = 1, chunk = 1}; 81 112 _starlit = { 82 113 mass = 1; 83 114 material = { 84 115 kind = 'element'; 85 116 element = id; 86 117 }; 87 118 fab = starlit.type.fab { 88 119 element = comp; 89 120 }; 90 121 }; 91 122 }); 123 + ]] 92 124 end) 93 125 94 126 95 127 M.metal.foreach('starlit:gen-forms', {}, function(id, m) 96 128 local baseID = F('%s:metal_%s_', minetest.get_current_modname(), id) 97 - local brickID, ingotID = baseID .. 'brick', baseID .. 'ingot' 98 - local brickName, ingotName = 99 - F('%s Brick', lib.str.capitalize(m.name)), 100 - F('%s Ingot', lib.str.capitalize(m.name)) 129 + local ingotID = baseID .. 'ingot' 130 + local ingotName = F('%s Ingot', lib.str.capitalize(m.name)) 101 131 m.form = m.form or {} 102 - m.form.brick = brickID 103 132 m.form.ingot = ingotID 104 133 local tt = function(t, d, g) 105 134 return starlit.ui.tooltip { 106 135 title = t, desc = d; 107 136 color = lib.color(0.1,0.1,0.1); 108 137 props = { 109 138 {title = 'Mass', desc = lib.math.si('g', g), affinity='info'} ................................................................................ 119 148 return t 120 149 end 121 150 local iblit = mkEltIndicator(mcomp) 122 151 local function img(s) 123 152 return iblit(s:colorize(m.color):render()) 124 153 end 125 154 126 - minetest.register_craftitem(brickID, { 127 - short_description = brickName; 128 - description = tt(brickName, F('A solid brick of %s, ready to be worked by a matter compiler', m.name), 100); 129 - inventory_image = img(lib.image 'starlit-item-brick.png'); 130 - wield_image = lib.image 'starlit-item-brick.png':colorize(m.color):render(); 131 - stack_max = 10; 132 - groups = {metal = 1, ingot = 1}; 133 - _starlit = { 134 - mass = 100; 135 - material = { 136 - kind = 'metal'; 137 - metal = id; 138 - }; 139 - fab = starlit.type.fab { 140 - flag = {smelt= true}; 141 - element = comp(1e2); 142 - }; 143 - }; 144 - }); 145 - 146 155 minetest.register_craftitem(ingotID, { 147 156 short_description = ingotName; 148 157 description = tt(ingotName, F('A solid ingot of %s, ready to be worked by a large matter compiler', m.name), 1e3); 149 158 inventory_image = img(lib.image('starlit-item-ingot.png')); 150 159 wield_image = lib.image 'starlit-item-ingot.png':colorize(m.color):render(); 151 160 groups = {metal = 1, ingot = 1}; 152 161 stack_max = 5; ................................................................................ 161 170 element = comp(1e3); 162 171 }; 163 172 }; 164 173 }); 165 174 166 175 167 176 end) 177 + 178 +local function canisterMeta(stack) 179 + return lib.marshal.metaStore { 180 + contents = {key = 'starlit:canister_contents', type = starlit.store.volume}; 181 + } (stack) 182 +end 168 183 169 184 local function canisterDesc(stack, def) 170 185 def = def or stack:get_definition()._starlit.canister 171 186 local props = { 172 - {title = 'Charge Slots', affinity = 'info', desc = tostring(def.slots)}; 187 + {title = 'Volume', affinity = 'info', desc = lib.math.si('L', def.vol,nil,nil,2)}; 173 188 }; 174 189 if stack then 190 + --[[ 175 191 local inv = starlit.item.container(stack) 176 192 for i,e in ipairs(inv:list 'elem') do 177 193 local comp = e:get_definition()._starlit.fab 178 194 table.insert(props, { 179 195 title = comp:formula(); 180 196 desc = lib.math.si('g', e:get_count()); 181 197 affinity = 'good'; 182 198 }) 199 + end ]] 200 + local itemMeta = canisterMeta(stack) 201 + local e = itemMeta.read 'contents' 202 + local mass = lib.math.si('g', e.mass, nil, nil, 2) 203 + local def, meas 204 + if e.kind == 'liquid' then 205 + def = M.liquid.db[e.id] 206 + local vol = lib.math.si('L', e.mass * def.composition.density, nil, nil, 2) 207 + meas = string.format("%s %s (%s %s)", vol, def.name, e.mass, def.composition:formula()) 208 + elseif e.kind == 'gas' then 209 + def = M.gas.db[e.id] 210 + meas = string.format("%s %s (%s)", mass, def.name, def.composition:formula()) 183 211 end 184 - -- TODO list masses 212 + local comp = def.composition 213 + table.insert(props, { 214 + title = meas; 215 + desc = def.desc; 216 + affinity = 'info'; 217 + }) 185 218 end 186 219 return starlit.ui.tooltip { 187 - title = def.name, desc = def.desc or 'A canister that can store a charge of elemental powder, gas, or liquid'; 220 + title = def.name, desc = def.desc or 'A canister that can store a charge of gas or liquid'; 188 221 color = lib.color(0.2,0.1,0.1); 189 222 props = props; 190 223 }; 191 224 end 192 225 193 226 starlit.item.canister = lib.registry.mk 'starlit:canister'; 194 227 starlit.item.canister.foreach('starlit:item-gen', {}, function(id, c) ................................................................................ 212 245 sz = c.slots; 213 246 }; 214 247 }; 215 248 }; 216 249 }; 217 250 }) 218 251 end) 252 + 253 +starlit.item.canister.meta = canisterMeta
Modified mods/starlit/init.lua from [1f09b99871] to [6f8dfbcd79].
45 45 }; 46 46 liveUI = { 47 47 -- cached subset of activeUI containing those UIs needing live updates 48 48 }; 49 49 50 50 interface = lib.registry.mk 'starlit:interface'; 51 51 item = { 52 + food = lib.registry.mk 'starlit:food'; 52 53 }; 53 54 54 55 region = { 55 56 radiator = { 56 57 store = AreaStore(); 57 58 emitters = {} 58 59 }; ................................................................................ 91 92 fact = lib.registry.mk 'starlit:fact'; 92 93 time = { 93 94 calendar = { 94 95 empire = { 95 96 name = 'Imperial Regnal Calendar'; 96 97 year = function(t, long) 97 98 local reigns = { 98 - -- if anyone actually makes it to his Honor & Glory Unfailing Persigan I i will be 99 + -- if anyone actually makes it to his Honor & Glory Unfailing Persivan I i will be 99 100 -- exceptionally flattered 100 101 {4, 'Emperor', 'Atavarka', 'the Bold'}; -- died at war 101 102 {9, 'Emperor', 'Vatikserka', 'the Unconquered'}; -- died at war 102 103 {22, 'Emperor', 'Rusifend', 'the Wise'}; -- poisoned at diplomacy 103 104 {61, 'Empress', 'Tafseshendi', 'the Great'}; -- died of an 'insurrection of the innards' after a celebrated reign 104 105 {291, 'Emperor', 'Treptebaska', 'the Unwise'}; -- murdered by his wife in short order 105 106 {292, 'Empress', 'Vilintalti', 'the Impious'}; -- removed by the praetorian elite 106 107 {298, 'Emperor', 'Radavan', 'the Reckless'}; -- died at war 107 108 {316, 'Emperor', 'Suldibrand', 'the Forsaken of Men'}; -- fucked around. found out. 108 - {320, 'Emperor', 'Persigan', 'the Deathless'}; 109 + {350, 'Emperor', 'Persivan', 'the Deathless'}; 109 110 } 110 111 local year, r = math.floor(t / 414) 111 112 for i=1, #reigns do if reigns[i+1][1] < year then r = reigns[i+1] end end 112 113 local reignBegin, title, name, epithet = lib.tbl.unpack(r) 113 114 local ry = 1 + (year - reignBegin) 114 115 return long and string.format('Year %s of the Reign of HH&GU %s %s %s', 115 116 ry, title, name, epithet) or string.format('Y. %s %s', name, ry) ................................................................................ 248 249 end) 249 250 end 250 251 start() 251 252 end 252 253 253 254 starlit.include 'stats' 254 255 starlit.include 'world' 256 +starlit.include 'food' 255 257 starlit.include 'fab' 256 258 starlit.include 'tiers' 257 259 starlit.include 'species' 258 260 259 261 starlit.include 'store' 260 262 261 263 starlit.include 'ui' ................................................................................ 356 358 user.action.bits = bit.bor(user.action.bits, 0x100) 357 359 --return user:trigger('secondary', {state = 'prog', delta = 0}) 358 360 elseif pointChanged(oldTgt, point) then 359 361 user:trigger('retarget', {oldTgt = oldTgt}) 360 362 end 361 363 end 362 364 -- sigh 365 +--[[ 363 366 core.noneitemdef_default.on_place = function(...) 364 367 if not triggerPower(...) then 365 368 minetest.item_place(...) 366 369 end 367 370 end 368 371 core.noneitemdef_default.on_use = function(...) triggerPower(...) end 369 372 core.noneitemdef_default.on_secondary_use = function(...) triggerPower(...) end 373 +]] 374 +print(dump(core.noneitemdef_default)) 375 +minetest.register_item(":", { 376 + type = "none", 377 + wield_image = "wieldhand.png", 378 + wield_scale = {x=1,y=1,z=2.5}, 379 + on_secondary_use = function(...) triggerPower(...) end; 380 +-- on_use = function(...) print'base' end; 381 + after_use = function(...) triggerPower(...) end; 382 +}) 383 +minetest.register_item("starlit:_hand_dig", { 384 + type = "none", 385 + wield_image = "wieldhand.png", 386 + wield_scale = {x=1,y=1,z=2.5}, 387 + tool_capabilities = { 388 + groupcaps = { 389 + plant = {maxlevel=1, times = {.50,.5,.5}}; 390 + dirt = {maxlevel=1, times = {2.5,1,1}}; 391 + }; 392 + } 393 +}) 370 394 371 395 minetest.register_on_player_inventory_action(function(luser, act, inv, p) 372 396 local name = luser:get_player_name() 373 397 local user = starlit.activeUsers[name] 374 398 -- allow UIs to update on UI changes 375 399 local state = starlit.activeUI[name] 376 400 if state then
Modified mods/starlit/interfaces.lua from [1cb802f20f] to [f0b5b90e43].
298 298 }) end 299 299 end 300 300 end 301 301 local menu = { kind = 'vert', mode = 'sw', padding = 0.5 } 302 302 if swm then table.insert(menu, abilityMenu(swm)) end 303 303 304 304 local inv = user.entity:get_inventory() 305 + --[[ 305 306 local cans = inv:get_list 'starlit_suit_canisters' 306 307 if cans and next(cans) then for i, st in ipairs(cans) do 307 308 local id = string.format('starlit_canister_%u_elem', i) 308 309 local esz = inv:get_size(id) 309 310 if esz > 0 then 310 311 local eltW, eltH = listWrap(esz, 5) 311 312 table.insert(menu, {kind = 'hztl', 312 313 {kind = 'img', desc='Elements', img = 'starlit-ui-icon-element.png', w=1,h=1}; 313 314 {kind = 'list', target = 'current_player', inv = id, 314 315 listContent = 'element', w = eltW, h = eltH, spacing = 0.1}; 315 316 }) 316 317 end 317 318 end end 319 + ]] 318 320 319 321 if #menu == 0 then 320 322 table.insert(menu, { 321 323 kind = 'img'; 322 324 img = 'starlit-ui-alert.png'; 323 325 w=2, h=2; 324 326 }) ................................................................................ 343 345 local tb = { 344 346 kind = 'vert', mode = 'sw'; 345 347 padding = 0.5, 346 348 {kind = 'hztl', padding = 0.25; 347 349 {kind = 'label', text = 'Name', w = 2, h = barh}; 348 350 {kind = 'label', text = user.persona.name, w = 4, h = barh}}; 349 351 } 350 - local statBars = {'hunger', 'thirst', 'fatigue', 'morale'} 352 + local statBars = {'hunger', 'thirst', 'fatigue', 'morale', 'irradiation', 'illness'} 351 353 for idx, id in ipairs(statBars) do 352 354 local s = starlit.world.stats[id] 353 355 local amt, sv = user:effectiveStat(id) 354 356 local min, max = starlit.world.species.statRange(user.persona.species, user.persona.speciesVariant, id) 355 357 local st = string.format('%s / %s', s.desc(amt, true), s.desc(max)) 356 358 table.insert(tb, {kind = 'hztl', padding = 0.25; 357 359 {kind = 'label', w=2, h=barh, text = s.name};
Modified mods/starlit/species.lua from [3944fdb227] to [642ae8f101].
14 14 15 15 -- constants 16 16 local animationFrameRate = 60 17 17 18 18 local species = { 19 19 human = { 20 20 name = 'Human'; 21 - desc = 'The weeds of the galactic flowerbed. Humans are one of the Lesser Races, excluded from the ranks of the Greatest Races by souls that lack, in normal circumstances, external psionic channels. Their mastery of the universe cut unexpectedly short, forever locked out of FTL travel, short-lived without augments, and alternately pitied or scorned by the lowest of the low, humans flourish nonetheless due to a capacity for adaptation unmatched among the Thinking Few, terrifyingly rapid reproductive cycles -- and a keen facility for bribery. While the lack of human psions remains a sensitive topic, humans (unlike the bitter and emotional Kruthandi) are practical enough to hire the talent they cannot possess, and have even built a small number of symbiotic civilizations with the more indulging of the Powers. In a galaxy where nearly all sophont life is specialized to a fault, humans have found the unique niche of occupying no particular niche.'; 21 + desc = 'The weeds of the galactic flowerbed. Humans are one of the Lesser Races, excluded from the ranks of the Starlit by souls that lack, in normal circumstances, external psionic channels. Their mastery of the universe cut unexpectedly short, forever locked out of FTL travel, short-lived without augments, and alternately pitied or scorned by the lowest of the low, humans flourish nonetheless due to a capacity for adaptation unmatched among the Thinking Few, terrifyingly rapid reproductive cycles -- and a keen facility for bribery. While the lack of human psions remains a sensitive topic, humans (unlike the bitter and emotional Kruthandi) are practical enough to hire the talent they cannot possess, and have even built a small number of symbiotic civilizations with the more indulging of the Powers. In a galaxy where nearly all sophont life is specialized to a fault, humans have found the unique niche of occupying no particular niche.'; 22 22 scale = 1.0; 23 23 params = { 24 24 {'eyeColor', 'Eye Color', 'tone', {hue=327, sat=0, lum=0}}; 25 25 {'hairColor', 'Hair Color', 'tone', {hue=100, sat=0, lum=0}}; 26 26 {'skinTone', 'Skin Tone', 'tone', {hue= 0, sat=0, lum=0}}; 27 27 }; 28 28 tempRange = { ................................................................................ 55 55 morale = 0.8; -- you are not She-Bear Grylls 56 56 }; 57 57 traits = { 58 58 health = 400; 59 59 lungCapacity = .6; 60 60 irradiation = 0.8; -- you are smaller, so it takes less rads to kill ya 61 61 sturdiness = 0; -- women are more fragile and thus susceptible to blunt force trauma 62 - metabolism = 1800; --Cal 62 + metabolism = 1800e3 / 24 / 60 / 60; --kCal/s 63 63 painTolerance = 0.4; 64 + dehydration = 3; -- mL/s 64 65 }; 65 66 }; 66 67 male = { 67 68 name = 'Human Male'; 68 69 eyeHeight = 1.6; 69 70 stats = { 70 71 psiRegen = 1.0; 71 72 psiPower = 1.0; 72 73 psi = 1.0; 73 74 hunger = 1.0; 75 + thirst = 1.0; 74 76 staminaRegen = .7; -- men are strong but have inferior endurance 75 77 }; 76 78 traits = { 77 79 health = 500; 78 80 painTolerance = 1.0; 79 81 lungCapacity = 1.0; 80 82 sturdiness = 0.3; 81 - metabolism = 2200; --Cal 83 + metabolism = 2200e3 / 24 / 60 / 60; --Cal/s 84 + dehydration = 5; -- mL/s 82 85 }; 83 86 }; 84 87 }; 85 88 traits = {}; 86 89 }; 87 90 } 91 + 88 92 89 93 starlit.world.species = { 90 94 index = species; 91 95 paramTypes = paramTypes; 92 96 } 97 + 98 +starlit.world.species.pheno = lib.class { 99 + name = 'starlit:species.pheno'; 100 + construct = function(pSp, pVar) 101 + local sp, var = starlit.world.species.lookup(pSp, pVar) 102 + return { 103 + species = sp, variant = var; 104 + pSpecies = pSp, pVariant = pVar; 105 + }; 106 + end; 107 + __index = { 108 + trait = function(me, st, dflt) 109 + local v = me.variant.traits[st] or me.species.traits[st] 110 + return v or dflt 111 + end; 112 + }; 113 +} 93 114 94 115 function starlit.world.species.mkDefaultParamsTable(pSpecies, pVariant) 95 116 local sp = species[pSpecies] 96 117 local var = sp.variants[pVariant] 97 118 local vpd = var.defaults or {} 98 119 local tbl = {} 99 120 for _, p in pairs(sp.params) do ................................................................................ 108 129 return { 109 130 species = pSpecies; 110 131 speciesVariant = pVariant; 111 132 bodyParams = starlit.world.species.paramsFromTable(pSpecies, 112 133 starlit.world.species.mkDefaultParamsTable(pSpecies, pVariant) 113 134 ); 114 135 statDeltas = {}; 136 + facts = {}; 115 137 } 116 138 end 117 139 118 140 local function spLookup(pSpecies, pVariant) 119 141 local sp = species[pSpecies] 120 142 local var = sp.variants[pVariant or next(sp.variants)] 121 143 return sp, var ................................................................................ 160 182 local delta = max - min 161 183 return min + delta*p 162 184 end 163 185 local ps = starlit.world.species.mkPersonaFor(pSpecies,pVariant) 164 186 local startingHP = pct('health', 1.0) 165 187 if circumstances.injured then startingHP = pct('health', circumstances.injured) end 166 188 if circumstances.psiCharged then ps.statDeltas.psi = pct('psi', circumstances.psiCharged) end 189 + for k,v in pairs(starlit.world.stats) do ps.statDeltas[k] = 0 end 167 190 ps.statDeltas.warmth = 20 -- don't instantly start dying of frostbite 168 191 169 192 entity:set_properties{hp_max = var.traits.health or sp.traits.health} 170 193 entity:set_hp(startingHP, 'initial hp') 171 194 return ps 172 195 end 173 196
Modified mods/starlit/stats.lua from [c766e87490] to [523263fc9a].
1 1 local lib = starlit.mod.lib 2 2 3 3 local function U(unit, prec, fixed) 4 + local trunc = 2 4 5 if fixed then 5 6 return function(amt, excludeUnit) 6 - if excludeUnit then return tostring(amt/prec) end 7 - return string.format("%s %s", amt/prec, unit) 7 + local ta = lib.math.trim(amt/prec, trunc) 8 + if excludeUnit then return tostring(ta) end 9 + return string.format("%s %s", ta, unit) 8 10 end 9 11 else 10 12 return function(amt, excludeUnit) 11 - if excludeUnit then return tostring(amt/prec) end 12 - return lib.math.si(unit, amt/prec) 13 + local ta = lib.math.trim(amt/prec, trunc) 14 + if excludeUnit then return tostring(ta) end 15 + return lib.math.si(unit, amt/prec, nil, nil, trunc) 13 16 end 14 17 end 15 18 end 16 19 17 20 local function C(h, s, l) 18 21 return lib.color {hue = h, sat = s or 1, lum = l or .7} 19 22 end ................................................................................ 22 25 -- numina is measured in daψ 23 26 warmth = {min = -1000, max = 1000, base = 0, desc = U('°C', 10, true), color = C(5), name = 'Warmth'}; 24 27 -- warmth in measured in °C×10 25 28 fatigue = {min = 0, max = 76 * 60, base = 0, desc = U('hr', 60, true), color = C(288,.3,.5), name = 'Fatigue'}; 26 29 -- fatigue is measured in minutes one needs to sleep to cure it 27 30 stamina = {min = 0, max = 20 * 100, base = true, desc = U('m', 100), color = C(88), name = 'Stamina'}; 28 31 -- stamina is measured in how many 10th-nodes (== cm) one can sprint 29 - hunger = {min = 0, max = 20000, base = 0, desc = U('Cal', 1), color = C(43,.5,.4), name = 'Hunger'}; 30 - -- hunger is measured in calories one must consume to cure it 31 - thirst = {min = 0, max = 1600, base = 0, desc = U('l', 100), color = C(217, .25,.4), name = 'Thirst'}; 32 - -- thirst is measured in centiliters of H²O required to cure it 32 + hunger = {min = 0, max = 2000e3, base = 0, desc = U('kCal', 1000, true), color = C(43,.5,.4), name = 'Hunger'}; 33 + -- hunger is measured in calories one must consume to cure it. at a 2kCal deficit, you start dying 34 + thirst = {min = 0, max = 4e3, base = 0, desc = U('L', 1e3), color = C(217, .25,.4), name = 'Thirst'}; 35 + -- thirst is measured in mL of H²O required to cure it 33 36 morale = {min = 0, max = 24 * 60 * 10, base = true, desc = U('hr', 60, true), color = C(0,0,.8), name = 'Morale'}; 34 37 -- morale is measured in minutes. e.g. at base rate morale degrades by 35 38 -- 60 points every hour. morale can last up to 10 days 36 39 irradiation = {min = 0, max = 20000, base = 0, desc = U('Gy', 1000), color = C(141,1,.5), name = 'Irradiation'}; 37 40 -- irrad is measured is milligreys 38 41 -- 1Gy counters natural healing 39 42 -- ~3Gy counters basic nanomedicine
Modified mods/starlit/store.lua from [73c6f814ce] to [9cc49bcaa7].
8 8 local T,G = lib.marshal.t, lib.marshal.g 9 9 starlit.store = {} -- the serialization equivalent of .type 10 10 11 11 ------------- 12 12 -- persona -- 13 13 ------------- ----------------------------------------------- 14 14 -- a Persona is a structure that defines the nature of -- 15 --- an (N)PC and how it interacts with the Starsoul-managed -- 15 +-- an (N)PC and how it interacts with the Starlit-managed -- 16 16 -- portion of the game world -- things like name, species, -- 17 17 -- stat values, physical characteristics, and so forth -- 18 18 19 19 local statStructFields = {} 20 20 for k,v in pairs(starlit.world.stats) do 21 21 statStructFields[k] = v.srzType or ( 22 22 (v.base == true or v.base > 0) and T.s16 or T.u16 ................................................................................ 47 47 starlit.store.suitMeta = lib.marshal.metaStore { 48 48 batteries = {key = 'starlit:suit_slots_bat', type = T.inventoryList}; 49 49 chips = {key = 'starlit:suit_slots_chips', type = T.inventoryList}; 50 50 elements = {key = 'starlit:suit_slots_elem', type = T.inventoryList}; 51 51 guns = {key = 'starlit:suit_slots_gun', type = T.inventoryList}; 52 52 ammo = {key = 'starlit:suit_slots_ammo', type = T.inventoryList}; 53 53 } 54 + 55 +starlit.store.volume = G.struct { 56 + kind = T.str; 57 + id = T.str; 58 + mass = T.decimal; 59 +}
Modified mods/starlit/suit.lua from [7112e6c94b] to [7f11ba51a8].
61 61 return w 62 62 end; 63 63 onReconfigure = function(self, inv) 64 64 -- apply any changes to item metadata and export any subinventories 65 65 -- to the provided invref, as they may have changed 66 66 local sc = starlit.item.container(self.item, inv, {pfx = 'starlit_suit'}) 67 67 sc:push() 68 - self:pullCanisters(inv) 68 +-- self:pullCanisters(inv) 69 69 end; 70 70 onItemMove = function(self, user, list, act, what) 71 71 -- called when the suit inventory is changed 72 72 if act == 'put' then 73 73 if list == 'starlit_suit_bat' then 74 74 user:suitSound('starlit-suit-battery-in') 75 75 elseif list == 'starlit_suit_chips' then ................................................................................ 86 86 user:suitSound('starlit-insert-snap') 87 87 end 88 88 end 89 89 end; 90 90 def = function(self) 91 91 return self.item:get_definition()._starlit.suit 92 92 end; 93 + --[[ 93 94 pullCanisters = function(self, inv) 94 95 starlit.item.container.dropPrefix(inv, 'starlit_canister') 95 96 self:forCanisters(inv, function(sc) sc:pull() end) 96 97 end; 97 98 pushCanisters = function(self, inv, st, i) 98 99 self:forCanisters(inv, function(sc) 99 100 sc:push() ................................................................................ 108 109 local sc = starlit.item.container(st, inv, {pfx = pfx}) 109 110 if fn(sc, st, i, pfx) then 110 111 inv:set_stack('starlit_suit_canisters', i, st) 111 112 end 112 113 end 113 114 end end 114 115 end; 116 + ]] 115 117 establishInventories = function(self, obj) 116 118 local inv = obj:get_inventory() 117 119 local ct = suitContainer(self.item, inv) 118 120 ct:pull() 121 + --[[ 119 122 self:pullCanisters(inv) 120 123 121 - --[[ 122 124 local def = self:def() 123 125 local sst = suitStore(self.item) 124 126 local function readList(listName, prop) 125 127 inv:set_size(listName, def.slots[prop]) 126 128 if def.slots[prop] > 0 then 127 129 local lst = sst.read(prop) 128 130 inv:set_list(listName, lst) ................................................................................ 213 215 on_use = function(st, luser, pointed) 214 216 local user = starlit.activeUsers[luser:get_player_name()] 215 217 if not user then return end 216 218 -- have mercy on users who've lost their suits and wound 217 219 -- up naked and dying of exposure 218 220 if user:naked() then 219 221 local ss = st:take_item(1) 220 - user:setSuit(starlit.type.suit(ss)) 222 + user:changeSuit(starlit.type.suit(ss)) 221 223 user:suitSound('starlit-suit-don') 222 224 return st 223 225 end 224 226 end; 225 227 inventory_image = icon:render(); 226 228 _starlit = { 227 229 container = {
Modified mods/starlit/terrain.lua from [5a8b3b76d0] to [b5b4e3205a].
78 78 def.img .. '.png'; 79 79 'default_dirt.png'; 80 80 { 81 81 name = 'default_dirt.png^' .. def.img ..'_side.png'; 82 82 tileable_vertical = false; 83 83 }; 84 84 }; 85 - groups = {grass = 1, sub_walk = 1}; 85 + groups = {grass = 1, dirt = 1, sub_walk = 1}; 86 86 drop = ''; 87 87 sounds = grassSounds; 88 88 _starlit = grassfst(2); 89 89 }) 90 90 for i=2,0,-1 do 91 91 local opacity = tostring((i/2.0) * 255) 92 92
Modified mods/starlit/user.lua from [aee7410825] to [43bf528964].
63 63 end; 64 64 __index = { 65 65 pullPersona = function(self) 66 66 -- if later records are added in public updates, extend this function to merge them 67 67 -- into one object 68 68 local s = userStore(self.entity) 69 69 self.persona = s.read 'persona' 70 + self.pheno = starlit.world.species.pheno(self.persona.species, self.persona.speciesVariant) 70 71 end; 71 72 pushPersona = function(self) 72 73 local s = userStore(self.entity) 73 74 s.write('persona', self.persona) 74 75 end; 75 76 uiColor = function(self) return lib.color {hue=238,sat=.5,lum=.5} end; 76 77 statDelta = function(self, stat, d, cause, abs) ................................................................................ 96 97 end 97 98 self:updateHUD() 98 99 -- TODO trigger relevant animations? 99 100 end; 100 101 lookupSpecies = function(self) 101 102 return starlit.world.species.lookup(self.persona.species, self.persona.speciesVariant) 102 103 end; 103 - phenoTrait = function(self, trait) 104 - local s,v = self:lookupSpecies() 105 - return v.traits[trait] or s.traits[trait] or 0 104 + phenoTrait = function(self, trait, dflt) 105 +-- local s,v = self:lookupSpecies() 106 +-- return v.traits[trait] or s.traits[trait] or 0 107 + return self.pheno:trait(trait, dflt) 106 108 end; 107 109 statRange = function(self, stat) --> min, max, base 108 110 return starlit.world.species.statRange( 109 111 self.persona.species, self.persona.speciesVariant, stat) 110 112 end; 111 113 effectiveStat = function(self, stat) 112 114 local val ................................................................................ 345 347 local hot = self:effectiveStat 'irradiation' 346 348 local color = self:uiColor():lerp(lib.color(0.3, 1, 0), math.min(1, hot/5)) 347 349 local txt = string.format("%sGy", math.floor(hot)) 348 350 return (hot/5), txt, color 349 351 end; 350 352 } 351 353 self.hud.elt.crosshair = self:attachImage { 352 - name = 'crosshair '; 354 + name = 'crosshair'; 353 355 tex = ''; 354 356 pos = {x=.5, y=.5}; 355 357 scale = {x=1,y=1}; 356 358 ofs = {x=0, y=0}; 357 359 align = {x=0, y=0}; 358 360 update = function(user, set) 359 361 local imgs = { ................................................................................ 375 377 align = {x=0, y=-1}; 376 378 z = -1; 377 379 update = function(user, set) 378 380 set('text', hudAdjustBacklight(hudCenterBG):render()) 379 381 end; 380 382 }; 381 383 end; 384 + -- horrible horrible HACK 385 + setModeHand = function(self) 386 + local inv = self.entity:get_inventory() 387 + local hnd 388 + if self.actMode == 'off' 389 + then hnd = ItemStack('starlit:_hand_dig') 390 + else hnd = ItemStack() 391 + end 392 + inv:set_stack('hand', 1, hnd) 393 + end; 382 394 onModeChange = function(self, oldMode, silent) 383 395 self.hud.elt.crosshair.update() 384 396 if not silent then 385 397 local sfxt = { 386 398 off = 'starlit-mode-off'; 387 399 nano = 'starlit-mode-nano'; 388 400 psi = 'starlit-mode-psi'; 389 401 weapon = 'starlit-mode-weapon'; 390 402 } 391 403 local sfx = self.actMode and sfxt[self.actMode] or sfxt.off 392 404 self:suitSound(sfx) 405 + self:setModeHand() 393 406 end 394 407 end; 395 408 actModeSet = function(self, mode, silent) 396 409 if not mode then mode = 'off' end 397 410 local oldMode = self.actMode 398 411 self.actMode = mode 399 412 self:onModeChange(oldMode, silent) ................................................................................ 415 428 return minetest.get_player_information(self.name) 416 429 end; 417 430 onSignup = function(self) 418 431 local meta = self.entity:get_meta() 419 432 local inv = self.entity:get_inventory() 420 433 -- the sizes indicated here are MAXIMA. limitations on e.g. the number of elements that may be carried are defined by your suit and enforced through callbacks and UI generation code, not inventory size 421 434 inv:set_size('main', 6) -- carried items and tools. main hotbar. 435 + inv:set_size('hand', 1) -- horrible hack to allow both tools and intrinsics 422 436 423 437 inv:set_size('starlit_suit', 1) -- your environment suit (change at wardrobe) 424 438 inv:set_size('starlit_cfg', 1) -- the item you're reconfiguring / container you're accessing 425 439 426 440 local scenario 427 441 for _, e in pairs(starlit.world.scenario) do 428 442 if e.id == starlit.world.defaultScenario then ................................................................................ 499 513 self:updateSuit() 500 514 return true 501 515 end; 502 516 onJoin = function(self) 503 517 local me = self.entity 504 518 local meta = me:get_meta() 505 519 self:pullPersona() 520 + self:setModeHand() 506 521 507 522 -- formspec_version and real_coordinates are apparently just 508 523 -- completely ignored here 509 524 me:set_formspec_prepend [[ 510 525 bgcolor[#00000000;true] 511 526 style_type[button,button_exit,image_button,item_image_button;border=false] 512 527 style_type[button;bgimg=starlit-ui-button-hw.png;bgimg_middle=8;content_offset=0,-2] ................................................................................ 781 796 give = function(self, item) 782 797 local inv = self.entity:get_inventory() 783 798 local function is(grp) 784 799 return minetest.get_item_group(item:get_name(), grp) ~= 0 785 800 end 786 801 -- TODO notif popups 787 802 if is 'specialInventory' then 803 + --[[ 788 804 if is 'powder' then 789 805 if self:naked() then return item end 790 806 local cans = inv:get_list 'starlit_suit_canisters' 791 807 if cans and next(cans) then for i, st in ipairs(cans) do 792 808 local lst = string.format('starlit_canister_%u_elem', i) 793 809 item = inv:add_item(lst, item) 794 810 if item:is_empty() then break end 795 811 end end 796 812 self:forSuit(function(x) x:pushCanisters(inv) end) 797 813 end 798 814 return item 815 + ]] 799 816 else 800 817 return inv:add_item('main', item) 801 818 end 802 819 end; 803 820 thrustUpon = function(self, item) 804 821 local r = self:give(st) 805 822 if not r:is_empty() then 806 823 return minetest.add_item(self.entity:get_pos(), r) 807 824 end 808 825 end; 826 + consume = function(self, stack, n) 827 + n = n or 1 828 + if n == 0 then n = stack:get_count() end 829 + local fd = stack:take_item(n) 830 + local stats = starlit.world.food.effectiveStats(fd) 831 + 832 + return stack 833 + end; 809 834 }; 810 835 } 811 836 812 837 local biointerval = 3.0 813 838 starlit.startJob('starlit:bio', biointerval, function(delta) 814 839 for id, u in pairs(starlit.activeUsers) do 840 + local p = u.pheno 841 + local bmr = p:trait 'metabolism' * biointerval 842 + -- TODO apply modifiers 843 + 844 + local dehydration = p:trait 'dehydration' * biointerval 845 + -- you dehydrate faster in higher temp 846 + dehydration = dehydration * math.max(1, starlit.world.climate.temp(u.entity:get_pos()) / 10) 815 847 848 + u:statDelta('hunger', bmr) 849 + u:statDelta('thirst', dehydration) 816 850 end 817 851 end) 818 852 819 853 local cbit = { 820 854 up = 0x001; 821 855 down = 0x002; 822 856 left = 0x004;
Modified mods/starlit/world.lua from [830720f731] to [d9bc181e37].
89 89 end 90 90 91 91 world.ecology.biomes.foreach('starlit:biome-gen', {}, function(id, b) 92 92 b.def.name = id 93 93 minetest.register_biome(b.def) 94 94 end) 95 95 96 -world.ecology.biomes.link('starlit:steppe', { 97 - nightTempDelta = -30; 98 - waterTempDelta = 0; 99 - -- W Sp Su Au W 100 - seasonalTemp = {-50, -10, 5, 5, -20, -50}; 101 - def = { 102 - node_top = 'starlit:greengraze', depth_top = 1; 103 - node_filler = 'starlit:soil', depth_filler = 4; 104 - node_riverbed = 'starlit:sand', depth_riverbed = 4; 105 - y_min = 0; 106 - y_max = 512; 107 - heat_point = 10; 108 - humidity_point = 30; 109 - }; 110 -}) 111 - 112 -world.ecology.biomes.link('starlit:ocean', { 113 - nightTempDelta = -35; 114 - waterTempDelta = 5; 115 - seasonalTemp = {0}; -- no seasonal variance 116 - def = { 117 - y_max = 3; 118 - y_min = -512; 119 - heat_point = 15; 120 - humidity_point = 50; 121 - node_top = 'starlit:sand', depth_top = 1; 122 - node_filler = 'starlit:sand', depth_filler = 3; 123 - }; 124 -}) 96 +world.ecology.plants.foreach('starlit:plant-gen', {}, function(id, b) 97 + local stageCt = #b.stages 98 + local function stageID(n) 99 + if n == stageCt then return id end 100 + return id .. string.format('_stage_%s', n) 101 + end 102 + b.stageNodes = {} 103 + local function regStage(n, st) 104 + local base = { 105 + description = b.name; 106 + drawtype = "plantlike"; 107 + tiles = { tostring(st.tex) }; 108 + paramtype = "light"; 109 + paramtype2 = "meshoptions"; 110 + walkable = false; 111 + buildable_to = true; 112 + groups = { 113 + plant = 1; 114 + plant_grow = stageCt ~= n and 1 or 0; 115 + }; 116 + drop = st.drop; 117 + _starlit = { 118 + plant = { 119 + id = id, stage = n; 120 + }; 121 + }; 122 + } 123 + if st.swap then 124 + base.node_dig_prediction = stageID(st.swap) 125 + function base.on_dig(pos, node, digger) 126 + node.name = stageID(st.swap) 127 + minetest.swap_node(pos, node) 128 + return true 129 + end 130 + end 131 + return base 132 + end 133 + for i, v in ipairs(b.stages) do 134 + local n = regStage(i, v) 135 + b.stageNodes[i] = n 136 + minetest.register_node(stageID(i), n) 137 + end 138 + b.fullyGrown = stageID(stageCt) 139 + 140 + local dec = { 141 + deco_type = 'simple'; 142 + decoration = b.fullyGrown; 143 + height = 1; 144 + param2 = 0; 145 + } 146 + for k,v in pairs(b.decoration) do dec[k] = v end 147 + b.decoration = minetest.register_decoration(dec) 148 +end) 125 149 126 150 local toward = lib.math.toward 127 151 local hfinterval = 1.5 128 152 starlit.startJob('starlit:heatflow', hfinterval, function(delta) 129 153 130 154 -- our base thermal conductivity (κ) is measured in °C/°C/s. say the 131 155 -- player is in -30°C weather, and has an internal temperature of
Modified mods/vtlib/image.lua from [479480cc25] to [9575362639].
19 19 str = '(' .. i.img:render() .. ')^' .. str 20 20 end 21 21 if str ~= '' then 22 22 str = str .. '(' 23 23 bracket = true 24 24 end 25 25 str = str .. self.string 26 - end 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 32 32 if bracket then str = str .. ')' end 33 33 return str ................................................................................ 82 82 color = lib.color(color) 83 83 end 84 84 color = color:to_hsl() 85 85 end 86 86 return image.change(self, { 87 87 fx = lib.tbl.append(self.fx, { 88 88 string.format('hsl:%s:%s:%s', 89 - color.hue, color.sat*100, color.lum*100) 89 + color.hue, color.sat, color.lum) 90 90 }) 91 91 }) 92 92 end; 93 93 94 94 rehue = function(self, hue) 95 95 return self.shift{hue=hue, sat=0, lum=0} 96 96 end;
Modified mods/vtlib/marshal.lua from [ec9d9f2682] to [670a4be42e].
201 201 report('defining struct name=%q fields=%s', name, dump(def)) 202 202 return { 203 203 name = name; 204 204 enc = function(obj) 205 205 local enc = m.streamEncoder() 206 206 local n = 0 207 207 for k,ty in pairs(def) do n=n+1 208 + if obj[k] == nil then error('missing key '..dump(k)..' for type '..ty.name) end 208 209 local encoded = ty.enc(obj[k]) 209 210 enc.push(T.u8.enc(#k), size.enc(#encoded), k, encoded) 210 211 end 211 212 return size.enc(n) .. enc.peek() 212 213 end; 213 214 dec = debugger.wrap(function(blob) 214 215 if blob == '' then
Modified mods/vtlib/math.lua from [28fc5b216f] to [988785061c].
22 22 return dsq / (dist^2) 23 23 -- [0,1) == less then 24 24 -- 1 == equal 25 25 -- >1 == greater than 26 26 end 27 27 28 28 -- produce an SI expression for a quantity 29 -fn.si = function(unit, val, full, uncommonScales) 29 +fn.si = function(unit, val, full, uncommonScales, prec) 30 30 if val == 0 then return '0 ' .. unit end 31 31 local scales = { 32 32 {30, 'Q', 'quetta',true, 'q', 'quecto',true}; 33 33 {27, 'R', 'ronna', true, 'r', 'ronto', true}; 34 34 {24, 'Y', 'yotta', true, 'y', 'yocto', true}; 35 35 {21, 'Z', 'zetta', true, 'z', 'zepto', true}; 36 36 {18, 'E', 'exa', true, 'a', 'atto', true}; ................................................................................ 45 45 for i, s in ipairs(scales) do 46 46 local amt, smaj, pmaj, cmaj, 47 47 smin, pmin, cmin = lib.tbl.unpack(s) 48 48 49 49 if math.abs(val) > 1 then 50 50 if uncommonScales or cmaj then 51 51 local denom = 10^amt 52 + local vd = val/denom 53 + if prec then vd = lib.math.trim(vd, prec) end 52 54 if math.abs(val) >= (10^(amt)) then 53 55 return string.format("%s %s%s", 54 - val / denom, (full and pmaj or smaj), unit) 56 + vd, (full and pmaj or smaj), unit) 55 57 end 56 58 end 57 59 elseif math.abs(val) < 1 then 58 60 if uncommonScales or cmin then 59 61 local denom = 10^-amt 62 + local vd = val/denom 63 + if prec then vd = lib.math.trim(vd, prec) end 60 64 if math.abs(val) <= (10^-(amt-1)) then 61 65 return string.format("%s %s%s", 62 - val / denom, (full and pmin or smin), unit) 66 + vd, (full and pmin or smin), unit) 63 67 end 64 68 end 65 69 end 66 70 end 67 71 68 72 return string.format("%s %s", val, unit) 69 73 end