starlit  Check-in [467a75e0dc]

Overview
Comment:genericize impacts
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 467a75e0dc50798c83a00b86806bd58cba398d555f0b3754c4ed3eee6c73feb7
User & Date: lexi on 2024-05-03 15:31:29
Other Links: manifest | tags
Context
2024-05-03
21:00
add primitive thermal hazard LEDs; further documentation check-in: 511814aace user: lexi tags: trunk
15:31
genericize impacts check-in: 467a75e0dc user: lexi tags: trunk
13:40
ui latency/performance improvements, bugfixes check-in: f1e68eb97e user: lexi tags: trunk
Changes

Modified mods/starlit-eco/plants.lua from [f0b6b474f2] to [798314c789].

122
123
124
125
126
127
128


129
130
131
132

133
134
135
136
137
138
139
	leaf = {
		color = lib.color(.6, .8, .8);
		drop = simpleDrop(2, 'starlit_eco:moondrop_petal');
	};
	berries = {
		desc = "The fruits of the moondrop are not very nutritious, but their peculiar sweet-sour flavor profile makes them one of Farthest Shadow's great delicacies";
		color = lib.color(1,0,.4);


		nourish = 10;
		hydrate = 0.05;
		taste = 1 * 60;
		mass = 1;

	};
	decoration = {
		place_on = 'starlit:greengraze';
		fill_ratio = 0.03;
		biomes = {'starlit:steppe', 'starlit:forest'};
		y_min = 10;
		y_max = 100;







>
>
|
|
|
<
>







122
123
124
125
126
127
128
129
130
131
132
133

134
135
136
137
138
139
140
141
	leaf = {
		color = lib.color(.6, .8, .8);
		drop = simpleDrop(2, 'starlit_eco:moondrop_petal');
	};
	berries = {
		desc = "The fruits of the moondrop are not very nutritious, but their peculiar sweet-sour flavor profile makes them one of Farthest Shadow's great delicacies";
		color = lib.color(1,0,.4);
		mass = 1;
		impact = starlit.type.impact {
			nutrition = 10;
			hydration = 0.05;
			taste = 1*60;

		};
	};
	decoration = {
		place_on = 'starlit:greengraze';
		fill_ratio = 0.03;
		biomes = {'starlit:steppe', 'starlit:forest'};
		y_min = 10;
		y_max = 100;

Modified mods/starlit-eco/trees.lua from [9fe2b3bf5d] to [a9d406a1cb].

58
59
60
61
62
63
64

65
66

67
68
69
70
71
72
73
})


starlit.item.food.link('starlit_eco:lambent_pine_berry', {
	name = 'Lambent Pine Berry';
	desc = 'Though packed with human-compatible nutrients, these berries are almost painfully sour when eaten raw.';
	tex = lib.image('starlit-eco-plant-berry-bunch.png'):shift{hue=180,sat=-30,lum=30}:render();

	nourish = 150;
	taste = -2 * 60;

	mass = 2;
})

starlit.item.seed.link('starlit_eco:lambent_pine_seed', {
	name = 'Lambent Pine Seed';
	tex = lib.image('starlit-eco-plant-seeds.png'):shift{hue=150, sat=-50, lum=80}:render();
	grow = {kind = 'tree', id = 'starlit_eco:lambent_pine'};







>
|
|
>







58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
})


starlit.item.food.link('starlit_eco:lambent_pine_berry', {
	name = 'Lambent Pine Berry';
	desc = 'Though packed with human-compatible nutrients, these berries are almost painfully sour when eaten raw.';
	tex = lib.image('starlit-eco-plant-berry-bunch.png'):shift{hue=180,sat=-30,lum=30}:render();
	impact = starlit.type.impact {
		nutrition = 150;
		taste = -2 * 60;
	};
	mass = 2;
})

