63
64
65
66
67
68
69
70
71
72
73
74
75
76
..
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
...
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
...
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
...
415
416
417
418
419
420
421
422
423
424
425
426
427
428
...
499
500
501
502
503
504
505
506
507
508
509
510
511
512
...
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
|
end;
__index = {
pullPersona = function(self)
-- if later records are added in public updates, extend this function to merge them
-- into one object
local s = userStore(self.entity)
self.persona = s.read 'persona'
end;
pushPersona = function(self)
local s = userStore(self.entity)
s.write('persona', self.persona)
end;
uiColor = function(self) return lib.color {hue=238,sat=.5,lum=.5} end;
statDelta = function(self, stat, d, cause, abs)
................................................................................
end
self:updateHUD()
-- TODO trigger relevant animations?
end;
lookupSpecies = function(self)
return starlit.world.species.lookup(self.persona.species, self.persona.speciesVariant)
end;
phenoTrait = function(self, trait)
local s,v = self:lookupSpecies()
return v.traits[trait] or s.traits[trait] or 0
end;
statRange = function(self, stat) --> min, max, base
return starlit.world.species.statRange(
self.persona.species, self.persona.speciesVariant, stat)
end;
effectiveStat = function(self, stat)
local val
................................................................................
local hot = self:effectiveStat 'irradiation'
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;
}
self.hud.elt.crosshair = self:attachImage {
name = 'crosshair ';
tex = '';
pos = {x=.5, y=.5};
scale = {x=1,y=1};
ofs = {x=0, y=0};
align = {x=0, y=0};
update = function(user, set)
local imgs = {
................................................................................
align = {x=0, y=-1};
z = -1;
update = function(user, set)
set('text', hudAdjustBacklight(hudCenterBG):render())
end;
};
end;
onModeChange = function(self, oldMode, silent)
self.hud.elt.crosshair.update()
if not silent then
local sfxt = {
off = 'starlit-mode-off';
nano = 'starlit-mode-nano';
psi = 'starlit-mode-psi';
weapon = 'starlit-mode-weapon';
}
local sfx = self.actMode and sfxt[self.actMode] or sfxt.off
self:suitSound(sfx)
end
end;
actModeSet = function(self, mode, silent)
if not mode then mode = 'off' end
local oldMode = self.actMode
self.actMode = mode
self:onModeChange(oldMode, silent)
................................................................................
return minetest.get_player_information(self.name)
end;
onSignup = function(self)
local meta = self.entity:get_meta()
local inv = self.entity:get_inventory()
-- the sizes indicated here are MAXIMA. limitations on e.g. the number of elements that may be carried are defined by your suit and enforced through callbacks and UI generation code, not inventory size
inv:set_size('main', 6) -- carried items and tools. main hotbar.
inv:set_size('starlit_suit', 1) -- your environment suit (change at wardrobe)
inv:set_size('starlit_cfg', 1) -- the item you're reconfiguring / container you're accessing
local scenario
for _, e in pairs(starlit.world.scenario) do
if e.id == starlit.world.defaultScenario then
................................................................................
self:updateSuit()
return true
end;
onJoin = function(self)
local me = self.entity
local meta = me:get_meta()
self:pullPersona()
-- formspec_version and real_coordinates are apparently just
-- completely ignored here
me:set_formspec_prepend [[
bgcolor[#00000000;true]
style_type[button,button_exit,image_button,item_image_button;border=false]
style_type[button;bgimg=starlit-ui-button-hw.png;bgimg_middle=8;content_offset=0,-2]
................................................................................
give = function(self, item)
local inv = self.entity:get_inventory()
local function is(grp)
return minetest.get_item_group(item:get_name(), grp) ~= 0
end
-- TODO notif popups
if is 'specialInventory' then
if is 'powder' then
if self:naked() then return item end
local cans = inv:get_list 'starlit_suit_canisters'
if cans and next(cans) then for i, st in ipairs(cans) do
local lst = string.format('starlit_canister_%u_elem', i)
item = inv:add_item(lst, item)
if item:is_empty() then break end
end end
self:forSuit(function(x) x:pushCanisters(inv) end)
end
return item
else
return inv:add_item('main', item)
end
end;
thrustUpon = function(self, item)
local r = self:give(st)
if not r:is_empty() then
return minetest.add_item(self.entity:get_pos(), r)
end
end;
};
}
local biointerval = 3.0
starlit.startJob('starlit:bio', biointerval, function(delta)
for id, u in pairs(starlit.activeUsers) do
end
end)
local cbit = {
up = 0x001;
down = 0x002;
left = 0x004;
|
>
|
|
|
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
..
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
...
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
...
377
378
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
406
407
408
409
410
411
412
...
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
...
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
...
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
|
end;
__index = {
pullPersona = function(self)
-- if later records are added in public updates, extend this function to merge them
-- into one object
local s = userStore(self.entity)
self.persona = s.read 'persona'
self.pheno = starlit.world.species.pheno(self.persona.species, self.persona.speciesVariant)
end;
pushPersona = function(self)
local s = userStore(self.entity)
s.write('persona', self.persona)
end;
uiColor = function(self) return lib.color {hue=238,sat=.5,lum=.5} end;
statDelta = function(self, stat, d, cause, abs)
................................................................................
end
self:updateHUD()
-- TODO trigger relevant animations?
end;
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;
statRange = function(self, stat) --> min, max, base
return starlit.world.species.statRange(
self.persona.species, self.persona.speciesVariant, stat)
end;
effectiveStat = function(self, stat)
local val
................................................................................
local hot = self:effectiveStat 'irradiation'
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;
}
self.hud.elt.crosshair = self:attachImage {
name = 'crosshair';
tex = '';
pos = {x=.5, y=.5};
scale = {x=1,y=1};
ofs = {x=0, y=0};
align = {x=0, y=0};
update = function(user, set)
local imgs = {
................................................................................
align = {x=0, y=-1};
z = -1;
update = function(user, set)
set('text', hudAdjustBacklight(hudCenterBG):render())
end;
};
end;
-- horrible horrible HACK
setModeHand = function(self)
local inv = self.entity:get_inventory()
local hnd
if self.actMode == 'off'
then hnd = ItemStack('starlit:_hand_dig')
else hnd = ItemStack()
end
inv:set_stack('hand', 1, hnd)
end;
onModeChange = function(self, oldMode, silent)
self.hud.elt.crosshair.update()
if not silent then
local sfxt = {
off = 'starlit-mode-off';
nano = 'starlit-mode-nano';
psi = 'starlit-mode-psi';
weapon = 'starlit-mode-weapon';
}
local sfx = self.actMode and sfxt[self.actMode] or sfxt.off
self:suitSound(sfx)
self:setModeHand()
end
end;
actModeSet = function(self, mode, silent)
if not mode then mode = 'off' end
local oldMode = self.actMode
self.actMode = mode
self:onModeChange(oldMode, silent)
................................................................................
return minetest.get_player_information(self.name)
end;
onSignup = function(self)
local meta = self.entity:get_meta()
local inv = self.entity:get_inventory()
-- the sizes indicated here are MAXIMA. limitations on e.g. the number of elements that may be carried are defined by your suit and enforced through callbacks and UI generation code, not inventory size
inv:set_size('main', 6) -- carried items and tools. main hotbar.
inv:set_size('hand', 1) -- horrible hack to allow both tools and intrinsics
inv:set_size('starlit_suit', 1) -- your environment suit (change at wardrobe)
inv:set_size('starlit_cfg', 1) -- the item you're reconfiguring / container you're accessing
local scenario
for _, e in pairs(starlit.world.scenario) do
if e.id == starlit.world.defaultScenario then
................................................................................
self:updateSuit()
return true
end;
onJoin = function(self)
local me = self.entity
local meta = me:get_meta()
self:pullPersona()
self:setModeHand()
-- formspec_version and real_coordinates are apparently just
-- completely ignored here
me:set_formspec_prepend [[
bgcolor[#00000000;true]
style_type[button,button_exit,image_button,item_image_button;border=false]
style_type[button;bgimg=starlit-ui-button-hw.png;bgimg_middle=8;content_offset=0,-2]
................................................................................
give = function(self, item)
local inv = self.entity:get_inventory()
local function is(grp)
return minetest.get_item_group(item:get_name(), grp) ~= 0
end
-- TODO notif popups
if is 'specialInventory' then
--[[
if is 'powder' then
if self:naked() then return item end
local cans = inv:get_list 'starlit_suit_canisters'
if cans and next(cans) then for i, st in ipairs(cans) do
local lst = string.format('starlit_canister_%u_elem', i)
item = inv:add_item(lst, item)
if item:is_empty() then break end
end end
self:forSuit(function(x) x:pushCanisters(inv) end)
end
return item
]]
else
return inv:add_item('main', item)
end
end;
thrustUpon = function(self, item)
local r = self:give(st)
if not r:is_empty() then
return minetest.add_item(self.entity:get_pos(), r)
end
end;
consume = function(self, stack, n)
n = n or 1
if n == 0 then n = stack:get_count() end
local fd = stack:take_item(n)
local stats = starlit.world.food.effectiveStats(fd)
return stack
end;
};
}
local biointerval = 3.0
starlit.startJob('starlit:bio', biointerval, function(delta)
for id, u in pairs(starlit.activeUsers) do
local p = u.pheno
local bmr = p:trait 'metabolism' * biointerval
-- TODO apply modifiers
local dehydration = p:trait 'dehydration' * biointerval
-- you dehydrate faster in higher temp
dehydration = dehydration * math.max(1, starlit.world.climate.temp(u.entity:get_pos()) / 10)
u:statDelta('hunger', bmr)
u:statDelta('thirst', dehydration)
end
end)
local cbit = {
up = 0x001;
down = 0x002;
left = 0x004;
|