Overview
Comment: | plant growth, edibles, fixes |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
e829ca194a0a1cb867d8e29e733a69d1 |
User & Date: | lexi on 2024-05-02 00:22:47 |
Other Links: | manifest | tags |
Context
2024-05-02
| ||
20:27 | check in missing mod, add forest biome, racial powers, overlays (untested) check-in: 6deb9bedbc user: lexi tags: trunk | |
00:22 | plant growth, edibles, fixes check-in: e829ca194a user: lexi tags: trunk | |
2024-05-01
| ||
16:25 | fixes, sounds; add license info check-in: 0e67c606c9 user: lexi tags: trunk | |
Changes
Modified mods/starlit-electronics/sw.lua from [e776ef774d] to [eb892cff12].
129 129 kind = 'suitPower', powerKind = 'active'; 130 130 desc = 'An open-source program used in its various forks and iterations all across human-inhabited space and beyond. Rumored to contain fragments of code stolen from the nanoware of the Greater Races by an elusive infoterrorist.'; 131 131 size = 500e3; 132 132 cost = { 133 133 cycles = 100e6; 134 134 ram = 500e6; 135 135 }; 136 - run = shredder{range=2, powerDraw=200}; 136 + run = shredder{range=3, powerDraw=200}; 137 137 }) 138 138 139 139 starlit.item.sw.link('starlit_electronics:compile_commune', { 140 140 name = 'Compile Matter'; 141 141 kind = 'suitPower', powerKind = 'direct'; 142 142 desc = "A basic suit matter compiler program, rather slow but ruthlessly optimized for power- and memory-efficiency by some of the Commune's most fanatic coders."; 143 143 size = 700e3;
Modified mods/starlit/init.lua from [c40c4aaae1] to [e52f2bba90].
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 52 food = lib.registry.mk 'starlit:food'; 53 + seed = lib.registry.mk 'starlit:seed'; 53 54 }; 54 55 55 56 region = { 56 57 radiator = { 57 58 store = AreaStore(); 58 - emitters = {} 59 + emitters = {}; 59 60 }; 60 61 }; 61 62 62 63 -- standardized effects 63 64 fx = {}; 64 65 65 66 type = {}; ................................................................................ 386 387 }) 387 388 minetest.register_item("starlit:_hand_dig", { 388 389 type = "none", 389 390 wield_image = "wieldhand.png", 390 391 wield_scale = {x=1,y=1,z=2.5}, 391 392 tool_capabilities = { 392 393 groupcaps = { 393 - plant = {maxlevel=1, times = {.50,.5,.5}}; 394 - dirt = {maxlevel=1, times = {2.5,1,1}}; 394 + plant = {maxlevel=1, times = {.50}}; 395 + dirt = {maxlevel=1, times = {2.5}}; 396 + 397 + log = {maxlevel=1, times = {1}}; 395 398 }; 396 399 } 397 400 }) 398 401 399 402 minetest.register_on_player_inventory_action(function(luser, act, inv, p) 400 403 local name = luser:get_player_name() 401 404 local user = starlit.activeUsers[name] ................................................................................ 418 421 -- cranked by similarly 419 422 end 420 423 return delta 421 424 end, true) 422 425 423 426 function minetest.handle_node_drops(pos, drops, digger) 424 427 local function jitter(pos) 425 - local function r(x) return x+math.random(-0.2, 0.2) end 428 + local function r(x) return x+math.random(-0.01, 0.01) end 426 429 return vector.new( 427 430 r(pos.x), 428 431 r(pos.y), 429 432 r(pos.z) 430 433 ) 431 434 end 432 435 for i, it in ipairs(drops) do 433 - minetest.add_item(jitter(pos), it) 436 + local it = minetest.add_item(jitter(pos), it) 437 + local dp = vector.new(0,0,0) 438 + if digger then dp = digger:get_pos() end 439 + local delta = dp - it:get_pos() 440 + it:add_velocity(vector.new(delta.x,0,delta.z)); 434 441 end 435 442 end 436 443 437 444 438 445 -- TODO timer iterates live UI 439 446
Modified mods/starlit/interfaces.lua from [5877ccf3fb] to [497adf50ee].
345 345 local tb = { 346 346 kind = 'vert', mode = 'sw'; 347 347 padding = 0.5, 348 348 {kind = 'hztl', padding = 0.25; 349 349 {kind = 'label', text = 'Name', w = 2, h = barh}; 350 350 {kind = 'label', text = user.persona.name, w = 4, h = barh}}; 351 351 } 352 - local statBars = {'hunger', 'thirst', 'fatigue', 'morale', 'irradiation', 'illness'} 352 + local statBars = {'nutrition', 'hydration', 'fatigue', 'morale', 'irradiation', 'illness'} 353 353 for idx, id in ipairs(statBars) do 354 354 local s = starlit.world.stats[id] 355 355 local amt, sv = user:effectiveStat(id) 356 356 local min, max = starlit.world.species.statRange(user.persona.species, user.persona.speciesVariant, id) 357 357 local st = string.format('%s / %s', s.desc(amt, true), s.desc(max)) 358 358 table.insert(tb, {kind = 'hztl', padding = 0.25; 359 359 {kind = 'label', w=2, h=barh, text = s.name};
Modified mods/starlit/species.lua from [642ae8f101] to [b30e9eb59a].
45 45 46 46 return {lining, plate, skin, skin, eye, hair} 47 47 end; 48 48 stats = { 49 49 psiRegen = 1.3; 50 50 psiPower = 1.2; 51 51 psi = 1.2; 52 - hunger = .8; -- women have smaller stomachs 53 - thirst = .8; 52 + nutrition = .8; -- women have smaller stomachs 53 + hydration = .8; 54 54 staminaRegen = 1.0; 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 = 1800e3 / 24 / 60 / 60; --kCal/s 62 + metabolism = .150; -- kCal/s 63 63 painTolerance = 0.4; 64 - dehydration = 3; -- mL/s 64 + dehydration = 10e-4; -- L/s 65 65 }; 66 66 }; 67 67 male = { 68 68 name = 'Human Male'; 69 69 eyeHeight = 1.6; 70 70 stats = { 71 71 psiRegen = 1.0; 72 72 psiPower = 1.0; 73 73 psi = 1.0; 74 - hunger = 1.0; 75 - thirst = 1.0; 74 + nutrition = 1.0; 75 + hydration = 1.0; 76 76 staminaRegen = .7; -- men are strong but have inferior endurance 77 77 }; 78 78 traits = { 79 79 health = 500; 80 80 painTolerance = 1.0; 81 81 lungCapacity = 1.0; 82 82 sturdiness = 0.3; 83 - metabolism = 2200e3 / 24 / 60 / 60; --Cal/s 84 - dehydration = 5; -- mL/s 83 + metabolism = .150; -- kCal/s 84 + dehydration = 15e-4; -- L/s 85 85 }; 86 86 }; 87 87 }; 88 88 traits = {}; 89 89 }; 90 90 } 91 91 ................................................................................ 165 165 if base == true then 166 166 base = max 167 167 elseif base == false then 168 168 base = min 169 169 end 170 170 171 171 end 172 - return min, max, base 172 + return min, max, base or 0 173 173 end 174 174 175 175 -- set the necessary properties and create a persona for a newspawned entity 176 176 function starlit.world.species.birth(pSpecies, pVariant, entity, circumstances) 177 177 circumstances = circumstances or {} 178 178 local sp,var = spLookup(pSpecies, pVariant) 179 179 ................................................................................ 184 184 end 185 185 local ps = starlit.world.species.mkPersonaFor(pSpecies,pVariant) 186 186 local startingHP = pct('health', 1.0) 187 187 if circumstances.injured then startingHP = pct('health', circumstances.injured) end 188 188 if circumstances.psiCharged then ps.statDeltas.psi = pct('psi', circumstances.psiCharged) end 189 189 for k,v in pairs(starlit.world.stats) do ps.statDeltas[k] = 0 end 190 190 ps.statDeltas.warmth = 20 -- don't instantly start dying of frostbite 191 + ps.statDeltas.nutrition = 2000 -- shoulda packed more MRE :c 192 + ps.statDeltas.hydration = 3 -- stay hydrated uwu 191 193 192 194 entity:set_properties{hp_max = var.traits.health or sp.traits.health} 193 195 entity:set_hp(startingHP, 'initial hp') 194 196 return ps 195 197 end 196 198 197 199 function starlit.world.species.paramsFromTable(pSpecies, tbl)
Modified mods/starlit/stats.lua from [523263fc9a] to [c485cf1b8a].
1 1 local lib = starlit.mod.lib 2 +local T,G = lib.marshal.t, lib.marshal.g 2 3 3 4 local function U(unit, prec, fixed) 4 5 local trunc = 2 5 6 if fixed then 6 7 return function(amt, excludeUnit) 7 8 local ta = lib.math.trim(amt/prec, trunc) 8 9 if excludeUnit then return tostring(ta) end 9 - return string.format("%s %s", ta, unit) 10 + return string.format("%s%s", ta, unit) 10 11 end 11 12 else 12 13 return function(amt, excludeUnit) 13 14 local ta = lib.math.trim(amt/prec, trunc) 14 15 if excludeUnit then return tostring(ta) end 15 16 return lib.math.si(unit, amt/prec, nil, nil, trunc) 16 17 end ................................................................................ 20 21 local function C(h, s, l) 21 22 return lib.color {hue = h, sat = s or 1, lum = l or .7} 22 23 end 23 24 starlit.world.stats = { 24 25 psi = {min = 0, max = 500, base = 0, desc = U('ψ', 10), color = C(320), name = 'Numina'}; 25 26 -- numina is measured in daψ 26 27 warmth = {min = -1000, max = 1000, base = 0, desc = U('°C', 10, true), color = C(5), name = 'Warmth'}; 27 - -- warmth in measured in °C×10 28 + -- warmth in measured in d°C 28 29 fatigue = {min = 0, max = 76 * 60, base = 0, desc = U('hr', 60, true), color = C(288,.3,.5), name = 'Fatigue'}; 29 30 -- fatigue is measured in minutes one needs to sleep to cure it 30 31 stamina = {min = 0, max = 20 * 100, base = true, desc = U('m', 100), color = C(88), name = 'Stamina'}; 31 32 -- stamina is measured in how many 10th-nodes (== cm) one can sprint 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 + nutrition = {min = 0, max = 8000, base = 0, desc = U('kCal', 1, true), color = C(43,.5,.4), name = 'Nutrition', srzType = T.decimal}; 34 + -- hunger is measured in kcalories one must consume to cure it. at 0, you start dying 35 + hydration = {min = 0, max = 4, base = 0, desc = U('L', 1), color = C(217, .25,.4), name = 'Hydration', srzType = T.decimal}; 36 + -- thirst is measured in L of H²O required to cure it 36 37 morale = {min = 0, max = 24 * 60 * 10, base = true, desc = U('hr', 60, true), color = C(0,0,.8), name = 'Morale'}; 37 38 -- morale is measured in minutes. e.g. at base rate morale degrades by 38 39 -- 60 points every hour. morale can last up to 10 days 39 - irradiation = {min = 0, max = 20000, base = 0, desc = U('Gy', 1000), color = C(141,1,.5), name = 'Irradiation'}; 40 + irradiation = {min = 0, max = 10, base = 0, desc = U('Gy', 1), color = C(141,1,.5), name = 'Irradiation', srzType = T.decimal}; 40 41 -- irrad is measured is milligreys 41 42 -- 1Gy counters natural healing 42 43 -- ~3Gy counters basic nanomedicine 43 44 -- 5Gy causes death within two weeks without nanomedicine 44 45 -- radiation speeds up psi regen 45 46 -- morale drain doubles with each 2Gy 46 47 illness = {min = 0, max = 1000, base = 0, desc = U('%', 10, true), color = C(71,.4,.25), name = 'Illness'}; 47 48 -- as illness increases, maximum stamina and health gain a corresponding limit 48 49 -- illness is increased by certain conditions, and decreases on its own as your 49 50 -- body heals when those conditions wear off. some drugs can lower accumulated illness 50 51 -- but illness-causing conditions require specific cures 51 52 -- illness also causes thirst and fatigue to increase proportionately 52 53 }
Modified mods/starlit/terrain.lua from [43cb3c61b6] to [033036f747].
4 4 starlit.terrain = {} 5 5 local soilSounds = { 6 6 footstep = 'default-dirt-footstep'; 7 7 dig = 'default-dig-crumbly'; 8 8 dug = 'default-dug-node'; 9 9 } 10 10 local sandSounds = { 11 - footstep = 'default-sand-footstep'; 11 + footstep = {name='default-sand-footstep',gain=0.1}; 12 12 dig = 'default-dig-crumbly'; 13 13 dug = 'default-dug-node'; 14 14 } 15 15 local grassSounds = { 16 16 footstep = 'default-grass-footstep'; 17 17 dig = 'default-dig-crumbly'; 18 18 dug = 'default-dug-node'; ................................................................................ 21 21 minetest.register_node('starlit:soil', { 22 22 description = T 'Soil'; 23 23 tiles = {'default_dirt.png'}; 24 24 groups = {dirt = 1}; 25 25 drop = ''; 26 26 sounds = soilSounds; 27 27 _starlit = { 28 - onDestroy = function() end; 29 28 kind = 'block'; 30 29 elements = {}; 31 30 }; 32 31 }) 33 32 34 33 35 34 minetest.register_node('starlit:sand', {
Modified mods/starlit/user.lua from [a0e5424f99] to [fe75c1df99].
72 72 pushPersona = function(self) 73 73 local s = userStore(self.entity) 74 74 s.write('persona', self.persona) 75 75 end; 76 76 uiColor = function(self) return lib.color {hue=238,sat=.5,lum=.5} end; 77 77 statDelta = function(self, stat, d, cause, abs) 78 78 local dt = self.persona.statDeltas 79 - local base 79 + local min, max, base = self:statRange(stat) 80 80 if abs then 81 - local min, max 82 - min, max, base = self:statRange(stat) 83 81 if d == true then d = max 84 82 elseif d == false then d = min end 85 83 end 86 84 if stat == 'health' then 87 85 self.entity:set_hp(abs and d or (self.entity:get_hp() + d), cause) 88 86 elseif stat == 'breath' then 89 87 self.entity:set_breath(abs and d or (self.entity:get_breath() + d)) 90 88 else 91 89 if abs then 92 90 dt[stat] = d - base 93 91 else 94 92 dt[stat] = dt[stat] + d 95 93 end 94 + 95 + if dt[stat]+base > max then dt[stat] = max-base 96 + elseif dt[stat]+base < min then dt[stat] = min-base end 96 97 self:pushPersona() 97 98 end 99 + 100 + 98 101 self:updateHUD() 99 102 -- TODO trigger relevant animations? 100 103 end; 101 104 lookupSpecies = function(self) 102 105 return starlit.world.species.lookup(self.persona.species, self.persona.speciesVariant) 103 106 end; 104 107 phenoTrait = function(self, trait, dflt) ................................................................................ 469 472 470 473 giveGifts('main', gifts.carry) 471 474 472 475 self:reconfigureSuit() 473 476 474 477 -- i feel like there has to be a better way 475 478 local cx = math.random(-500,500) 476 - local startPoint 479 + local iter, startPoint = 1 477 480 repeat local temp = -100 478 481 local cz = math.random(-500,500) 479 482 local cy = minetest.get_spawn_level(cx, cz) 480 483 if cy then 481 484 startPoint = vector.new(cx,cy,cz) 482 485 temp = starlit.world.climate.eval(startPoint,.5,.5).surfaceTemp 483 486 end 484 - if cx > 10000 then break end -- avoid infiniloop in pathological conditions 487 + iter = iter + 1 488 + if iter > 100 then break end -- avoid infiniloop in pathological conditions 485 489 until temp > -2 486 490 self.entity:set_pos(startPoint) 487 491 meta:set_string('starlit_spawn', startPoint:to_string()) 488 492 end; 489 493 onDie = function(self, reason) 490 494 local inv = self.entity:get_inventory() 491 495 local where = self.entity:get_pos() ................................................................................ 496 500 minetest.item_drop(o, self.entity, where) 497 501 end 498 502 end 499 503 inv:set_list(lst, {}) 500 504 end 501 505 dropInv 'main' 502 506 dropInv 'starlit_suit' 503 - self:statDelta('psi', 0, 'death', true) 504 - self:statDelta('hunger', 0, 'death', true) 505 - self:statDelta('thirst', 0, 'death', true) 506 - self:statDelta('fatigue', 0, 'death', true) 507 - self:statDelta('stamina', 0, 'death', true) 507 + self:statDelta('psi', 0, 'death', true) 508 + self:statDelta('nutrition', 1500, 'death', true) 509 + self:statDelta('hydration', 2, 'death', true) 510 + self:statDelta('fatigue', 0, 'death', true) 511 + self:statDelta('stamina', 0, 'death', true) 508 512 self:updateSuit() 509 513 end; 510 514 onRespawn = function(self) 511 515 local meta = self.entity:get_meta() 512 516 self.entity:set_pos(vector.from_string(meta:get_string'starlit_spawn')) 513 517 self:updateSuit() 514 518 return true ................................................................................ 840 844 local bmr = p:trait 'metabolism' * biointerval 841 845 -- TODO apply modifiers 842 846 843 847 local dehydration = p:trait 'dehydration' * biointerval 844 848 -- you dehydrate faster in higher temp 845 849 dehydration = dehydration * math.max(1, starlit.world.climate.temp(u.entity:get_pos()) / 10) 846 850 847 - u:statDelta('hunger', bmr) 848 - u:statDelta('thirst', dehydration) 851 + u:statDelta('nutrition', -bmr) 852 + u:statDelta('hydration', -dehydration) 853 + 854 + if u:effectiveStat 'nutrition' == 0 then 855 + -- starvation 856 + end 857 + 858 + if u:effectiveStat 'hydration' == 0 then 859 + -- dying of thirst 860 + end 861 + 862 + local rads = u:effectiveStat 'irradiation' 863 + if rads > 0 then 864 + u:statDelta('irradiation', -0.0001 * biointerval) 865 + end 866 + 849 867 end 850 868 end) 851 869 852 870 local cbit = { 853 871 up = 0x001; 854 872 down = 0x002; 855 873 left = 0x004;
Modified mods/starlit/world.lua from [c6867ae3a2] to [4823845880].
137 137 base.node_dig_prediction = stageID(st.swap) 138 138 function base.after_dig_node(pos, node, digger) 139 139 node.name = stageID(st.swap) 140 140 minetest.swap_node(pos, node) 141 141 return true 142 142 end 143 143 end 144 - if st.biolum then 145 - base.light_source = math.floor(st.biolum * (n/stageCt)) 146 - end 144 + if st.biolum then base.light_source = st.biolum; end 147 145 return base 148 146 end 149 147 for i, v in ipairs(b.stages) do 150 148 local n = regStage(i, v) 151 - b.stageNodes[i] = n 152 149 minetest.register_node(stageID(i), n) 150 + b.stageNodes[i] = stageID(i) 153 151 end 154 152 b.fullyGrown = stageID(stageCt) 155 153 156 154 local dec = { 157 155 deco_type = 'simple'; 158 - decoration = b.fullyGrown; 156 + decoration = b.stageNodes; 159 157 height = 1; 160 158 param2 = b.meshOpt or 0; 161 159 } 162 160 for k,v in pairs(b.decoration) do dec[k] = v end 163 161 b.decoration = minetest.register_decoration(dec) 164 162 end) 165 163 ................................................................................ 231 229 end 232 230 -- for every degree of difference you suffer 2 points of damage/s 233 231 local dmg = math.ceil(dv * 2) 234 232 user:statDelta('health', -dmg) 235 233 end 236 234 end 237 235 end) 236 + 237 + 238 +world.ecology.trees.foreach('starlit:tree-gen', {}, function(id, t) 239 + local dec = { 240 + deco_type = 'lsystem'; 241 + treedef = t.def; 242 + } 243 + for k,v in pairs(t.decorate) do dec[k]=v end 244 + minetest.register_decoration(dec) 245 +end) 246 + 247 +minetest.register_abm { 248 + label = "plant growth"; 249 + nodenames = {'group:plant_grow'}; 250 + chance = 15; 251 + interval = 20; 252 + catch_up = true; 253 + action = function(pos, node) 254 + local def = minetest.registered_nodes[node.name]._starlit.plant 255 + local plant = starlit.world.ecology.plants.db[def.id] 256 + local nextStage = plant.stageNodes[def.stage + 1] 257 + minetest.swap_node(pos, {name=nextStage}) 258 + end; 259 +}
Modified mods/vtlib/marshal.lua from [500f446f0a] to [2822b4a0ba].
134 134 -- generic type constructors -- 135 135 ------------------------------- 136 136 137 137 function G.int(bits,signed) 138 138 local bytes = math.ceil(bits / 8) 139 139 local max = 2 ^ bits 140 140 local spoint = math.floor(max/2) 141 - return { 142 - sz = bytes; 143 - name = string.format("%sint<%s>", 141 + local name = string.format("%sint<%s>", 144 142 signed and 's' or 'u', bits 145 143 ); 144 + return { 145 + name = name; 146 + sz = bytes; 146 147 enc = function(obj) 148 + report('encoding %s value=%s', name, dump(obj)) 147 149 obj = obj or 0 148 150 local val = math.abs(obj) 149 151 local str = '' 150 152 if signed then 151 153 local max = math.floor(max / 2) 152 154 if (obj > max) or (obj < (0-(max+1))) then 153 - return m.err.domain end 155 + return error('domain error') end 154 156 if obj < 0 then val = val + spoint end 155 157 -- e.g. for 8bit: 0x80 == -1; 0xFF = -128 156 158 else 157 - if val > max then return m.err.domain end 159 + if val > max then error('domain error') end 158 160 end 159 161 for i=1,bytes do 160 162 local n = math.fmod(val, 0x100) 161 163 str = str .. string.char(n) 162 164 val = math.floor(val / 0x100) 163 165 end 164 166 return str ................................................................................ 198 200 def = ... 199 201 end 200 202 name = 'struct' .. (name and ':' .. name or ''); 201 203 report('defining struct name=%q fields=%s', name, dump(def)) 202 204 return { 203 205 name = name; 204 206 enc = function(obj) 207 + report('encoding struct name=%q vals=%s', name, dump(obj)) 205 208 local enc = m.streamEncoder() 206 209 local n = 0 207 210 for k,ty in pairs(def) do n=n+1 208 211 if obj[k] == nil then error('missing key '..dump(k)..' for type '..ty.name) end 209 212 local encoded = ty.enc(obj[k]) 210 213 enc.push(T.u8.enc(#k), size.enc(#encoded), k, encoded) 211 214 end
Modified mods/vtlib/ui.lua from [121fdb8a0d] to [765cced2b5].
42 42 }; 43 43 44 44 tooltipper = function(dui) 45 45 -- takes a configuration table mapping affinities to colors. 46 46 -- 'neutral' is the only required affinity 47 47 return function(a) 48 48 local color = a.color and a.color:readable(0.65, 1.0) 49 - if color == nil then color = l.color(136,158,177) end 49 + if color == nil then color = l.color(.5,.5,.5) end 50 50 local str = a.title 51 51 if a.desc then 52 52 str = str .. '\n' .. color:fmt(minetest.wrap_text(a.desc,60)) 53 53 end 54 54 if a.props then 55 55 -- str = str .. '\n' 56 56 for _,prop in pairs(a.props) do