6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
..
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
...
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
...
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
...
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
...
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
...
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
...
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
...
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
....
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
....
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
....
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
....
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
....
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
....
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
....
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
|
-- client. it provides for initial signup and join,
-- managing the HUD, skinning the player model,
-- effecting weather changes, etc.
local lib = starlit.mod.lib
local function hudAdjustBacklight(img)
local night = math.abs(minetest.get_timeofday() - .5) * 2
local opacity = night*0.8
return img:fade(opacity)
end
local userStore = lib.marshal.metaStore {
persona = {
key = 'starlit:persona';
................................................................................
starlit.type.user = lib.class {
name = 'starlit:user';
leds = leds;
construct = function(ident)
local name, luser
if type(ident) == 'string' then
name = ident
luser = minetest.get_player_by_name(name)
else
luser = ident
name = luser:get_player_name()
end
return {
entity = luser;
name = name;
................................................................................
}
end;
__index = {
--------------
-- overlays --
--------------
updateOverlays = function(self)
-- minetest: because fuck you, that's why
local engineGravity = starlit.constant.phys.engineGravity
local targetGravity = starlit.world.planet.gravity
local phys = {
speed = self.pheno:trait('speed',1);
jump = self.pheno:trait('jump',1);
gravity = targetGravity / engineGravity;
speed_climb = 1;
................................................................................
self.hud.elt.time = self:attachTextBox {
name = 'time';
align = {x=0, y=1};
pos = {x=0.5, y=1};
ofs = {x=0,y=-95};
text = function(user)
local cal = starlit.world.time.calendar[user.pref.calendar]
return cal.time(minetest.get_timeofday())
end;
}
self.hud.elt.temp = self:attachMeter {
name = 'temp';
align = {x=1, y=-1};
pos = {x=0, y=1};
ofs = {x=20, y=-20};
................................................................................
updateHUD = function(self)
for name, e in pairs(self.hud.elt) do
if e.update then e.update() end
end
self:updateLEDs()
end;
updateLEDs = function(self)
local time = minetest.get_gametime()
local function updateSide(name, ofs, tx)
local del = {}
local idx = 0
for i, l in ipairs(self.hud.led[name]) do
if time - l.origin > 3 then
if l.elt then self.entity:hud_remove(l.elt.id) end
self.hud.led.map[l.kind] = nil
................................................................................
inv:set_stack('hand', 1, hnd)
end;
---------------------
-- intel-gathering --
---------------------
clientInfo = function(self)
return minetest.get_player_information(self.name)
end;
species = function(self)
return starlit.world.species.index[self.persona.species]
end;
-- can the suit heater sustain its current internal temperature in an area of t°C
tempCanSustain = function(self, t)
if self:naked() then return false end
................................................................................
-- i feel like there has to be a better way
local posrng = starlit.world.seedbank[0x13f19] -- TODO player-specific seed
local cx = posrng:int(-500,500) --math.random(-500,500)
local iter, startPoint = 1
repeat local temp = -100
local cz = posrng:int(-500,500)
local cy = minetest.get_spawn_level(cx, cz)
if cy then
startPoint = vector.new(cx,cy,cz)
temp = starlit.world.climate.eval(startPoint,.5,.5).surfaceTemp
end
iter = iter + 1
if iter > 100 then break end -- avoid infiniloop in pathological conditions
until temp > -2
................................................................................
onDie = function(self, reason)
local inv = self.entity:get_inventory()
local where = self.entity:get_pos()
local function dropInv(lst)
local l = inv:get_list(lst)
for i, o in ipairs(l) do
if o and not o:is_empty() then
minetest.item_drop(o, self.entity, where)
end
end
inv:set_list(lst, {})
end
dropInv 'main'
dropInv 'starlit_suit'
self:updateSuit()
................................................................................
-- environment suit & body --
-----------------------------
suitStack = function(self)
return self.entity:get_inventory():get_stack('starlit_suit', 1)
end;
suitSound = function(self, sfx)
-- trigger a sound effect from the player's suit computer
minetest.sound_play(sfx, {object=self.entity, max_hear_distance=4}, true)
end;
suitPowerStateSet = function(self, state, silent)
-- necessary to enable reacting to power state changes
-- e.g. to play sound effects, display warnings
local os
self:forSuit(function(s)
os=s:powerState()
................................................................................
return true
end
return false
end;
alarm = function(self, urgency, kind, minFreq)
minFreq = minFreq or 1.5
local time = minetest.get_gametime()
local led = leds[kind]
local ul = self.hud.led.map[kind]
if ul then
if time - ul.origin > minFreq then
ul.origin = time
else return end
................................................................................
--[[
freq = freq or 3
local urgencies = {
[1] = {sound = 'starlit-alarm'};
[2] = {sound = 'starlit-alarm-urgent'};
}
local gt = minetest.get_gametime()
local urg = urgencies[urgency] or urgencies[#urgencies]
if gt - self.cooldownTimes.alarm < freq then return end
self.cooldownTimes.alarm = gt
self:suitSound(urg.sound)
................................................................................
}
elt.ofs.x = elt.ofs.x + where.ofs.x
elt.ofs.y = elt.ofs.y + where.ofs.y
local attached = self:attachImage(elt)
table.insert(self.hud.alarm, attached)
-- HATE. HATE. HAAAAAAAAAAATE
minetest.after(freq/2, function()
for k,v in pairs(self.hud.alarm) do
self.entity:hud_remove(v.id)
end
self.hud.alarm={}
end)
end]]
end;
................................................................................
---------------
-- inventory --
---------------
give = function(self, item)
item = ItemStack(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'
................................................................................
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)
................................................................................
u:statDelta('health', -5*biointerval)
end
if water == 0 then -- dying of thirst
u:statDelta('health', -20*biointerval)
end
if sp < 1.0 and minetest.get_gametime() - u.cooldownTimes.stamina > 5.0 then
u:statDelta('stamina', (u:phenoTrait('staminaRegen',1) * penaltyFromFatigue) / heatPenalty)
-- print('stam', u:effectiveStat 'stamina', u:phenoTrait('staminaRegen',1) / heatPenalty, heatPenalty)
end
local morale, mp = u:effectiveStat 'morale'
local pr = u:phenoTrait 'numinaRegen'
u:statDelta('numina', pr * penaltyFromFatigue * mp)
................................................................................
manv = 0x020;
snk = 0x040;
dig = 0x080;
put = 0x100;
zoom = 0x200;
}
-- this is the painful part
minetest.register_globalstep(function(delta)
local doNothing,mustInit,mustHalt = 0,1,2
for id, user in pairs(starlit.activeUsers) do
local ent = user.entity
local bits = ent:get_player_control_bits()
local function what(b)
if bit.band(bits, b) ~= 0 and bit.band(user.action.bits, b) == 0 then
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
..
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
...
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
...
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
...
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
...
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
...
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
...
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
...
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
....
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
....
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
....
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
....
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
....
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
....
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
....
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
|
-- client. it provides for initial signup and join,
-- managing the HUD, skinning the player model,
-- effecting weather changes, etc.
local lib = starlit.mod.lib
local function hudAdjustBacklight(img)
local night = math.abs(core.get_timeofday() - .5) * 2
local opacity = night*0.8
return img:fade(opacity)
end
local userStore = lib.marshal.metaStore {
persona = {
key = 'starlit:persona';
................................................................................
starlit.type.user = lib.class {
name = 'starlit:user';
leds = leds;
construct = function(ident)
local name, luser
if type(ident) == 'string' then
name = ident
luser = core.get_player_by_name(name)
else
luser = ident
name = luser:get_player_name()
end
return {
entity = luser;
name = name;
................................................................................
}
end;
__index = {
--------------
-- overlays --
--------------
updateOverlays = function(self)
-- luanti: because fuck you, that's why
local engineGravity = starlit.constant.phys.engineGravity
local targetGravity = starlit.world.planet.gravity
local phys = {
speed = self.pheno:trait('speed',1);
jump = self.pheno:trait('jump',1);
gravity = targetGravity / engineGravity;
speed_climb = 1;
................................................................................
self.hud.elt.time = self:attachTextBox {
name = 'time';
align = {x=0, y=1};
pos = {x=0.5, y=1};
ofs = {x=0,y=-95};
text = function(user)
local cal = starlit.world.time.calendar[user.pref.calendar]
return cal.time(core.get_timeofday())
end;
}
self.hud.elt.temp = self:attachMeter {
name = 'temp';
align = {x=1, y=-1};
pos = {x=0, y=1};
ofs = {x=20, y=-20};
................................................................................
updateHUD = function(self)
for name, e in pairs(self.hud.elt) do
if e.update then e.update() end
end
self:updateLEDs()
end;
updateLEDs = function(self)
local time = core.get_gametime()
local function updateSide(name, ofs, tx)
local del = {}
local idx = 0
for i, l in ipairs(self.hud.led[name]) do
if time - l.origin > 3 then
if l.elt then self.entity:hud_remove(l.elt.id) end
self.hud.led.map[l.kind] = nil
................................................................................
inv:set_stack('hand', 1, hnd)
end;
---------------------
-- intel-gathering --
---------------------
clientInfo = function(self)
return core.get_player_information(self.name)
end;
species = function(self)
return starlit.world.species.index[self.persona.species]
end;
-- can the suit heater sustain its current internal temperature in an area of t°C
tempCanSustain = function(self, t)
if self:naked() then return false end
................................................................................
-- i feel like there has to be a better way
local posrng = starlit.world.seedbank[0x13f19] -- TODO player-specific seed
local cx = posrng:int(-500,500) --math.random(-500,500)
local iter, startPoint = 1
repeat local temp = -100
local cz = posrng:int(-500,500)
local cy = core.get_spawn_level(cx, cz)
if cy then
startPoint = vector.new(cx,cy,cz)
temp = starlit.world.climate.eval(startPoint,.5,.5).surfaceTemp
end
iter = iter + 1
if iter > 100 then break end -- avoid infiniloop in pathological conditions
until temp > -2
................................................................................
onDie = function(self, reason)
local inv = self.entity:get_inventory()
local where = self.entity:get_pos()
local function dropInv(lst)
local l = inv:get_list(lst)
for i, o in ipairs(l) do
if o and not o:is_empty() then
core.item_drop(o, self.entity, where)
end
end
inv:set_list(lst, {})
end
dropInv 'main'
dropInv 'starlit_suit'
self:updateSuit()
................................................................................
-- environment suit & body --
-----------------------------
suitStack = function(self)
return self.entity:get_inventory():get_stack('starlit_suit', 1)
end;
suitSound = function(self, sfx)
-- trigger a sound effect from the player's suit computer
core.sound_play(sfx, {object=self.entity, max_hear_distance=4}, true)
end;
suitPowerStateSet = function(self, state, silent)
-- necessary to enable reacting to power state changes
-- e.g. to play sound effects, display warnings
local os
self:forSuit(function(s)
os=s:powerState()
................................................................................
return true
end
return false
end;
alarm = function(self, urgency, kind, minFreq)
minFreq = minFreq or 1.5
local time = core.get_gametime()
local led = leds[kind]
local ul = self.hud.led.map[kind]
if ul then
if time - ul.origin > minFreq then
ul.origin = time
else return end
................................................................................
--[[
freq = freq or 3
local urgencies = {
[1] = {sound = 'starlit-alarm'};
[2] = {sound = 'starlit-alarm-urgent'};
}
local gt = core.get_gametime()
local urg = urgencies[urgency] or urgencies[#urgencies]
if gt - self.cooldownTimes.alarm < freq then return end
self.cooldownTimes.alarm = gt
self:suitSound(urg.sound)
................................................................................
}
elt.ofs.x = elt.ofs.x + where.ofs.x
elt.ofs.y = elt.ofs.y + where.ofs.y
local attached = self:attachImage(elt)
table.insert(self.hud.alarm, attached)
-- HATE. HATE. HAAAAAAAAAAATE
core.after(freq/2, function()
for k,v in pairs(self.hud.alarm) do
self.entity:hud_remove(v.id)
end
self.hud.alarm={}
end)
end]]
end;
................................................................................
---------------
-- inventory --
---------------
give = function(self, item)
item = ItemStack(item)
local inv = self.entity:get_inventory()
local function is(grp)
return core.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'
................................................................................
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 core.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)
................................................................................
u:statDelta('health', -5*biointerval)
end
if water == 0 then -- dying of thirst
u:statDelta('health', -20*biointerval)
end
if sp < 1.0 and core.get_gametime() - u.cooldownTimes.stamina > 5.0 then
u:statDelta('stamina', (u:phenoTrait('staminaRegen',1) * penaltyFromFatigue) / heatPenalty)
-- print('stam', u:effectiveStat 'stamina', u:phenoTrait('staminaRegen',1) / heatPenalty, heatPenalty)
end
local morale, mp = u:effectiveStat 'morale'
local pr = u:phenoTrait 'numinaRegen'
u:statDelta('numina', pr * penaltyFromFatigue * mp)
................................................................................
manv = 0x020;
snk = 0x040;
dig = 0x080;
put = 0x100;
zoom = 0x200;
}
-- this is the painful part
core.register_globalstep(function(delta)
local doNothing,mustInit,mustHalt = 0,1,2
for id, user in pairs(starlit.activeUsers) do
local ent = user.entity
local bits = ent:get_player_control_bits()
local function what(b)
if bit.band(bits, b) ~= 0 and bit.band(user.action.bits, b) == 0 then
|