starlit  Diff

Differences From Artifact [e60d6be4a9]:

To Artifact [788077fd8e]:


    36     36   			name = luser:get_player_name()
    37     37   		end
    38     38   		return {
    39     39   			entity = luser;
    40     40   			name = name;
    41     41   			hud = {
    42     42   				elt = {};
           43  +				bar = {};
    43     44   			};
    44     45   			tree = {};
    45     46   			action = {
    46     47   				bits = 0; -- for control deltas
    47     48   				prog = {}; -- for recording action progress on a node; reset on refocus
    48     49   				tgt = {type='nothing'};
    49     50   				sfx = {};
................................................................................
    56     57   				psi = {primary = nil, secondary = nil};
    57     58   				maneuver = nil;
    58     59   			};
    59     60   			pref = {
    60     61   				calendar = 'commune';
    61     62   			};
    62     63   			overlays = {};
           64  +			cooldownTimes = {
           65  +				stamina = 0;
           66  +			};
    63     67   		}
    64     68   	end;
    65     69   	__index = {
    66     70   		--------------
    67     71   		-- overlays --
    68     72   		--------------
    69     73   		updateOverlays = function(self)
................................................................................
   131    135   
   132    136   				if     dt[stat]+base > max then dt[stat] = max-base
   133    137   				elseif dt[stat]+base < min then dt[stat] = min-base end
   134    138   				self:pushPersona()
   135    139   			end
   136    140   
   137    141   
   138         -			self:updateHUD()
          142  +			local sb = self.hud.bar[stat]
          143  +			if sb then sb:update() end
          144  +-- 			self:updateHUD()
   139    145   			-- TODO trigger relevant animations?
   140    146   		end;
   141    147   		statRange = function(self, stat) --> min, max, base
   142    148   			return starlit.world.species.statRange(
   143    149   				self.persona.species, self.persona.speciesVariant, stat)
   144    150   		end;
   145    151   		effectiveStat = function(self, stat)
................................................................................
   315    321   			return bar, {x=3 * def.size, y=16} -- x*2??? what
   316    322   		end;
   317    323   		createHUD = function(self)
   318    324   			local function basicStat(statName)
   319    325   				return function(user, bar)
   320    326   					return self:effectiveStat(statName)
   321    327   				end
          328  +			end
          329  +			local function attachBasicStat(def)
          330  +				local statName = def.stat
          331  +				def.stat = basicStat(def.stat)
          332  +				local b = self:attachStatBar(def)
          333  +				self.hud.bar[statName] = b
          334  +				return b
   322    335   			end
   323    336   			local function batteryLookup(user)
   324    337   				local max = user:suitPowerCapacity()
   325    338   				if max == 0 then return 0, 0 end
   326    339   				local ch = user:suitCharge()
   327    340   				return (ch/max)*100, ch/max
   328    341   			end
   329    342   			local function C(h,s,l) return {hue=h,sat=s,lum=l} end
   330    343   			local hbofs = (1+self.entity:hud_get_hotbar_itemcount()) * 25
   331    344   			local bpad = 8
   332         -			self.hud.elt.health = self:attachStatBar {
   333         -				name = 'health', stat = basicStat 'health';
   334         -				color = C(340,0,.3), size = 100;
          345  +			self.hud.elt.health = attachBasicStat {
          346  +				name = 'health', stat = 'health';
          347  +				color = C(10,0,.3), size = 100;
   335    348   				pos = {x=0.5, y=1}, ofs = {x = -hbofs, y=-48 - bpad};
   336    349   				dir = 1;
   337    350   				align = {x=-1, y=-1};
   338    351   			}
   339         -			self.hud.elt.stamina = self:attachStatBar {
   340         -				name = 'stamina', stat = basicStat 'stamina';
          352  +			self.hud.elt.stamina = attachBasicStat {
          353  +				name = 'stamina', stat = 'stamina';
   341    354   				color = C(60,0,.2), size = 100;
   342    355   				pos = {x=0.5, y=1}, ofs = {x = -hbofs, y=-24 - bpad};
   343    356   				dir = 1;
   344    357   				align = {x=-1, y=-1};
   345    358   			}
   346    359   			self.hud.elt.bat = self:attachStatBar {
   347    360   				name = 'battery', stat = batteryLookup;
   348    361   				color = C(190,0,.2), size = 100;
   349    362   				pos = {x=0.5, y=1}, ofs = {x = hbofs - 4, y=-48 - bpad};
   350    363   				dir = 0;
   351    364   				align = {x=1, y=-1};
   352    365   			}
   353         -			self.hud.elt.psi = self:attachStatBar {
   354         -				name = 'psi', stat = basicStat 'psi';
          366  +			self.hud.elt.psi = attachBasicStat {
          367  +				name = 'psi', stat = 'psi';
   355    368   				color = C(320,0,.2), size = 100;
   356    369   				pos = {x=0.5, y=1}, ofs = {x = hbofs - 4, y=-24 - bpad};
   357    370   				dir = 0;
   358    371   				align = {x=1, y=-1};
   359    372   			}
   360    373   			self.hud.elt.time = self:attachTextBox {
   361    374   				name = 'time';
................................................................................
   394    407   				measure = function(user)
   395    408   					local hot = self:effectiveStat 'irradiation'
   396    409   					local color = self:uiColor():lerp(lib.color(0.3, 1, 0), math.min(1, hot/5))
   397    410   					local txt = string.format("%sGy", math.floor(hot))
   398    411   					return (hot/5), txt, color
   399    412   				end;
   400    413   			}
          414  +
          415  +			-- special-case the meters
          416  +			self.hud.bar.irradiation = self.hud.elt.geiger
          417  +			self.hud.bar.warmth = self.hud.elt.temp
          418  +
   401    419   			self.hud.elt.crosshair = self:attachImage {
   402    420   				name = 'crosshair';
   403    421   				tex = '';
   404    422   				pos = {x=.5, y=.5};
   405    423   				scale = {x=1,y=1};
   406    424   				ofs = {x=0, y=0};
   407    425   				align = {x=0, y=0};
................................................................................
   424    442   				ofs = {x=0, y=0};
   425    443   				align = {x=0, y=-1};
   426    444   				z = -1;
   427    445   				update = function(user, set)
   428    446   					set('text', hudAdjustBacklight(hudCenterBG):render())
   429    447   				end;
   430    448   			};
          449  +			self:updateHUD()
   431    450   		end;
   432    451   		deleteHUD = function(self)
   433    452   			for name, e in pairs(self.hud.elt) do
   434    453   				self:hud_delete(e.id)
   435    454   			end
   436    455   		end;
   437    456   		updateHUD = function(self)
................................................................................
   726    745   				local suit = self:getSuit()
   727    746   				suit:establishInventories(self.entity)
   728    747   
   729    748   				if self:suitCharge() <= 0 then
   730    749   					self:suitPowerStateSet 'off'
   731    750   				end
   732    751   			end
   733         -			self:updateHUD()
          752  +-- 			self:updateHUD()
          753  +			self.hud.elt.bat:update()
   734    754   		end;
   735    755   		reconfigureSuit = function(self)
   736    756   			-- and here's where things get ugly
   737    757   			-- you can't have an inventory inside another item. to hack around this,
   738    758   			-- we use the player as the location of the suit inventories, and whenever
   739    759   			-- there's a change in the content of these inventories, this function is
   740    760   			-- called to serialize those inventories out to the suit stack
................................................................................
   906    926   			local fd = stack:take_item(n)
   907    927   			local stats = starlit.world.food.effectiveStats(fd)
   908    928   
   909    929   			return stack
   910    930   		end;
   911    931   	};
   912    932   }
          933  +
          934  +local clockInterval = 1.0
          935  +starlit.startJob('starlit:clock', clockInterval, function(delta)
          936  +	for id, u in pairs(starlit.activeUsers) do
          937  +		u.hud.elt.time:update()
          938  +	end
          939  +end)
   913    940   
   914    941   local biointerval = 1.0
   915    942   starlit.startJob('starlit:bio', biointerval, function(delta)
   916    943   	for id, u in pairs(starlit.activeUsers) do
   917    944   		if u:effectiveStat 'health' ~= 0 then
   918    945   			local bmr = u:phenoTrait 'metabolism' * biointerval
   919    946   			-- TODO apply modifiers
................................................................................
   942    969   				local tempPenalty = tempDiff/3
   943    970   				moralePenalty = moralePenalty + tempPenalty
   944    971   				heatPenalty = heatPenalty + tempPenalty
   945    972   			end
   946    973   
   947    974   			-- penalize heavy phys. activity
   948    975   			local stamina, sp = u:effectiveStat 'stamina'
          976  +			local fatigue, fp = u:effectiveStat 'fatigue'
   949    977   			fatiguePenalty = fatiguePenalty * (1 + 9*(1-sp))
          978  +			local penaltyFromFatigue = 1 - fp
   950    979   
   951    980   			local food = u:effectiveStat 'nutrition'
   952    981   			local water = u:effectiveStat 'hydration'
   953    982   			local rads = u:effectiveStat 'irradiation'
   954    983   			if food < 1000 then moralePenalty = moralePenalty + (1 - (food/1000)) * 5 end
   955    984   			if water < 1   then moralePenalty = moralePenalty + (1 - (water/1)) * 10 end
   956    985   
................................................................................
   967    996   				u:statDelta('health', -5*biointerval)
   968    997   			end
   969    998   
   970    999   			if water == 0 then -- dying of thirst
   971   1000   				u:statDelta('health', -20*biointerval)
   972   1001   			end
   973   1002   
   974         -			if sp < 1.0 then
   975         -				u:statDelta('stamina', u:phenoTrait('staminaRegen',1) / heatPenalty)
         1003  +			if sp < 1.0 and minetest.get_gametime() - u.cooldownTimes.stamina > 5.0 then
         1004  +				u:statDelta('stamina', (u:phenoTrait('staminaRegen',1) * penaltyFromFatigue) / heatPenalty)
   976   1005   -- 				print('stam', u:effectiveStat 'stamina', u:phenoTrait('staminaRegen',1) / heatPenalty, heatPenalty)
   977   1006   			end
         1007  +
         1008  +			local morale, mp = u:effectiveStat 'morale'
         1009  +			local pr = u:phenoTrait 'psiRegen'
         1010  +			u:statDelta('psi', pr * penaltyFromFatigue * mp)
   978   1011   		end
   979   1012   	end
   980   1013   end)
   981   1014   
   982   1015   local cbit = {
   983   1016   	up   = 0x001;
   984   1017   	down = 0x002;