starlit.item.seed.link('starlit_eco:lambent_pine_seed', {
	name = 'Lambent Pine Seed';
	tex = lib.image('starlit-eco-plant-seeds.png'):shift{hue=150, sat=-50, lum=80}:render();
	grow = {kind = 'tree', id = 'starlit_eco:lambent_pine'};

Modified mods/starlit/interfaces.lua from [db0300e682] to [6c49562563].

86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
...
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
...
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
	flush()

	for _, i in ipairs(l) do
		local bw = w/max
		if i.cfg then w = w - rh end

		table.insert(bar, {
			kind = 'button', close = i.close;
			color = i.color;
			fg = i.fg;
			label = i.label;
			icon = i.img;
			id = i.id;
			w = bw, h = rh;
		})
		if i.cfg then 
			table.insert(bar, {
				kind = 'button';
				color = i.color;
				fg = i.fg;
				label = "CFG";
				icon = i.img;
				id = i.id .. '_cfg';
				w = rh, h = rh;
			})
		end

		if bar[max] then flush() end
	end
................................................................................
				local statBars = {'nutrition', 'hydration', 'fatigue', 'morale', 'irradiation', 'illness'}
				for idx, id in ipairs(statBars) do
					local s = starlit.world.stats[id]
					local amt, sv = user:effectiveStat(id)
					local min, max = starlit.world.species.statRange(user.persona.species, user.persona.speciesVariant, id)
					local st = string.format('%s / %s', s.desc(amt, true), s.desc(max))
					table.insert(tb, {kind = 'hztl', padding = 0.25;
						{kind = 'label', w=2, h=barh, text = s.name};
						{kind = 'hbar',  w=4, h=barh, fac = sv, text = st, color=s.color};
					})
				end
				local abilities = {
					maneuver = {};
					direct = {};
					passive = {};
................................................................................
				for i, a in pairs(user:species().abilities) do
					local id = 'abl_'..a.id;
					state.abilityMap[id] = a;
					table.insert(abilities[a.powerKind], {
						id = id;
						label = a.name;
						desc = a.desc;
						img = a.img;

						-- HACK
						color = pptrMatch(user.power.maneuver, {ref=a}) and
							{hue = 150, sat = 0, lum = .3} or nil;
					});
				end
				for i, n in ipairs {'maneuver', 'direct', 'passive'} do







|



|









|







 







|







 







|







86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
...
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
...
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
	flush()

	for _, i in ipairs(l) do
		local bw = w/max
		if i.cfg then w = w - rh end

		table.insert(bar, {
			kind = i.img and 'contact' or 'button', close = i.close;
			color = i.color;
			fg = i.fg;
			label = i.label;
			img = i.img;
			id = i.id;
			w = bw, h = rh;
		})
		if i.cfg then 
			table.insert(bar, {
				kind = 'button';
				color = i.color;
				fg = i.fg;
				label = "CFG";
				img = i.img;
				id = i.id .. '_cfg';
				w = rh, h = rh;
			})
		end

		if bar[max] then flush() end
	end
................................................................................
				local statBars = {'nutrition', 'hydration', 'fatigue', 'morale', 'irradiation', 'illness'}
				for idx, id in ipairs(statBars) do
					local s = starlit.world.stats[id]
					local amt, sv = user:effectiveStat(id)
					local min, max = starlit.world.species.statRange(user.persona.species, user.persona.speciesVariant, id)
					local st = string.format('%s / %s', s.desc(amt, true), s.desc(max))
					table.insert(tb, {kind = 'hztl', padding = 0.25;
						{kind = 'label', w=2, h=barh, text = lib.str.capitalize(s.name)};
						{kind = 'hbar',  w=4, h=barh, fac = sv, text = st, color=s.color};
					})
				end
				local abilities = {
					maneuver = {};
					direct = {};
					passive = {};
................................................................................
				for i, a in pairs(user:species().abilities) do
					local id = 'abl_'..a.id;
					state.abilityMap[id] = a;
					table.insert(abilities[a.powerKind], {
						id = id;
						label = a.name;
						desc = a.desc;
-- 						img = a.img;

						-- HACK
						color = pptrMatch(user.power.maneuver, {ref=a}) and
							{hue = 150, sat = 0, lum = .3} or nil;
					});
				end
				for i, n in ipairs {'maneuver', 'direct', 'passive'} do

Modified mods/starlit/stats.lua from [255a217522] to [3922a2ec73].

18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53


























































































































	end
end

local function C(h, s, l)
	return lib.color {hue = h, sat = s or 1, lum = l or .7}
end
starlit.world.stats = {
	psi        = {min = 0, max = 500, base = 0, desc = U('ψ', 10), color = C(320), name = 'Numina'};
	-- 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 = 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
	morale     = {min = 0, max = 10 * 24 * 60, base = true, desc = U('hr', 60, true), color = C(0,0,.8), name = 'Morale', srzType = T.decimal};

	-- morale is measured in minutes. e.g. at base rate morale degrades by
	-- 60 points every hour. morale can last up to 10 earthdays
	irradiation = {min = 0, max = 10, base = 0, desc = U('Gy', 1), color = C(141,1,.5), name = 'Irradiation', srzType = T.decimal};
	-- irrad is measured is milligreys
	-- 1Gy counters natural healing
	-- ~3Gy counters basic nanomedicine
	-- 5Gy causes death within two weeks without nanomedicine
	-- radiation speeds up psi regen
	-- morale drain doubles with each 2Gy
	illness    = {min = 0, max = 1, base = 0, desc = U('%', .01, true), color = C(71,.4,.25), name = 'Illness', srzType = T.factor};
	-- as illness increases, maximum stamina and health gain a corresponding limit
	-- illness is increased by certain conditions, and decreases on its own as your
	-- body heals when those conditions wear off. some drugs can lower accumulated illness
	-- but illness-causing conditions require specific cures
	-- illness also causes thirst and fatigue to increase proportionately
}

































































































































|

|

|

|

|

|

|
>


|






|






>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
	end
end

local function C(h, s, l)
	return lib.color {hue = h, sat = s or 1, lum = l or .7}
end
starlit.world.stats = {
	psi        = {min = 0, max = 500, base = 0, desc = U('ψ', 10), color = C(320), name = 'numina'};
	-- 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', harm=true, srzType = T.decimal};
	-- fatigue is measured in minutes one needs to sleep to cure it
	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
	morale     = {min = 0, max = 10 * 24 * 60, base = true, color = C(0,0,.8), name = 'morale', srzType = T.decimal;
		desc = function(amt, excU) return lib.math.timespec(amt) end};
	-- morale is measured in minutes. e.g. at base rate morale degrades by
	-- 60 points every hour. morale can last up to 10 earthdays
	irradiation = {min = 0, max = 10, base = 0, desc = U('Gy', 1), color = C(141,1,.5), name = 'irradiation', harm=true, srzType = T.decimal};
	-- irrad is measured is milligreys
	-- 1Gy counters natural healing
	-- ~3Gy counters basic nanomedicine
	-- 5Gy causes death within two weeks without nanomedicine
	-- radiation speeds up psi regen
	-- morale drain doubles with each 2Gy
	illness    = {min = 0, max = 1, base = 0, desc = U('%', .01, true), color = C(71,.4,.25), name = 'illness', harm=true, srzType = T.factor};
	-- as illness increases, maximum stamina and health gain a corresponding limit
	-- illness is increased by certain conditions, and decreases on its own as your
	-- body heals when those conditions wear off. some drugs can lower accumulated illness
	-- but illness-causing conditions require specific cures
	-- illness also causes thirst and fatigue to increase proportionately
}

starlit.world.statOrder = {
	'health', 'stamina', 'psi', 'warmth';

	'nutrition', 'hydration', 'irradiation';
	'illness', 'morale', 'fatigue';
}

local impactStruct = G.struct {
	base = G.array(8, G.struct {id = T.str, val = T.decimal});
-- 	alt = G.array(8, )
}

starlit.type.impact = lib.class {
	__name = 'starlit.type.impact';
	construct = function(p)
		-- deltaPack {
		-- 	nutrition = 5.0;
		-- 	hydration = -1;
		--		{"Taste", 'good'; {'morale', 1}};
		--		{"Narcotic", 'mixed'; {'morale', 10};
		--                          {'addiction', function(user) ... end}};
		-- 	{"Magic", 'info'; 'casts an magic spell', function(user) ... end};
		-- }
		return p
	end;
-- 	__tostring = function(me)
-- 	end;
	__index = {
		pushProps = function(me, p)
			for i,k in pairs(starlit.world.statOrder) do
				if me[k] then
					local s = starlit.world.stats[k]

					local v = me[k]
					local good = v > 0
					if s.harm then good = not good end
					local d = s.desc(v)
					if v > 0 then d = '+' .. d end

					table.insert(p, {
						title = lib.str.capitalize(s.name);
						affinity = good and 'good' or 'bad';
						desc = d;
					})
				end
			end
			for i,v in ipairs(me) do
				local label, aff = v[1], v[2]
				local effectStrs = {}
				for i = 3, #v do
					local t = v[i]
					local str
					if type(t) == 'table' then
						local id, amt = t[1], t[2]
						local s = starlit.world.stats[id]
						local desc = s.desc(amt)
						if amt > 0 then desc = '+' .. desc end
						str = string.format('%s to %s', desc, s.name)
					-- elseif type(v[i]) == 'function' then
					elseif type(t) == 'string' then
						str = t
					end
					if str then table.insert(effectStrs, str) end
				end

				table.insert(p, {
					title = lib.str.capitalize(label);
					affinity = aff;
					desc = next(effectStrs) and table.concat(effectStrs, ', ') or nil;
				})
			end
		end;
		propTable = function(me)
			local t = {}
			me:pushProps(t)
			return t
		end;
		addToItem = function(me, stack, key)
			key = key or 'starlit:impact'
			local m = stack:get_meta()
			local tbl = {base={}}
			for k,v in pairs(me) do
				if type(k) == 'string' then
					tbl.base[k] = v
				end
			end
			local armored = lib.str.meta_armor(impactStruct.enc(tbl))
			m:set_string(key, armored)
			return stack
		end;
		effective = function(me, stack, key)
			key = key or 'starlit:impact'
			local c = starlit.type.impact.clone(me)

			local m = stack:get_meta()
			if m:contains(key) then
				local tbl = impactStruct.dec(lib.str.meta_dearmor(m:get_string(key)))
				for k,v in pairs(tbl.base) do c[k] = v end
			end

			return c
		end;
		apply = function(me, user)
			for k,v in pairs(me) do
				if starlit.world.stats[k] then
					user:statDelta(k, v)
				elseif type(k) == 'number' then
					for i = 3, #v do
						local t = v[i]
						if type(t) == 'table' then
							local id, amt = t[1], t[2]
							user:statDelta(id, amt)
						elseif type(t) == 'function' then
							t(user)
						end
					end
				end
			end
		end;
	};
}

Modified mods/vtlib/math.lua from [6a568676fe] to [54a7601a0f].

134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
}
-- function fn.vlerp

function fn.timespec(n)
	if n == 0 then return '0s' end
	if n < 0 then return '-' .. fn.timespec(n*-1) end

	local sec = n % 60
	local hr = math.floor(n / 60)
	local spec = {}

	if sec ~= 0 then table.insert(spec, string.format("%ss",  sec)) end
	if hr  ~= 0 then table.insert(spec, string.format("%shr", hr))  end
	return table.concat(spec, ' ')
end
return fn







|



|
|



134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
}
-- function fn.vlerp

function fn.timespec(n)
	if n == 0 then return '0s' end
	if n < 0 then return '-' .. fn.timespec(n*-1) end

	local sec = math.floor(n % 60)
	local hr = math.floor(n / 60)
	local spec = {}

	if hr  ~= 0 then table.insert(spec, string.format("%shr", hr))  end
	if sec ~= 0 then table.insert(spec, string.format("%ss",  sec)) end
	return table.concat(spec, ' ')
end
return fn