Comment: | somewhat improve buttons |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | trunk |
Files: | files | file ages | folders |
SHA3-256: |
d2ab51532e382991cb3c83f280782dbf |
User & Date: | lexi on 2025-03-25 17:47:31 |
Other Links: | manifest | tags |
2025-03-25
| ||
17:47 | somewhat improve buttons Leaf check-in: d2ab51532e user: lexi tags: trunk | |
2025-01-19
| ||
19:18 | we have always been at war with east minecraft check-in: 4732f8d454 user: lexi tags: trunk | |
Modified asset.list from [33338e0378] to [7b9ff32a24].
228 229 230 231 232 233 234 235 236 237 238 239 240 241 |
mods/starlit/textures/starlit-ui-alert.png mods/starlit/textures/starlit-ui-bar.png mods/starlit/textures/starlit-ui-bg-digital.png mods/starlit/textures/starlit-ui-bg-panel.png mods/starlit/textures/starlit-ui-button-hw-hover.png mods/starlit/textures/starlit-ui-button-hw-press.png mods/starlit/textures/starlit-ui-button-hw.png mods/starlit/textures/starlit-ui-button-sw-hover.png mods/starlit/textures/starlit-ui-button-sw-press.png mods/starlit/textures/starlit-ui-button-sw.png mods/starlit/textures/starlit-ui-crosshair-nano.png mods/starlit/textures/starlit-ui-crosshair-psi.png mods/starlit/textures/starlit-ui-crosshair-weapon.png mods/starlit/textures/starlit-ui-crosshair.png |
> |
228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 |
mods/starlit/textures/starlit-ui-alert.png
mods/starlit/textures/starlit-ui-bar.png
mods/starlit/textures/starlit-ui-bg-digital.png
mods/starlit/textures/starlit-ui-bg-panel.png
mods/starlit/textures/starlit-ui-button-hw-hover.png
mods/starlit/textures/starlit-ui-button-hw-press.png
mods/starlit/textures/starlit-ui-button-hw.png
mods/starlit/textures/starlit-ui-button-sw-active.png
mods/starlit/textures/starlit-ui-button-sw-hover.png
mods/starlit/textures/starlit-ui-button-sw-press.png
mods/starlit/textures/starlit-ui-button-sw.png
mods/starlit/textures/starlit-ui-crosshair-nano.png
mods/starlit/textures/starlit-ui-crosshair-psi.png
mods/starlit/textures/starlit-ui-crosshair-weapon.png
mods/starlit/textures/starlit-ui-crosshair.png
|
Added mods/starlit-psionics/init.lua version [539da653d2].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
local lib = starlit.mod.lib starlit.interface.install(starlit.type.ui { id = 'starlit_psionics:cultivate'; pages = { index = { setupState = function(state, user) end; handle = function(state, user, act) end; }; }; }) starlit.world.psi.meld { cultivate = { name = 'Cultivate'; desc = 'Invest numina to develop new powers'; powerKind = 'direct'; cost = {}; -- cultivate costs are applied in the interface -- all psions start with this power learnCost = 0, rarity = 0; ui = 'starlit_psionics:cultivate'; }; } starlit.world.psi.meld { cultivate = { name = 'Mend'; desc = 'Burn numina to rapidly heal yourself'; powerKind = 'passive'; cost = { stat = {numina = 10} }; -- ψ/s learnCost = 1000, rarity = 5; bgProc = function(ctx) end; }; } |
Added mods/starlit-psionics/mod.conf version [e85c7f4195].
> > > > |
1 2 3 4 |
name = starlit_psionics title = starlit psionics description = defines the base psi powers depends = starlit |
Modified mods/starlit-scenario/init.lua from [8a376bbedc] to [339ae3b1f1].
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
local scenario = starlit.world.scenario local log = starlit.logger 'scenario' local function makeChip(label, schem, sw) local E = starlit.mod.electronics local files = {} local sz = 0 for _, e in ipairs(schem) do local p = E.sw.findSchematicFor(e[1]) if p then local file = { kind = 'sw', name = '', drm = e[2]; body = {pgmId = p, conf = {}}; } table.insert(files, file) sz = sz + E.chip.fileSize(file) end end for _, e in ipairs(sw) do local file = { kind = 'sw', name = '', drm = e[2]; body = {pgmId = e[1], conf = {}}; } table.insert(files, file) sz = sz + E.chip.fileSize(file) end local chip = ItemStack(assert(E.chip.findBest(function(c) return c.flash >= sz, c.ram + c.clockRate end))) local r = E.chip.read(chip) r.label = label r.files = files E.chip.write(chip, r) |
> > > > > > > > < < < < < < < < |
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
local scenario = starlit.world.scenario local log = starlit.logger 'scenario' local function makeChip(label, schem, sw) local E = starlit.mod.electronics local files = {} local sz = 0 for _, e in ipairs(sw) do local file = { kind = 'sw', name = '', drm = e[2]; body = {pgmId = e[1], conf = {}}; } table.insert(files, file) sz = sz + E.chip.fileSize(file) end for _, e in ipairs(schem) do local p = E.sw.findSchematicFor(e[1]) if p then local file = { kind = 'sw', name = '', drm = e[2]; body = {pgmId = p, conf = {}}; } table.insert(files, file) sz = sz + E.chip.fileSize(file) end end local chip = ItemStack(assert(E.chip.findBest(function(c) return c.flash >= sz, c.ram + c.clockRate end))) local r = E.chip.read(chip) r.label = label r.files = files E.chip.write(chip, r) |
Modified mods/starlit-suit/init.lua from [078f484c1f] to [ef81e2c820].
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
tex = { plate = { id = 'starlit-suit-survival-plate'; tint = lib.color {hue = 210, sat = .5, lum = .5}; }; lining = { id = 'starlit-suit-survival-lining'; tint = lib.color {hue = 180, sat = .2, lum = .7}; }; }; tints = {'suit_plate', 'suit_lining'}; temp = { desc = facDesc('survival','cc'); maxHeat = 0.7; -- can produce a half-degree Δ per second maxCool = 0.5; |
| |
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
tex = { plate = { id = 'starlit-suit-survival-plate'; tint = lib.color {hue = 210, sat = .5, lum = .5}; }; lining = { id = 'starlit-suit-survival-lining'; tint = lib.color {hue = 260, sat = .3, lum = .3}; }; }; tints = {'suit_plate', 'suit_lining'}; temp = { desc = facDesc('survival','cc'); maxHeat = 0.7; -- can produce a half-degree Δ per second maxCool = 0.5; |
Modified mods/starlit/food.lua from [09c96accb0] to [ee714c2ec0].
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
props = props;
color = f.color;
};
end
F.foreach('starlit:gen-food', {}, function(id, f)
core.register_item(id, {
type = f.itemType or 'none';
inventory_image = f.tex;
short_description = f.name;
description = foodTip(nil, f);
on_use = function(st, luser)
local user = starlit.activeUsers[luser:get_player_name()]
st:take_item(1)
local imp = F.impact(st,f)
|
| |
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
props = props;
color = f.color;
};
end
F.foreach('starlit:gen-food', {}, function(id, f)
core.register_item(id, {
type = f.itemType or 'craft';
inventory_image = f.tex;
short_description = f.name;
description = foodTip(nil, f);
on_use = function(st, luser)
local user = starlit.activeUsers[luser:get_player_name()]
st:take_item(1)
local imp = F.impact(st,f)
|
Modified mods/starlit/init.lua from [ae90c8058c] to [ae88cd06e3].
92
93
94
95
96
97
98
99
100
101
102
103
104
105
...
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
|
trees = lib.registry.mk 'starlit:trees'; biomes = lib.registry.mk 'starlit:biome'; }; climate = { weather = lib.registry.mk 'starlit:weather'; weatherMap = {} }; scenario = {}; planet = { gravity = 7.44; orbit = 189; -- 1 year is 189 days revolve = 20; -- 1 day is 20 irl minutes }; fact = lib.registry.mk 'starlit:fact'; ................................................................................ -- of the default hp_max. since we crank up -- hp by a factor of 50~40, damage should be -- cranked by similarly end return delta end, true) function core.handle_node_drops(pos, drops, digger) local function jitter(pos) local function r(x) return x+math.random(-0.01, 0.01) end return vector.new( r(pos.x), r(pos.y), r(pos.z) ) end for i, it in ipairs(drops) do if type(it) == 'string' then it = ItemStack(it) end if not it:is_empty() then local ent = core.add_item(jitter(pos), it) if ent ~= nil then -- avoid crash when dropping unknown item local dp = vector.new(0,0,0) if digger then dp = digger:get_pos() end local delta = dp - ent:get_pos() ent:add_velocity(vector.new(delta.x,0,delta.z)); end end end end -- TODO timer iterates live UI |
>
<
|
>
>
>
>
>
>
>
>
>
>
|
|
|
|
|
|
|
|
|
>
<
|
|
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
...
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
|
trees = lib.registry.mk 'starlit:trees'; biomes = lib.registry.mk 'starlit:biome'; }; climate = { weather = lib.registry.mk 'starlit:weather'; weatherMap = {} }; psi = lib.registry.mk 'starlit:psi'; scenario = {}; planet = { gravity = 7.44; orbit = 189; -- 1 year is 189 days revolve = 20; -- 1 day is 20 irl minutes }; fact = lib.registry.mk 'starlit:fact'; ................................................................................ -- of the default hp_max. since we crank up -- hp by a factor of 50~40, damage should be -- cranked by similarly end return delta end, true) do local function jitter(pos) local function r(x) return x+math.random(-0.01, 0.01) end return vector.new( r(pos.x), r(pos.y), r(pos.z) ) end function starlit.throwItem(luser, stack) local ent = core.add_item(jitter(luser:get_pos()), stack) a = luser:get_look_dir() a = a * math.random(1, 10); a.y = a.y + 0.5 ent:add_velocity(a) end function core.handle_node_drops(pos, drops, digger) for i, it in ipairs(drops) do if type(it) == 'string' then it = ItemStack(it) end if not it:is_empty() then local ent = core.add_item(jitter(pos), it) if ent ~= nil then -- avoid crash when dropping unknown item local dp = vector.new(0,0,0) if digger then dp = digger:get_pos() end local delta = dp - ent:get_pos() ent:add_velocity(vector.new(delta.x,0,delta.z)); end end end end end -- TODO timer iterates live UI |
Modified mods/starlit/interfaces.lua from [7199aa7738] to [51ed588904].
1 2 3 4 5 6 7 8 9 10 11 12 .. 37 38 39 40 41 42 43 44 45 46 47 48 49 50 ... 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 |
local lib = starlit.mod.lib function starlit.ui.setupForUser(user) local function cmode(mode) if user.actMode == mode then return {hue = 150, sat = 0, lum = .3} end end user.entity:set_inventory_formspec(starlit.ui.build { kind = 'vert', mode = 'sw'; padding = .5, spacing = 0.1; {kind = 'hztl'; {kind = 'contact', w=1.5,h=1.5, id = 'mode_nano', img='starlit-ui-icon-nano.png', close=true, color = cmode'nano'}; ................................................................................ if user.actMode == mode then user:actModeSet 'off' else user:actModeSet(mode) end end local modes = { nano = true, psi = false, weapon = true } for e,s in pairs(modes) do if fields['mode_' .. e] then if s and (user:naked() or user:getSuit():powerState() == 'off') then user:suitSound 'starlit-error' else setSuitMode(e) ................................................................................ local suit = user:getSuit() local suitDef = suit:def() local chipW, chipH = listWrap(suitDef.slots.chips, 5) local batW, batH = listWrap(suitDef.slots.batteries, 5) local canW, canH = listWrap(suitDef.slots.canisters, 5) local suitMode = suit:powerState() local function modeColor(mode) if mode == suitMode then return {hue = 180, sat = 0, lum = .5} end end return starlit.ui.build { kind = 'vert', mode = 'sw'; padding = 0.5, spacing = 0.1; {kind = 'hztl', {kind = 'img', desc='Batteries', img = 'starlit-item-battery.png', w=1,h=1}; {kind = 'list', target = 'current_player', inv = 'starlit_suit_bat', |
| > > > > > > | |
1 2 3 4 5 6 7 8 9 10 11 12 .. 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 ... 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 |
local lib = starlit.mod.lib function starlit.ui.setupForUser(user) local function cmode(mode) if user.actMode == mode then return {hue = 290, sat = 0, lum = .1} end end user.entity:set_inventory_formspec(starlit.ui.build { kind = 'vert', mode = 'sw'; padding = .5, spacing = 0.1; {kind = 'hztl'; {kind = 'contact', w=1.5,h=1.5, id = 'mode_nano', img='starlit-ui-icon-nano.png', close=true, color = cmode'nano'}; ................................................................................ if user.actMode == mode then user:actModeSet 'off' else user:actModeSet(mode) end end -- disable suit modes if the suit is off or the user is naked local modes = { nano = true, psi = false, weapon = true } for e,s in pairs(modes) do if fields['mode_' .. e] then if s and (user:naked() or user:getSuit():powerState() == 'off') then user:suitSound 'starlit-error' else setSuitMode(e) ................................................................................ local suit = user:getSuit() local suitDef = suit:def() local chipW, chipH = listWrap(suitDef.slots.chips, 5) local batW, batH = listWrap(suitDef.slots.batteries, 5) local canW, canH = listWrap(suitDef.slots.canisters, 5) local suitMode = suit:powerState() local function modeColor(mode) local c = { off = {hue = 0, sat = 0, lum = 0}; powerSave = {hue = 60, sat = 0, lum = 0}; on = {hue = 100, sat = 0, lum = 0}; } if mode == suitMode then return c[mode] end end return starlit.ui.build { kind = 'vert', mode = 'sw'; padding = 0.5, spacing = 0.1; {kind = 'hztl', {kind = 'img', desc='Batteries', img = 'starlit-item-battery.png', w=1,h=1}; {kind = 'list', target = 'current_player', inv = 'starlit_suit_bat', |
Added mods/starlit/psi.lua version [8b15304149].
> |
1 |
local lib = starlit.mod.lib
|
Modified mods/starlit/suit.lua from [d40c92ebbb] to [0ecf5e03a5].
82 83 84 85 86 87 88 89 90 91 92 93 94 95 ... 284 285 286 287 288 289 290 291 292 293 294 295 296 297 ... 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 |
user:suitSound('starlit-insert-snap') elseif list == 'starlit_suit_chips' then --user:suitSound('starlit-suit-chip-out') elseif list == 'starlit_suit_canisters' then user:suitSound('starlit-insert-snap') end end end; def = function(self) return self.item:get_definition()._starlit.suit end; --[[ pullCanisters = function(self, inv) starlit.item.container.dropPrefix(inv, 'starlit_canister') ................................................................................ }; suit = def; }; }); end) local slotProps = { starlit_cfg = { itemClass = 'inv'; }; starlit_suit_bat = { suitSlot = true; powerLock = true; itemClass = 'dynamo'; ................................................................................ return true end) core.register_on_player_inventory_action(function(luser, act, inv, p) local user = starlit.activeUsers[luser:get_player_name()] local function slotChange(slot,a,item) local s = slotProps[slot] if slot == 'starlit_suit' then user:updateSuit() if user:naked() then starlit.type.suit.purgeInventories(user.entity) user.power.nano = {} end elseif s and s.suitSlot then local s = user:getSuit() s:onItemMove(user, slot, a, item) s:onReconfigure(user.entity:get_inventory()) user:setSuit(s) else return end user:updateHUD() end if act == 'put' or act == 'take' then local item = p.stack slotChange(p.listname, act, item) |
> > > > > | | | > |
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 ... 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 ... 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 |
user:suitSound('starlit-insert-snap') elseif list == 'starlit_suit_chips' then --user:suitSound('starlit-suit-chip-out') elseif list == 'starlit_suit_canisters' then user:suitSound('starlit-insert-snap') end end return true -- move allowed end; def = function(self) return self.item:get_definition()._starlit.suit end; --[[ pullCanisters = function(self, inv) starlit.item.container.dropPrefix(inv, 'starlit_canister') ................................................................................ }; suit = def; }; }); end) local slotProps = { -- main = { -- free = true; -- }; starlit_cfg = { itemClass = 'inv'; }; starlit_suit_bat = { suitSlot = true; powerLock = true; itemClass = 'dynamo'; ................................................................................ return true end) core.register_on_player_inventory_action(function(luser, act, inv, p) local user = starlit.activeUsers[luser:get_player_name()] local function slotChange(slot,a,item) local s = slotProps[slot] local allow = true if slot == 'starlit_suit' then user:updateSuit() if user:naked() then starlit.type.suit.purgeInventories(user.entity) user.power.nano = {} end elseif s and s.suitSlot then local s = user:getSuit() if s:onItemMove(user, slot, a, item) then s:onReconfigure(user.entity:get_inventory()) user:setSuit(s) else return end else return end user:updateHUD() end if act == 'put' or act == 'take' then local item = p.stack slotChange(p.listname, act, item) |
Modified mods/starlit/user.lua from [1a0e392600] to [8da9d84fa1].
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
...
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
|
return val, (val - min) / d end; --------------- -- phenotype -- --------------- lookupSpecies = function(self) return starlit.world.species.lookup(self.persona.species, self.persona.speciesVariant) end; phenoTrait = function(self, trait, dflt) -- local s,v = self:lookupSpecies() -- return v.traits[trait] or s.traits[trait] or 0 return self.pheno:trait(trait, dflt) end; damageModifier = function(self, kind, amt) ................................................................................ local luser = self.entity local bar = {def = def} local img = lib.image 'starlit-ui-bar.png' local colorized = img if type(def.color) ~= 'function' then colorized = colorized:shift(def.color) end bar.id = luser:hud_add { type = 'statbar'; position = def.pos; offset = def.ofs; name = def.name; text = colorized:render(); text2 = img:tint{hue=0, sat=-1, lum = -0.5}:fade(0.5):render(); number = def.size; item = def.size; direction = def.dir; alignment = def.align; size = {x=4,y=24}; } bar.update = function() local sv, sf = def.stat(self, bar, def) luser:hud_change(bar.id, 'number', def.size * sf) if type(def.color) == 'function' then local clr = def.color(sv, luser, sv, sf) luser:hud_change(bar.id, 'text', img:tint(clr):render()) end end return bar, {x=3 * def.size, y=16} -- x*2??? what end; createHUD = function(self) local function basicStat(statName) return function(user, bar) return self:effectiveStat(statName) end end |
|
>
>
>
>
>
>
>
>
>
<
|
|
|
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
...
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
|
return val, (val - min) / d end; --------------- -- phenotype -- --------------- lookupSpecies = function(self) return starlit.world.species.lookup( self.persona.species, self.persona.speciesVariant) end; phenoTrait = function(self, trait, dflt) -- local s,v = self:lookupSpecies() -- return v.traits[trait] or s.traits[trait] or 0 return self.pheno:trait(trait, dflt) end; damageModifier = function(self, kind, amt) ................................................................................ local luser = self.entity local bar = {def = def} local img = lib.image 'starlit-ui-bar.png' local colorized = img if type(def.color) ~= 'function' then colorized = colorized:shift(def.color) end local function adjustNumber(n) -- produce a value that is realized as whole number -- of images, rather than half-images return math.floor(n/2)*2; end bar.id = luser:hud_add { type = 'statbar'; position = def.pos; offset = def.ofs; name = def.name; number = adjustNumber(def.size); text = colorized:render(); text2 = img:tint{hue=0, sat=-1, lum = -0.5}:fade(0.5):render(); item = def.size; direction = def.dir; alignment = def.align; size = {x=4,y=24}; } bar.update = function() local sv, sf = def.stat(self, bar, def) luser:hud_change(bar.id, 'number', adjustNumber(def.size * sf)) if type(def.color) == 'function' then local clr = def.color(sv, luser, sv, sf) luser:hud_change(bar.id, 'text', img:tint(clr):render()) end end return bar, {x=3 * def.size, y=16} -- x*3??? what end; createHUD = function(self) local function basicStat(statName) return function(user, bar) return self:effectiveStat(statName) end end |
Modified starlit.ct from [f4a136801c] to [259abbd299].
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 |
** naturally diminishes, but very slowly
* [*illness]: not everything on Farthest Shadow's ecosystem is, shall we say, biocompatible. measured in percent
** affects [*morale]: the higher your illness, the more quickly you bleed morale
your primary stats are shown on your HUD. ancillary stats can be viewed in the "body" panel.
### psionics
there are four types of psionic abilities: Manual, Maneuver, Ritual, and Contextual.
you can assign two Manual abilities at any given time and access them with the mouse buttons in Psionics mode.
you can select a Psi Maneuver in the Psionics panel and activate it by holding [*Aux1].
a Ritual is triggered directly from the psionics menu. as the name implies, these are complex, powerful abilities that require large amounts of Psi and time to meditate before they trigger, and any interruption will cancel the ability (though it will not restore any lost psi). the most famous Ritual is of course Conjoin Metric, which Starlit astropaths use in conjunction with powerful amplifiers to perform long-distance FTL jumps -- but without centuries of dedication to the art, the best you can hope for if you manage to learn this storied power is to move yourself a few kilometers.
a Contextual ability is triggered in a specific situation, usually by interacting with a certain kind of object. Contextual abilities often require specialized equipment, to the point that many Starlit practitioners maintain their own Psionics Lab.
## legal
starlit source code (*.lua, *.conf, *.txt, *.csd files) is released under the GNU AGPLv3.
assets (images, sounds, models, and anything else in the repo that doesn't qualify as source code) are released under the CC-BY-NC-SA 3.0 license.
sound files with the prefix `default-` are taken from Luanti Game, whose assets are available under the CC-BY-SA 3.0 license.
|
> > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
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 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 |
** naturally diminishes, but very slowly * [*illness]: not everything on Farthest Shadow's ecosystem is, shall we say, biocompatible. measured in percent ** affects [*morale]: the higher your illness, the more quickly you bleed morale your primary stats are shown on your HUD. ancillary stats can be viewed in the "body" panel. ### psionics psionics draws from your reserve of numina to allow your spirit to directly affect the material world, or other spirits. numina accretes slowly, though high morale will speed this up. there are four types of psionic abilities: Manual, Maneuver, Ritual, and Contextual. you can assign two Manual abilities at any given time and access them with the mouse buttons in Psionics mode. you can select a Psi Maneuver in the Psionics panel and activate it by holding [*Aux1]. a Ritual is triggered directly from the psionics menu. as the name implies, these are complex, powerful abilities that require large amounts of Psi and time to meditate before they trigger, and any interruption will cancel the ability (though it will not restore any lost psi). the most famous Ritual is of course Rift, which Starlit astropaths use in conjunction with powerful amplifiers to perform long-distance FTL jumps -- but without centuries of dedication to the art, the best you can hope for if you manage to learn this storied power is to move yourself a few kilometers. a Contextual ability is triggered in a specific situation, usually by interacting with a certain kind of object. Contextual abilities often require specialized equipment, to the point that many Starlit practitioners maintain their own Psionics Lab. at the beginning of the game, you start with the power "Cultivate", which is used to develop your psionic talents. to gain new psionic abilities, invest numina by triggering the Cultivate power. gaining new powers requires much more numina than using them, so you'll want to be careful about how much power you expend. once you have invested enough numina in your psionic advancement, you will be given a list of up to three new powers to choose from. the specific powers are partially randomized, though some have additional prerequisites. the environment in which you meditate can affect which powers are offered; some powers can only be achieved in certain biomes or circumstances. make sure you have a secure location to meditate in, however, as any interruption will disrupt your meditation, wasting the invested numina. you can also invest numina to strengthen a power you already possess. this can be done using the powers "Fortify" and "Advance". Fortify produces extremely strong temporary power boosts without affecting the base power cost; these wear off as you use the Fortified power. Advance permanently enhances the power in small increments, but the base power cost increases for every Advancement. note, however, that the further you Advance a power, the more efficient its use of numina becomes. there is a maximum amount of numina that a spirit can hold onto. this is determined by your species and sex, with females generally having larger numina pools. if this becomes limiting, it is possible to stockpile numina through the use of numinium crystals, a sort of psychic battery. these are not cheap to build, however, and doing so requires a psi-forge. a manual psionic power belongs to one of three categories: * [*Currents]: a [*Current] is a modifier that can be toggled on or off. quale determine the effect produced by a Carrier; for instance, you can produce a healing shockwave centered on your character by activating [*Purify] and firing [*Pulse]. multiple currents can be active at a time, though this consumes proportionally further power. * [*Carriers]: a [*Carrier] determines how the selected [*Currents] are expressed into the world, both in terms of targeting and efficiency. Advancing a Carrier improves its efficiency, and where relevant, range. * [*]: a [*] power can be expressed in only one way; its Carrier is indivisble from its Current. psionic powers you can learn include, but are not limited to: #### Carriers * [*Infuse]: applies Current directly to the user. this is the most efficient of all effectors. * [*Reach]: affect a single target on an ongoing basis. less efficient with distance, but almost as efficient as [*Infuse] when the target is right beside you. * [*Pulse]: release a wave of psionic force, applying Current to everything in range except yourself. this is the least efficient power. * [*Lance]: produces a narrow beam that delivers the full force of its Current to the first thing it hits. Lances are chargeable; you can invest an arbitrary amount of numina into the chosen Currents by holding the bound key for a time before releasing it. Lances travel further the stronger their charge. * [*Torrent]: produces a wide beam that weakens the further it travels, but affects all in its path * [*Tide]: like [*Torrent], but even less efficient; the width of the beam expands as it travels, making it useful for targeting groups of enemies. * [*Vortex]: like Lance, but explodes when it hits its target, affecting everything in range of the blast. * [*Pierce]: fire off homing orbs that track nearby targets and applies Current on impact. the more Pierce is charged, the more orbs will be launched, and the greater their efficiency will be. * [*Arc]: affects the nearest target, then jumps to the target nearest them, and so on. the more powerful Arc becomes, the greater the jump range, branching factor, and maximum jump count. #### Currents * [*Shatter]: a powerful destructive force. useful for cutting open passageways quickly, and harming your enemies. * [*Purify]: banish ailments affecting you or nearby players * [*Nullify]: weaken or break active psionic powers nearby * [*Confine]: temporarily block a psionic being from being able to use their powers. to break a confinement, they will have to an amount of numina proportional to what you invested into it; the more powerful this ability becomes, the greater the multiplier. * [*Siphon]: drain health and stamina from a target * [*Reave]: destroy some of your target's numina * [*Lift]: produces antigravity. the specific effect depends on the Carrier. Lift is very useful in combination with other Currents, especially with [*Reach] carriers, as it can render foes helpless for the duration of the effect. ** a [*Lift Lance], [*Pulse], or [*Vortex] tosses targets high into the air ** a [*Lift Infusion] allows you to raise yourself into the air. this is not as flexible as true psionic flight, as it can only raise you upwards. ** a [*Lift Reach] allows telekinetic control of the target ** a [*Lift Torrent] or [*Tide] work like Reach, but can affect multiple targets. extremely useful when used alongside Repulse. ** [*Persisted] Lift currents can leave targets helplessly trapped until the Current runs out of power * [*Repulse]: like Lift, but throws targets back instead of up ** a [*Repulsion Lance] throws a target back violently ** a [*Repulsion Pulse] flings everything away from you ** a [*Repulsion Infusion] works like a charged psionic jump, as opposed to the hover effect of [*Lift]. ** a [*Repulsion Reach] charges an object with latent velocity, which is applied all at once when the effect is released ** a [*Repulsion Vortex] hurls its victims away from the point of detonation ** a [*Repulsion Torrent] or [*Tide] creates a powerful gale pushing targets back * [*Draw]: pull things toward you. can be used to disarm enemies * [*Reflect]: intercepts projectiles and causes them to ricochet or dissolve. this can only be used with certain Carriers: ** [*Reflect Pulse]: produces a protective dome ** [*Reflect Torrent]: produces a circular barrier in front of you ** [*Reflect Tide]: produces a broad barrier in front of you * [*Inflict]: severely damages target morale and stamina; increases fatigue and illness. a sadistic technique devised by the Kuradoqše. * [*Broil]: increases the target's body heat dramatically * [*Lattice]: a meta-Current, causes effects to persist for a given amount of time, to, for instance, suspend an enemy in the air and keep them trapped there long enough to give you a head start, or apply a damage-over-time effect. Lattice Currents only have a small effect from moment to moment, but they are more efficient than momentane Currents. the more you charge a persisted effect, the longer it will last and the more efficient it will become. #### * [*Blip]: short-range teleportation. can be used to break free of psionic holds #### Rituals * [*Cultivate] * [*Fortify] * [*Advance] * [*Coalesce]: manifest a spiritual object in the physical world by condensing your numina into a matter matrix. this is how numinium is created. * [*Rift]: teleport directly to a memorized location. * [*Ward]: surround yourself with a psionic barrier that must be worn down before anything can affect you. * [*Shard]: create psionic projectiles that orbit you until you are attached; the projectiles will then home in on the attacker and do significant damage. * [*Meditate]: sacrifice numina to improve your morale #### Manuvers * [*Rush]: psionic sprint * [*Soar]: psionic flight -- much faster than suit flight systems, but too power-hungry to use over long distances. * [*Shift]: teleport randomly a short distance to evade incoming attacks. * [*Shroud]: make yourself imperceptible ## legal starlit source code (*.lua, *.conf, *.txt, *.csd files) is released under the GNU AGPLv3. assets (images, sounds, models, and anything else in the repo that doesn't qualify as source code) are released under the CC-BY-NC-SA 3.0 license. sound files with the prefix `default-` are taken from Luanti Game, whose assets are available under the CC-BY-SA 3.0 license. |