Differences From
Artifact [255a217522]:
18 18 end
19 19 end
20 20
21 21 local function C(h, s, l)
22 22 return lib.color {hue = h, sat = s or 1, lum = l or .7}
23 23 end
24 24 starlit.world.stats = {
25 - psi = {min = 0, max = 500, base = 0, desc = U('ψ', 10), color = C(320), name = 'Numina'};
25 + psi = {min = 0, max = 500, base = 0, desc = U('ψ', 10), color = C(320), name = 'numina'};
26 26 -- numina is measured in daψ
27 - warmth = {min = -1000, max = 1000, base = 0, desc = U('°C', 10, true), color = C(5), name = 'Warmth'};
27 + warmth = {min = -1000, max = 1000, base = 0, desc = U('°C', 10, true), color = C(5), name = 'warmth'};
28 28 -- warmth in measured in d°C
29 - fatigue = {min = 0, max = 76 * 60, base = 0, desc = U('hr', 60, true), color = C(288,.3,.5), name = 'Fatigue', srzType = T.decimal};
29 + 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};
30 30 -- fatigue is measured in minutes one needs to sleep to cure it
31 - stamina = {min = 0, max = 10 * 20, base = true, desc = U('m', 100), color = C(88), name = 'Stamina'};
31 + stamina = {min = 0, max = 10 * 20, base = true, desc = U('m', 100), color = C(88), name = 'stamina'};
32 32 -- stamina is measured in how many 10th-nodes (== cm) one can sprint
33 - nutrition = {min = 0, max = 8000, base = 0, desc = U('kCal', 1, true), color = C(43,.5,.4), name = 'Nutrition', srzType = T.decimal};
33 + nutrition = {min = 0, max = 8000, base = 0, desc = U('kCal', 1, true), color = C(43,.5,.4), name = 'nutrition', srzType = T.decimal};
34 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};
35 + hydration = {min = 0, max = 4, base = 0, desc = U('L', 1), color = C(217, .25,.4), name = 'hydration', srzType = T.decimal};
36 36 -- thirst is measured in L of H²O required to cure it
37 - morale = {min = 0, max = 10 * 24 * 60, base = true, desc = U('hr', 60, true), color = C(0,0,.8), name = 'Morale', srzType = T.decimal};
37 + morale = {min = 0, max = 10 * 24 * 60, base = true, color = C(0,0,.8), name = 'morale', srzType = T.decimal;
38 + desc = function(amt, excU) return lib.math.timespec(amt) end};
38 39 -- morale is measured in minutes. e.g. at base rate morale degrades by
39 40 -- 60 points every hour. morale can last up to 10 earthdays
40 - irradiation = {min = 0, max = 10, base = 0, desc = U('Gy', 1), color = C(141,1,.5), name = 'Irradiation', srzType = T.decimal};
41 + irradiation = {min = 0, max = 10, base = 0, desc = U('Gy', 1), color = C(141,1,.5), name = 'irradiation', harm=true, srzType = T.decimal};
41 42 -- irrad is measured is milligreys
42 43 -- 1Gy counters natural healing
43 44 -- ~3Gy counters basic nanomedicine
44 45 -- 5Gy causes death within two weeks without nanomedicine
45 46 -- radiation speeds up psi regen
46 47 -- morale drain doubles with each 2Gy
47 - illness = {min = 0, max = 1, base = 0, desc = U('%', .01, true), color = C(71,.4,.25), name = 'Illness', srzType = T.factor};
48 + illness = {min = 0, max = 1, base = 0, desc = U('%', .01, true), color = C(71,.4,.25), name = 'illness', harm=true, srzType = T.factor};
48 49 -- as illness increases, maximum stamina and health gain a corresponding limit
49 50 -- illness is increased by certain conditions, and decreases on its own as your
50 51 -- body heals when those conditions wear off. some drugs can lower accumulated illness
51 52 -- but illness-causing conditions require specific cures
52 53 -- illness also causes thirst and fatigue to increase proportionately
53 54 }
55 +
56 +starlit.world.statOrder = {
57 + 'health', 'stamina', 'psi', 'warmth';
58 +
59 + 'nutrition', 'hydration', 'irradiation';
60 + 'illness', 'morale', 'fatigue';
61 +}
62 +
63 +local impactStruct = G.struct {
64 + base = G.array(8, G.struct {id = T.str, val = T.decimal});
65 +-- alt = G.array(8, )
66 +}
67 +
68 +starlit.type.impact = lib.class {
69 + __name = 'starlit.type.impact';
70 + construct = function(p)
71 + -- deltaPack {
72 + -- nutrition = 5.0;
73 + -- hydration = -1;
74 + -- {"Taste", 'good'; {'morale', 1}};
75 + -- {"Narcotic", 'mixed'; {'morale', 10};
76 + -- {'addiction', function(user) ... end}};
77 + -- {"Magic", 'info'; 'casts an magic spell', function(user) ... end};
78 + -- }
79 + return p
80 + end;
81 +-- __tostring = function(me)
82 +-- end;
83 + __index = {
84 + pushProps = function(me, p)
85 + for i,k in pairs(starlit.world.statOrder) do
86 + if me[k] then
87 + local s = starlit.world.stats[k]
88 +
89 + local v = me[k]
90 + local good = v > 0
91 + if s.harm then good = not good end
92 + local d = s.desc(v)
93 + if v > 0 then d = '+' .. d end
94 +
95 + table.insert(p, {
96 + title = lib.str.capitalize(s.name);
97 + affinity = good and 'good' or 'bad';
98 + desc = d;
99 + })
100 + end
101 + end
102 + for i,v in ipairs(me) do
103 + local label, aff = v[1], v[2]
104 + local effectStrs = {}
105 + for i = 3, #v do
106 + local t = v[i]
107 + local str
108 + if type(t) == 'table' then
109 + local id, amt = t[1], t[2]
110 + local s = starlit.world.stats[id]
111 + local desc = s.desc(amt)
112 + if amt > 0 then desc = '+' .. desc end
113 + str = string.format('%s to %s', desc, s.name)
114 + -- elseif type(v[i]) == 'function' then
115 + elseif type(t) == 'string' then
116 + str = t
117 + end
118 + if str then table.insert(effectStrs, str) end
119 + end
120 +
121 + table.insert(p, {
122 + title = lib.str.capitalize(label);
123 + affinity = aff;
124 + desc = next(effectStrs) and table.concat(effectStrs, ', ') or nil;
125 + })
126 + end
127 + end;
128 + propTable = function(me)
129 + local t = {}
130 + me:pushProps(t)
131 + return t
132 + end;
133 + addToItem = function(me, stack, key)
134 + key = key or 'starlit:impact'
135 + local m = stack:get_meta()
136 + local tbl = {base={}}
137 + for k,v in pairs(me) do
138 + if type(k) == 'string' then
139 + tbl.base[k] = v
140 + end
141 + end
142 + local armored = lib.str.meta_armor(impactStruct.enc(tbl))
143 + m:set_string(key, armored)
144 + return stack
145 + end;
146 + effective = function(me, stack, key)
147 + key = key or 'starlit:impact'
148 + local c = starlit.type.impact.clone(me)
149 +
150 + local m = stack:get_meta()
151 + if m:contains(key) then
152 + local tbl = impactStruct.dec(lib.str.meta_dearmor(m:get_string(key)))
153 + for k,v in pairs(tbl.base) do c[k] = v end
154 + end
155 +
156 + return c
157 + end;
158 + apply = function(me, user)
159 + for k,v in pairs(me) do
160 + if starlit.world.stats[k] then
161 + user:statDelta(k, v)
162 + elseif type(k) == 'number' then
163 + for i = 3, #v do
164 + local t = v[i]
165 + if type(t) == 'table' then
166 + local id, amt = t[1], t[2]
167 + user:statDelta(id, amt)
168 + elseif type(t) == 'function' then
169 + t(user)
170 + end
171 + end
172 + end
173 + end
174 + end;
175 + };
176 +}