Index: mods/starlit-eco/init.lua ================================================================== --- mods/starlit-eco/init.lua +++ mods/starlit-eco/init.lua @@ -9,13 +9,13 @@ def = { node_top = 'starlit:greengraze', depth_top = 1; node_filler = 'starlit:soil', depth_filler = 4; node_riverbed = 'starlit:sand', depth_riverbed = 4; y_min = 0; - y_max = 512; - heat_point = 20; - humidity_point = 35; + y_max = 56; + heat_point = 50; + humidity_point = 40; }; }) world.ecology.biomes.link('starlit:forest', { nightTempDelta = -20; @@ -26,12 +26,12 @@ node_top = 'starlit:greengraze', depth_top = 1; node_filler = 'starlit:soil', depth_filler = 4; node_riverbed = 'starlit:sand', depth_riverbed = 4; y_min = 0; y_max = 256; - heat_point = 50; - humidity_point = 40; + heat_point = 60; + humidity_point = 45; }; }) world.ecology.biomes.link('starlit:desert', { nightTempDelta = -40; @@ -54,11 +54,11 @@ waterTempDelta = 5; seasonalTemp = {0}; -- no seasonal variance def = { y_max = 3; y_min = -512; - heat_point = 50; + heat_point = 60; humidity_point = 70; node_top = 'starlit:sand', depth_top = 1; node_filler = 'starlit:sand', depth_filler = 3; }; }) @@ -68,13 +68,13 @@ waterTempDelta = 5; -- W Sp Su Au W seasonalTemp = {-70, -30, 0, -60, -70}; def = { y_max = 70; - y_min = 1; - heat_point = 0; - humidity_point = 5; + y_min = 0; + heat_point = 20; + humidity_point = 30; node_water_top = 'starlit:ice', depth_water_top = 1; node_top = 'starlit:undergloam', depth_top = 1; node_filler = 'starlit:soil', depth_filler = 2; }; }) @@ -85,12 +85,12 @@ -- W Sp Su Au W seasonalTemp = {-15, 5, 15, 7, -15}; def = { y_max = 30; y_min = 0; - heat_point = 15; - humidity_point = 35; + heat_point = 30; + humidity_point = 30; -- node_top = 'starlit:undergloam', depth_top = 1; node_filler = 'starlit:lifesilt', depth_filler = 5; }; }) @@ -99,11 +99,11 @@ waterTempDelta = 5; -- W Sp Su Au W seasonalTemp = {-30, -20, 0, -20, -30}; def = { y_max = 512; - y_min = 0; + y_min = -512; heat_point = 0; humidity_point = 0; }; }) minetest.register_craftitem('starlit_eco:fiber', { Index: mods/starlit/species.lua ================================================================== --- mods/starlit/species.lua +++ mods/starlit/species.lua @@ -46,14 +46,16 @@ local d = ctx.how.delta local p = user.action.prog.sprint -- is the player currently holding any of WASD local isMoving = bit.band(0x0f, user.entity:get_player_control_bits()) ~= 0 if p and isMoving then + user.cooldownTimes.stamina = minetest.get_gametime() p.cb = p.cb + cost*d - if p.cb >= 10 then - user:statDelta('stamina', -10) - if user:effectiveStat 'stamina' < 10 then halt() end + if p.cb >= 5 then + user:statDelta('stamina', -p.cb) + p.cb = 0 + if user:effectiveStat 'stamina' < cost then halt() end end end elseif ctx.how.state == 'halt' then halt() end @@ -90,48 +92,48 @@ local lining = adorn.suit and adorn.suit.lining or invis return {lining, plate, skin, skin, eye, hair} end; stats = { - psiRegen = 1.3; - psiPower = 1.2; psi = 1.2; nutrition = .8; -- women have smaller stomachs hydration = .8; morale = 0.8; -- you are not She-Bear Grylls + irradiation = 0.8; -- you are smaller, so it takes less rads to kill ya }; traits = { health = 400; lungCapacity = .6; - irradiation = 0.8; -- you are smaller, so it takes less rads to kill ya sturdiness = 0; -- women are more fragile and thus susceptible to blunt force trauma metabolism = .150; -- kCal/s painTolerance = 0.4; dehydration = 10e-4; -- L/s speed = 1.1; - staminaRegen = 30.0; + staminaRegen = 10.0; + psiRegen = 1.3; + psiPower = 1.2; }; }; male = { name = 'Human Male'; eyeHeight = 1.6; stats = { - psiRegen = 1.0; - psiPower = 1.0; psi = 1.0; nutrition = 1.0; hydration = 1.0; - staminaRegen = 20; -- men are strong but have inferior endurance + staminaRegen = 7; -- men are strong but have inferior endurance }; traits = { health = 500; painTolerance = 1.0; lungCapacity = 1.0; sturdiness = 0.3; metabolism = .150; -- kCal/s dehydration = 15e-4; -- L/s speed = 1.0; + psiRegen = 1.0; + psiPower = 1.0; }; }; }; traits = {}; abilities = {bioAbilities.sprint}; Index: mods/starlit/stats.lua ================================================================== --- mods/starlit/stats.lua +++ mods/starlit/stats.lua @@ -26,11 +26,11 @@ -- numina is measured in daψ warmth = {min = -1000, max = 1000, base = 0, desc = U('°C', 10, true), color = C(5), name = 'Warmth'}; -- warmth in measured in d°C fatigue = {min = 0, max = 76 * 60, base = 0, desc = U('hr', 60, true), color = C(288,.3,.5), name = 'Fatigue', srzType = T.decimal}; -- fatigue is measured in minutes one needs to sleep to cure it - stamina = {min = 0, max = 40 * 100, base = true, desc = U('m', 100), color = C(88), name = 'Stamina'}; + stamina = {min = 0, max = 10 * 20, base = true, desc = U('m', 100), color = C(88), name = 'Stamina'}; -- stamina is measured in how many 10th-nodes (== cm) one can sprint nutrition = {min = 0, max = 8000, base = 0, desc = U('kCal', 1, true), color = C(43,.5,.4), name = 'Nutrition', srzType = T.decimal}; -- hunger is measured in kcalories one must consume to cure it. at 0, you start dying hydration = {min = 0, max = 4, base = 0, desc = U('L', 1), color = C(217, .25,.4), name = 'Hydration', srzType = T.decimal}; -- thirst is measured in L of H²O required to cure it Index: mods/starlit/user.lua ================================================================== --- mods/starlit/user.lua +++ mods/starlit/user.lua @@ -38,10 +38,11 @@ return { entity = luser; name = name; hud = { elt = {}; + bar = {}; }; tree = {}; action = { bits = 0; -- for control deltas prog = {}; -- for recording action progress on a node; reset on refocus @@ -58,10 +59,13 @@ }; pref = { calendar = 'commune'; }; overlays = {}; + cooldownTimes = { + stamina = 0; + }; } end; __index = { -------------- -- overlays -- @@ -133,11 +137,13 @@ elseif dt[stat]+base < min then dt[stat] = min-base end self:pushPersona() end - self:updateHUD() + local sb = self.hud.bar[stat] + if sb then sb:update() end +-- self:updateHUD() -- TODO trigger relevant animations? end; statRange = function(self, stat) --> min, max, base return starlit.world.species.statRange( self.persona.species, self.persona.speciesVariant, stat) @@ -317,10 +323,17 @@ createHUD = function(self) local function basicStat(statName) return function(user, bar) return self:effectiveStat(statName) end + end + local function attachBasicStat(def) + local statName = def.stat + def.stat = basicStat(def.stat) + local b = self:attachStatBar(def) + self.hud.bar[statName] = b + return b end local function batteryLookup(user) local max = user:suitPowerCapacity() if max == 0 then return 0, 0 end local ch = user:suitCharge() @@ -327,19 +340,19 @@ return (ch/max)*100, ch/max end local function C(h,s,l) return {hue=h,sat=s,lum=l} end local hbofs = (1+self.entity:hud_get_hotbar_itemcount()) * 25 local bpad = 8 - self.hud.elt.health = self:attachStatBar { - name = 'health', stat = basicStat 'health'; - color = C(340,0,.3), size = 100; + self.hud.elt.health = attachBasicStat { + name = 'health', stat = 'health'; + color = C(10,0,.3), size = 100; pos = {x=0.5, y=1}, ofs = {x = -hbofs, y=-48 - bpad}; dir = 1; align = {x=-1, y=-1}; } - self.hud.elt.stamina = self:attachStatBar { - name = 'stamina', stat = basicStat 'stamina'; + self.hud.elt.stamina = attachBasicStat { + name = 'stamina', stat = 'stamina'; color = C(60,0,.2), size = 100; pos = {x=0.5, y=1}, ofs = {x = -hbofs, y=-24 - bpad}; dir = 1; align = {x=-1, y=-1}; } @@ -348,12 +361,12 @@ color = C(190,0,.2), size = 100; pos = {x=0.5, y=1}, ofs = {x = hbofs - 4, y=-48 - bpad}; dir = 0; align = {x=1, y=-1}; } - self.hud.elt.psi = self:attachStatBar { - name = 'psi', stat = basicStat 'psi'; + self.hud.elt.psi = attachBasicStat { + name = 'psi', stat = 'psi'; color = C(320,0,.2), size = 100; pos = {x=0.5, y=1}, ofs = {x = hbofs - 4, y=-24 - bpad}; dir = 0; align = {x=1, y=-1}; } @@ -396,10 +409,15 @@ local color = self:uiColor():lerp(lib.color(0.3, 1, 0), math.min(1, hot/5)) local txt = string.format("%sGy", math.floor(hot)) return (hot/5), txt, color end; } + + -- special-case the meters + self.hud.bar.irradiation = self.hud.elt.geiger + self.hud.bar.warmth = self.hud.elt.temp + self.hud.elt.crosshair = self:attachImage { name = 'crosshair'; tex = ''; pos = {x=.5, y=.5}; scale = {x=1,y=1}; @@ -426,10 +444,11 @@ z = -1; update = function(user, set) set('text', hudAdjustBacklight(hudCenterBG):render()) end; }; + self:updateHUD() end; deleteHUD = function(self) for name, e in pairs(self.hud.elt) do self:hud_delete(e.id) end @@ -728,11 +747,12 @@ if self:suitCharge() <= 0 then self:suitPowerStateSet 'off' end end - self:updateHUD() +-- self:updateHUD() + self.hud.elt.bat:update() end; reconfigureSuit = function(self) -- and here's where things get ugly -- you can't have an inventory inside another item. to hack around this, -- we use the player as the location of the suit inventories, and whenever @@ -908,10 +928,17 @@ return stack end; }; } + +local clockInterval = 1.0 +starlit.startJob('starlit:clock', clockInterval, function(delta) + for id, u in pairs(starlit.activeUsers) do + u.hud.elt.time:update() + end +end) local biointerval = 1.0 starlit.startJob('starlit:bio', biointerval, function(delta) for id, u in pairs(starlit.activeUsers) do if u:effectiveStat 'health' ~= 0 then @@ -944,11 +971,13 @@ heatPenalty = heatPenalty + tempPenalty end -- penalize heavy phys. activity local stamina, sp = u:effectiveStat 'stamina' + local fatigue, fp = u:effectiveStat 'fatigue' fatiguePenalty = fatiguePenalty * (1 + 9*(1-sp)) + local penaltyFromFatigue = 1 - fp local food = u:effectiveStat 'nutrition' local water = u:effectiveStat 'hydration' local rads = u:effectiveStat 'irradiation' if food < 1000 then moralePenalty = moralePenalty + (1 - (food/1000)) * 5 end @@ -969,14 +998,18 @@ if water == 0 then -- dying of thirst u:statDelta('health', -20*biointerval) end - if sp < 1.0 then - u:statDelta('stamina', u:phenoTrait('staminaRegen',1) / heatPenalty) + if sp < 1.0 and minetest.get_gametime() - u.cooldownTimes.stamina > 5.0 then + u:statDelta('stamina', (u:phenoTrait('staminaRegen',1) * penaltyFromFatigue) / heatPenalty) -- print('stam', u:effectiveStat 'stamina', u:phenoTrait('staminaRegen',1) / heatPenalty, heatPenalty) end + + local morale, mp = u:effectiveStat 'morale' + local pr = u:phenoTrait 'psiRegen' + u:statDelta('psi', pr * penaltyFromFatigue * mp) end end end) local cbit = {