Index: asset.list ================================================================== --- asset.list +++ asset.list @@ -211,17 +211,16 @@ mods/starlit/textures/starlit-terrain-sand.png mods/starlit/textures/starlit-terrain-soil.png mods/starlit/textures/starlit-terrain-undergloam-overlay.png mods/starlit/textures/starlit-terrain-cuprite.png mods/starlit/textures/starlit-terrain-undergloam.png -mods/starlit/textures/starlit-ui-alert-bg-hot.png mods/starlit/textures/starlit-ui-alert-bg-hydration.png mods/starlit/textures/starlit-ui-alert-bg-nutrition.png mods/starlit/textures/starlit-ui-alert-bg-rad.png mods/starlit/textures/starlit-ui-alert-bg-success.png +mods/starlit/textures/starlit-ui-alert-bg-temp-hot.png mods/starlit/textures/starlit-ui-alert-bg-temp-cold.png -mods/starlit/textures/starlit-ui-alert-bg-temp-rad.png mods/starlit/textures/starlit-ui-alert-hydration.png mods/starlit/textures/starlit-ui-alert-item.png mods/starlit/textures/starlit-ui-alert-nutrition.png mods/starlit/textures/starlit-ui-alert-rad.png mods/starlit/textures/starlit-ui-alert-temp-cold.png Index: mods/starlit-building/init.lua ================================================================== --- mods/starlit-building/init.lua +++ mods/starlit-building/init.lua @@ -174,10 +174,15 @@ end B.stage.foreach('starlit:stageGen', {}, function(id, e) local grp = e.groups and table.copy(e.groups) or {} grp.stage = 1 + local meta = { + stage = id; + recover = e.recover; + } + for k,v in pairs(e.meta or {}) do meta[k] = v end minetest.register_node(id, { description = 'Construction'; drawtype = (e.box and 'nodebox') or (e.mesh and 'mesh') or 'regular'; @@ -185,14 +190,11 @@ paramtype2 = e.paramtype2 or 'none'; tiles = e.tex; node_box = e.box; mesh = e.mesh; groups = grp; - _starlit = { - stage = id; - recover = e.recover; - }; + _starlit = meta; }) if e.begin then for _, kind in ipairs {'part', 'tool'} do for i, v in ipairs(e.begin[kind] or {}) do assert(B.begin[kind][v] == nil, 'attempted to overwrite buildpath beginning') Index: mods/starlit-building/stages/arch.lua ================================================================== --- mods/starlit-building/stages/arch.lua +++ mods/starlit-building/stages/arch.lua @@ -133,10 +133,30 @@ drop = 'starlit_building:panel'; swap = 'starlit_building:stage_floor_heater'; }; }; }; + groups = { + radiator = 1; + }; + meta = { + radiator = { + -- FIXME -- + maxEffectArea = function(pos) + local r = 3 + local dist = vector.new(r,r,r) + return pos - dist, pos + dist + end; + radius = function(pos) + return 3; + end; + radiate = function(rp, pos) + return 0; + end; + -- END FIXME -- + }; + }; }) B.panelRun = lib.registry.mk 'starlit_building:panelRun' B.panelRun.foreach('starlit_building:runGen', {}, function(id, run) local F = string.format @@ -194,11 +214,10 @@ }) local floorBasis = run.floorBasis or 'starlit_building:stage_foundation_insulation' B.pathLink(floorBasis, 'part', buildPart, floorStageRaw) - mat = floorMat + fabFor 'starlit_building:panel'; B.stage.link(floorStage, { tex = { 'starlit-node-floor-panel-top.png'; 'starlit-node-concrete.png'; imgPlug:blit(lib.image 'starlit-node-floor-panel-side.png'):render(); Index: mods/starlit-scenario/init.lua ================================================================== --- mods/starlit-scenario/init.lua +++ mods/starlit-scenario/init.lua @@ -35,10 +35,11 @@ return chip end local survivalBasics = { {'starlit_tech:chem_lamp', 0}; + {'starlit_tech:chem_radiator', 0}; {'starlit_tech:crate', 0}; {'starlit_building:battery_box', 0}; {'starlit_building:heating_element', 0}; {'starlit_building:electrode', 0}; {'starlit_building:cable_electric', 0}; Index: mods/starlit-tech/init.lua ================================================================== --- mods/starlit-tech/init.lua +++ mods/starlit-tech/init.lua @@ -1,100 +1,164 @@ local lib = starlit.mod.lib -do -- chemlamp - local burnTime = 60*60 - local maxBright = 12 - local stages = maxBright +local function mkBurnDown(def) -- chemlamp + local burnTime = def.time + local stages = def.stages or 10 local stageTimeout = burnTime / stages - local function chemLampID(n) - if n == stages then return 'starlit_tech:chem_lamp' end - return string.format('starlit_tech:chem_lamp_%s',n) + local function stID(n) + if n == stages then return def.id end + return string.format('%s_%s',def.id,n) end - local fab = starlit.type.fab { - element = { carbon = 4, magnesium = 1 }; - cost = { power = 100 }; - flag = { print = true }; - time = { print = 5 }; - }; + local fab = def.fab for i = stages, 0, -1 do - minetest.register_node(chemLampID(i), { - short_description = 'Chem Lamp'; + local grp = { + object = 1; + attached_node = 1; + } + if def.group then + for k,v in pairs(def.group((i/stages))) do grp[k]=v end + end + minetest.register_node(stID(i), { + short_description = def.name; description = starlit.ui.tooltip { - title = 'Chem Lamp'; - desc = "A simple carbon-frame chemical light source powered by ambient oxygen. Cheap, quick to print, and biodedragable, without any need for an electric grid or complex power storage mechanism. However, the light only lasts a few days, after which the lamp must be recycled or discarded."; - color = lib.color(1,.4,.1); + title = def.name; + desc = def.desc; + color = def.color; props = { - {title = 'Burn Remaining', desc=lib.math.timespec(stageTimeout * i), affinity=i > 4 and 'good' or 'bad'}; - {title = 'Mass', desc='10g', affinity='info'}; + {title = 'Burn Remaining', desc=lib.math.timespec(stageTimeout * i), affinity=i > (stages/2) and 'good' or 'bad'}; + {title = 'Mass', desc=lib.math.siUI('g', def.mass), affinity='info'}; }; }; drawtype = 'nodebox'; - groups = { - object = 1; - attached_node = 1; - }; + groups = grp; node_box = { type = 'fixed'; fixed = { - -.4, -.5, -.20; - .4, -.3, .20; + -(7/16), -.5, -(4/16); + (7/16), -.5 + (2/16), (4/16); }; }; - tiles = { - lib.image 'starlit-tech-lamp-glow.png' - :fade(1 - i/stages) - :blit(lib.image 'starlit-tech-lamp.png') - :render(); - }; + tiles = def.tile((i/stages)); paramtype = 'light'; paramtype2 = 'wallmounted'; wallmounted_rotate_vertical = true; - light_source = math.floor(lib.math.lerp(i/stages, 0, maxBright)); + light_source = math.floor(lib.math.lerp(i/stages, 0, def.glow)); on_construct = i ~= 0 and function(pos) local t = minetest.get_node_timer(pos) t:start(stageTimeout) + if def.ctor then def.ctor(pos, (i/stages)) end + end or nil; + on_destruct = def.dtor and function(pos) + def.dtor(pos, (i/stages)) end or nil; on_timer = i ~= 0 and function(pos) local me = minetest.get_node(pos) - minetest.swap_node(pos, {name=chemLampID(i-1), param2=me.param2}) + minetest.swap_node(pos, {name=stID(i-1), param2=me.param2}) return i > 1 end or nil; - _starlit = { - mass = 10; - reverseEngineer = { - complexity = 1; - sw = 'starlit_tech:schematic_chem_lamp'; - }; - recover = starlit.type.fab { - element = { - carbon = 8; - magnesium = math.floor(lib.math.lerp(i/stages, 0, 2)); + _starlit = (function() + local meta = { + mass = def.mass; + reverseEngineer = { + complexity = 1; + sw = def.id .. '_schematic'; + }; + recover = def.mat + + (def.fuel / (i/stages)) + + starlit.type.fab { + time = { + shred = .5; + shredPower = 2; + }; }; - time = { - shred = .5; - shredPower = 2; - }; - }; - - }; + } + for k,v in pairs(def.meta and def.meta((i/stages)) or {}) do meta[k]=v end + return meta + end)(); }) end - starlit.item.sw.link('starlit_tech:schematic_chem_lamp', { - name = 'Chem Lamp Schematic'; + starlit.item.sw.link(def.id .. '_schematic', { + name = def.name .. ' Schematic'; kind = 'schematic'; - input = fab; - output = chemLampID(stages); + input = def.fab + def.mat + def.fuel; + output = stID(stages); size = 32e6; cost = { cycles = 8e9; ram = 16e6; }; rarity = 1; }) end + +mkBurnDown { + id = 'starlit_tech:chem_lamp'; + name = 'Chem Lamp'; + desc = "A simple carbon-frame chemical light source powered by ambient oxygen. Cheap, quick to print, and biodedragable, without any need for an electric grid or complex power storage mechanism. However, the light only lasts a few days, after which the lamp must be recycled or discarded."; + stages = 12; + glow = 12; + time = 60*60; + mass = 10; + color = lib.color(1,.4,.1); + tile = function(f) return { + lib.image 'starlit-tech-lamp-glow.png' + :fade(f) + :blit(lib.image 'starlit-tech-lamp.png') + :render(); + } end; + fab = starlit.type.fab { + cost = { power = 100 }; + flag = { print = true }; + time = { print = 5 }; + }; + mat = starlit.type.fab { element = { carbon = 4 }; }; + fuel = starlit.type.fab { element = { magnesium = 1 }; }; +} + +mkBurnDown { + id = 'starlit_tech:chem_radiator'; + name = 'Chem Radiator'; + desc = "A simple carbon-frame chemical heat source powered by ambient oxygen. Cheap, quick to print, and biodedragable, without any need for an electric grid or complex power storage mechanism. However, the heat only lasts a few hours, after which the lamp must be recycled or discarded."; + stages = 12; + glow = 7; + time = 15*60; + mass = 10; + color = lib.color(1,.4,.1); + tile = function(f) return { + lib.image 'starlit-tech-lamp-glow.png' + :fade(f) + :blit(lib.image 'starlit-tech-lamp.png') + :tint{hue=0,sat=1,lum=.5}:render(); + } end; + fab = starlit.type.fab { + cost = { power = 150 }; + flag = { print = true }; + time = { print = 10 }; + }; + mat = starlit.type.fab { element = { carbon = 4 }; }; + fuel = starlit.type.fab { element = { magnesium = 2, iron = 2 }; }; + group = function(f) + if f > 0 + then return {radiator=1} + else return {} + end + end; + ctor = function(pos, f) starlit.region.radiator.scan(pos) end; + dtor = function(pos, f) starlit.region.radiator.unload(pos) end; + meta = function(f) return { + radiator = { + radius = function(pos) + return 2; + end; + radiate = function(rp, pos) + return 15 * f + end; + }; + } end; +} minetest.register_node('starlit_tech:crate', { short_description = 'Crate'; description = starlit.ui.tooltip { title = 'Crate'; Index: mods/starlit/init.lua ================================================================== --- mods/starlit/init.lua +++ mods/starlit/init.lua @@ -63,11 +63,11 @@ alg = {}; region = { radiator = { store = AreaStore(); - emitters = {}; + sources = {}; }; }; -- standardized effects fx = {}; @@ -220,29 +220,50 @@ end function starlit.include(name, ...) -- semantic variant used for loading modules return starlit.evaluate(name..'.lua', ...) end + +function starlit.region.radiator.scan(pos,node) + local R = starlit.region + local phash = minetest.hash_node_position(pos) + if R.radiator.sources[phash] then return end -- already loaded + node = node or minetest.get_node(pos) + + local def = minetest.registered_nodes[node.name] + local cl = def._starlit and def._starlit.radiator + if not cl then return nil end + local min,max = cl.maxEffectArea and cl.maxEffectArea(pos) or nil + if not min then + assert(cl.radius, 'no radius callback for radiator') + local r = cl.radius(pos) + local vr = vector.new(r,r,r) + min,max = pos-vr, pos+vr + end + local id = R.radiator.store:insert_area(min,max, minetest.pos_to_string(pos)) + R.radiator.sources[phash] = id +end + +function starlit.region.radiator.unload(pos) + local R = starlit.region + local phash = minetest.hash_node_position(pos) + local id = R.radiator.sources[phash] + R.radiator.store:remove_area(id) + R.radiator.sources[phash] = nil +end minetest.register_lbm { label = 'build radiator index'; name = 'starlit:loadradiatorboxes'; nodenames = {'group:radiator'}; run_at_every_load = true; action = function(pos, node, dt) - local R = starlit.region - local phash = minetest.hash_node_position(pos) - if R.radiator.sources[phash] then return end -- already loaded - - local def = minetest.registered_nodes[node.name] - local cl = def._starlit.radiator - local min,max = cl.maxEffectArea(pos) - local id = R.radiator.store:insert_area(min,max, minetest.pos_to_string(pos)) - R.radiator.sources[phash] = id + starlit.region.radiator.scan(pos, node) end; -- NOTE: temp emitter nodes are responsible for decaching themselves in their on_destruct cb } + function starlit.startJob(id, interval, job) local lastRun local function start() starlit.jobs[id] = minetest.after(interval, function() Index: mods/starlit/user.lua ================================================================== --- mods/starlit/user.lua +++ mods/starlit/user.lua @@ -247,17 +247,16 @@ alignment = def.align; position = def.pos; offset = def.ofs; z_index = def.z; } - if def.update then - img.update = function() - def.update(user, function(prop, val) - user:hud_change(img.id, prop, val) - end, def) - end + function img.chg(prop, val) + user:hud_change(img.id, prop, val) end + img.update = def.update and function() + def.update(user, img.chg, def) + end or function() end return img end; attachMeter = function(self, def) local luser = self.entity local m = {def = def} @@ -530,20 +529,20 @@ 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 - local idx = 0 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 table.insert(del, i) else - local xc = (idx*48 + 400)*ofs + local xc = (idx*80 + 399)*ofs if l.elt and next(del) then - l.elt:update('offset', {x=xc, y=1}) + l.elt.chg('offset', {x=xc, y=1}) else local tex = leds[l.kind].icon:blit(hudAdjustBacklight(leds[l.kind].bg)) if tx then tex = lib.image(tex:render()):transform(tx) end if not l.elt then l.elt = self:attachImage { @@ -1033,18 +1032,16 @@ self.cooldownTimes.alarm = time self:suitSound(urg.sound) end end - local newLed = { kind = kind; origin = time; } self.hud.led.map[kind] = newLed table.insert(self.hud.led[led.side], newLed) - self:updateLEDs() --[[ freq = freq or 3 Index: mods/vtlib/math.lua ================================================================== --- mods/vtlib/math.lua +++ mods/vtlib/math.lua @@ -6,11 +6,11 @@ end -- minetest now only provides the version of this function that sqrts the result -- which is pointlessly wasteful much of the time fn.vdsq = function(a,b) - local d = vector.subtract(v1,v2) + local d = vector.subtract(a,b) return (d.x ^ 2) + (d.y ^ 2) + (d.z ^ 2) end fn.vdcomp = function(dist,v1,v2) -- compare the distance between two points -- (cheaper than calculating distance outright)