starlit  Check-in [2e501ef0db]

Overview
Comment:add chem radiator, add dummy radiator props to underfloor heater, complete (?) unfinished radiator API, fix longstanding LED offset buggery & crash, fix asset filename issue for LEDs, fix broken vector func
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 2e501ef0db93a7c47eeb2926ebd6dd9f9d16a713a62822048a733e191d703ed1
User & Date: lexi on 2024-05-15 20:37:58
Original Comment: add chem radiator add dummy radiator props to underfloor heater fix longstanding LED offset buggery & crash fix asset filename issue for LEDs fix broken vector func
Other Links: manifest | tags
Context
2024-12-19
20:03
unfuck cpio invocations check-in: e926621707 user: root tags: trunk
2024-05-15
20:37
add chem radiator, add dummy radiator props to underfloor heater, complete (?) unfinished radiator API, fix longstanding LED offset buggery & crash, fix asset filename issue for LEDs, fix broken vector func check-in: 2e501ef0db user: lexi tags: trunk
18:51
add (nonfunctional) floor heater check-in: d6efac25ef user: lexi tags: trunk
Changes

Modified asset.list from [38c250b2ba] to [33338e0378].

   209    209   mods/starlit/textures/starlit-terrain-greengraze.png~
   210    210   mods/starlit/textures/starlit-terrain-lifesilt.png
   211    211   mods/starlit/textures/starlit-terrain-sand.png
   212    212   mods/starlit/textures/starlit-terrain-soil.png
   213    213   mods/starlit/textures/starlit-terrain-undergloam-overlay.png
   214    214   mods/starlit/textures/starlit-terrain-cuprite.png
   215    215   mods/starlit/textures/starlit-terrain-undergloam.png
   216         -mods/starlit/textures/starlit-ui-alert-bg-hot.png
   217    216   mods/starlit/textures/starlit-ui-alert-bg-hydration.png
   218    217   mods/starlit/textures/starlit-ui-alert-bg-nutrition.png
   219    218   mods/starlit/textures/starlit-ui-alert-bg-rad.png
   220    219   mods/starlit/textures/starlit-ui-alert-bg-success.png
          220  +mods/starlit/textures/starlit-ui-alert-bg-temp-hot.png
   221    221   mods/starlit/textures/starlit-ui-alert-bg-temp-cold.png
   222         -mods/starlit/textures/starlit-ui-alert-bg-temp-rad.png
   223    222   mods/starlit/textures/starlit-ui-alert-hydration.png
   224    223   mods/starlit/textures/starlit-ui-alert-item.png
   225    224   mods/starlit/textures/starlit-ui-alert-nutrition.png
   226    225   mods/starlit/textures/starlit-ui-alert-rad.png
   227    226   mods/starlit/textures/starlit-ui-alert-temp-cold.png
   228    227   mods/starlit/textures/starlit-ui-alert-temp-hot.png
   229    228   mods/starlit/textures/starlit-ui-alert.png

Modified mods/starlit-building/init.lua from [c6afb91b3d] to [cc61bb3736].

   172    172   	if not B.path[from] then return nil end
   173    173   	return B.path[from][kind][what]
   174    174   end
   175    175   
   176    176   B.stage.foreach('starlit:stageGen', {}, function(id, e)
   177    177   	local grp = e.groups and table.copy(e.groups) or {}
   178    178   	grp.stage = 1
          179  +	local meta = {
          180  +		stage = id;
          181  +		recover = e.recover;
          182  +	}
          183  +	for k,v in pairs(e.meta or {}) do meta[k] = v end
   179    184   	minetest.register_node(id, {
   180    185   		description = 'Construction';
   181    186   		drawtype = (e.box  and 'nodebox')
   182    187   		        or (e.mesh and 'mesh')
   183    188   		        or 'regular';
   184    189   		paramtype  = e.paramtype or (e.box or e.mesh or e.light) and 'light' or nil;
   185    190   		paramtype2 = e.paramtype2 or 'none';
   186    191   		tiles = e.tex;
   187    192   		node_box = e.box;
   188    193   		mesh = e.mesh;
   189    194   		groups = grp;
   190         -		_starlit = {
   191         -			stage = id;
   192         -			recover = e.recover;
   193         -		};
          195  +		_starlit = meta;
   194    196   	})
   195    197   	if e.begin then
   196    198   		for _, kind in ipairs {'part', 'tool'} do
   197    199   			for i, v in ipairs(e.begin[kind] or {}) do
   198    200   				assert(B.begin[kind][v] == nil, 'attempted to overwrite buildpath beginning')
   199    201   				B.begin[kind][v] = id
   200    202   			end

Modified mods/starlit-building/stages/arch.lua from [625292d7b1] to [26a8b6ec24].

   131    131   			unscrew = {
   132    132   				speed = 2;
   133    133   				drop = 'starlit_building:panel';
   134    134   				swap = 'starlit_building:stage_floor_heater';
   135    135   			};
   136    136   		};
   137    137   	};
          138  +	groups = {
          139  +		radiator = 1;
          140  +	};
          141  +	meta = {
          142  +		radiator = {
          143  +			-- FIXME --
          144  +			maxEffectArea = function(pos)
          145  +				local r = 3
          146  +				local dist = vector.new(r,r,r)
          147  +				return pos - dist, pos + dist
          148  +			end;
          149  +			radius = function(pos)
          150  +				return 3;
          151  +			end;
          152  +			radiate = function(rp, pos)
          153  +				return 0;
          154  +			end;
          155  +			-- END FIXME --
          156  +		};
          157  +	};
   138    158   })
   139    159   
   140    160   B.panelRun = lib.registry.mk 'starlit_building:panelRun'
   141    161   B.panelRun.foreach('starlit_building:runGen', {}, function(id, run)
   142    162   	local F = string.format
   143    163   	assert(run.name, 'missing name for panelrun')
   144    164   	local name = run.name
................................................................................
   192    212   			};
   193    213   		};
   194    214   	})
   195    215   
   196    216   	local floorBasis = run.floorBasis or 'starlit_building:stage_foundation_insulation'
   197    217   	B.pathLink(floorBasis, 'part', buildPart, floorStageRaw)
   198    218   
   199         -	mat = floorMat + fabFor 'starlit_building:panel';
   200    219   	B.stage.link(floorStage, {
   201    220   		tex = {
   202    221   			'starlit-node-floor-panel-top.png';
   203    222   			'starlit-node-concrete.png';
   204    223   			imgPlug:blit(lib.image 'starlit-node-floor-panel-side.png'):render();
   205    224   		};
   206    225   		recover = floorMat + fabFor 'starlit_building:panel';

Modified mods/starlit-scenario/init.lua from [d2f3af923b] to [8a376bbedc].

    33     33   	r.files = files
    34     34   	E.chip.write(chip, r)
    35     35   	return chip
    36     36   end
    37     37   
    38     38   local survivalBasics = {
    39     39   		{'starlit_tech:chem_lamp', 0};
           40  +		{'starlit_tech:chem_radiator', 0};
    40     41   		{'starlit_tech:crate', 0};
    41     42   		{'starlit_building:battery_box', 0};
    42     43   		{'starlit_building:heating_element', 0};
    43     44   		{'starlit_building:electrode', 0};
    44     45   		{'starlit_building:cable_electric', 0};
    45     46   		{'starlit_building:transformer', 0};
    46     47   		{'starlit_building:concrete', 0};

Modified mods/starlit-tech/init.lua from [de8d4eba0f] to [22b6956759].

     1      1   local lib = starlit.mod.lib
     2      2   
     3      3   
     4         -do -- chemlamp
     5         -	local burnTime = 60*60
     6         -	local maxBright = 12
     7         -	local stages = maxBright
            4  +local function mkBurnDown(def) -- chemlamp
            5  +	local burnTime = def.time
            6  +	local stages = def.stages or 10
     8      7   	local stageTimeout = burnTime / stages
     9         -	local function chemLampID(n)
    10         -		if n == stages then return 'starlit_tech:chem_lamp' end
    11         -		return string.format('starlit_tech:chem_lamp_%s',n)
            8  +	local function stID(n)
            9  +		if n == stages then return def.id end
           10  +		return string.format('%s_%s',def.id,n)
    12     11   	end
    13         -	local fab = starlit.type.fab {
    14         -		element = { carbon = 4, magnesium = 1 };
    15         -		cost = { power = 100 };
    16         -		flag = { print = true };
    17         -		time = { print = 5 };
    18         -	};
           12  +	local fab = def.fab
    19     13   	for i = stages, 0, -1 do
    20         -		minetest.register_node(chemLampID(i), {
    21         -			short_description = 'Chem Lamp';
           14  +		local grp = {
           15  +			object = 1;
           16  +			attached_node = 1;
           17  +		}
           18  +		if def.group then
           19  +			for k,v in pairs(def.group((i/stages))) do grp[k]=v end
           20  +		end
           21  +		minetest.register_node(stID(i), {
           22  +			short_description = def.name;
    22     23   			description = starlit.ui.tooltip {
    23         -				title = 'Chem Lamp';
    24         -				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.";
    25         -				color = lib.color(1,.4,.1);
           24  +				title = def.name;
           25  +				desc = def.desc;
           26  +				color = def.color;
    26     27   				props = {
    27         -					{title = 'Burn Remaining', desc=lib.math.timespec(stageTimeout * i), affinity=i > 4 and 'good' or 'bad'};
    28         -					{title = 'Mass', desc='10g', affinity='info'};
           28  +					{title = 'Burn Remaining', desc=lib.math.timespec(stageTimeout * i), affinity=i > (stages/2) and 'good' or 'bad'};
           29  +					{title = 'Mass', desc=lib.math.siUI('g', def.mass), affinity='info'};
    29     30   				};
    30     31   			};
    31     32   			drawtype = 'nodebox';
    32         -			groups = {
    33         -				object = 1;
    34         -				attached_node = 1;
    35         -			};
           33  +			groups = grp;
    36     34   			node_box = {
    37     35   				type = 'fixed';
    38     36   				fixed = {
    39         -					-.4, -.5, -.20;
    40         -					 .4, -.3,  .20;
           37  +					-(7/16), -.5,          -(4/16);
           38  +					 (7/16), -.5 + (2/16),  (4/16);
    41     39   				};
    42     40   			};
    43         -			tiles = {
    44         -				lib.image 'starlit-tech-lamp-glow.png'
    45         -					:fade(1 - i/stages)
    46         -					:blit(lib.image 'starlit-tech-lamp.png')
    47         -				:render();
    48         -			};
           41  +			tiles = def.tile((i/stages));
    49     42   			paramtype = 'light';
    50     43   			paramtype2 = 'wallmounted';
    51     44   			wallmounted_rotate_vertical = true;
    52         -			light_source = math.floor(lib.math.lerp(i/stages, 0, maxBright));
           45  +			light_source = math.floor(lib.math.lerp(i/stages, 0, def.glow));
    53     46   			on_construct = i ~= 0 and function(pos)
    54     47   				local t = minetest.get_node_timer(pos)
    55     48   				t:start(stageTimeout)
           49  +				if def.ctor then def.ctor(pos, (i/stages)) end
           50  +			end or nil;
           51  +			on_destruct = def.dtor and function(pos)
           52  +				def.dtor(pos, (i/stages))
    56     53   			end or nil;
    57     54   			on_timer = i ~= 0 and function(pos)
    58     55   				local me = minetest.get_node(pos)
    59         -				minetest.swap_node(pos, {name=chemLampID(i-1), param2=me.param2})
           56  +				minetest.swap_node(pos, {name=stID(i-1), param2=me.param2})
    60     57   				return i > 1
    61     58   			end or nil;
    62         -			_starlit = {
    63         -				mass = 10;
    64         -				reverseEngineer = {
    65         -					complexity = 1;
    66         -					sw = 'starlit_tech:schematic_chem_lamp';
    67         -				};
    68         -				recover = starlit.type.fab {
    69         -					element = {
    70         -						carbon = 8;
    71         -						magnesium = math.floor(lib.math.lerp(i/stages, 0, 2));
           59  +			_starlit = (function()
           60  +				local meta = {
           61  +					mass = def.mass;
           62  +					reverseEngineer = {
           63  +						complexity = 1;
           64  +						sw = def.id .. '_schematic';
           65  +					};
           66  +					recover = def.mat
           67  +					        + (def.fuel / (i/stages))
           68  +					        + starlit.type.fab {
           69  +						time = {
           70  +							shred = .5;
           71  +							shredPower = 2;
           72  +						};
    72     73   					};
    73         -					time = {
    74         -						shred = .5;
    75         -						shredPower = 2;
    76         -					};
    77         -				};
    78         -
    79         -			};
           74  +				}
           75  +				for k,v in pairs(def.meta and def.meta((i/stages)) or {}) do meta[k]=v end
           76  +				return meta
           77  +			end)();
    80     78   		})
    81     79   	end
    82         -	starlit.item.sw.link('starlit_tech:schematic_chem_lamp', {
    83         -		name = 'Chem Lamp Schematic';
           80  +	starlit.item.sw.link(def.id .. '_schematic', {
           81  +		name = def.name .. ' Schematic';
    84     82   		kind = 'schematic';
    85         -		input = fab;
    86         -		output = chemLampID(stages);
           83  +		input = def.fab + def.mat + def.fuel;
           84  +		output = stID(stages);
    87     85   		size = 32e6;
    88     86   		cost = {
    89     87   			cycles = 8e9;
    90     88   			ram = 16e6;
    91     89   		};
    92     90   		rarity = 1;
    93     91   	})
    94     92   end
    95     93   
           94  +
           95  +mkBurnDown {
           96  +	id = 'starlit_tech:chem_lamp';
           97  +	name = 'Chem Lamp';
           98  +	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.";
           99  +	stages = 12;
          100  +	glow = 12;
          101  +	time = 60*60;
          102  +	mass = 10;
          103  +	color = lib.color(1,.4,.1);
          104  +	tile = function(f) return {
          105  +		lib.image 'starlit-tech-lamp-glow.png'
          106  +			:fade(f)
          107  +			:blit(lib.image 'starlit-tech-lamp.png')
          108  +		:render();
          109  +	} end;
          110  +	fab = starlit.type.fab {
          111  +		cost = { power = 100 };
          112  +		flag = { print = true };
          113  +		time = { print = 5 };
          114  +	};
          115  +	mat  = starlit.type.fab { element = { carbon = 4 }; };
          116  +	fuel = starlit.type.fab { element = { magnesium = 1 }; };
          117  +}
          118  +
          119  +mkBurnDown {
          120  +	id = 'starlit_tech:chem_radiator';
          121  +	name = 'Chem Radiator';
          122  +	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.";
          123  +	stages = 12;
          124  +	glow = 7;
          125  +	time = 15*60;
          126  +	mass = 10;
          127  +	color = lib.color(1,.4,.1);
          128  +	tile = function(f) return {
          129  +		lib.image 'starlit-tech-lamp-glow.png'
          130  +			:fade(f)
          131  +			:blit(lib.image 'starlit-tech-lamp.png')
          132  +		:tint{hue=0,sat=1,lum=.5}:render();
          133  +	} end;
          134  +	fab = starlit.type.fab {
          135  +		cost = { power = 150 };
          136  +		flag = { print = true };
          137  +		time = { print = 10 };
          138  +	};
          139  +	mat  = starlit.type.fab { element = { carbon = 4 }; };
          140  +	fuel = starlit.type.fab { element = { magnesium = 2, iron = 2 }; };
          141  +	group = function(f)
          142  +		if f > 0
          143  +			then return {radiator=1}
          144  +			else return {}
          145  +		end
          146  +	end;
          147  +	ctor = function(pos, f) starlit.region.radiator.scan(pos) end;
          148  +	dtor = function(pos, f) starlit.region.radiator.unload(pos) end;
          149  +	meta = function(f) return {
          150  +		radiator = {
          151  +			radius = function(pos)
          152  +				return 2;
          153  +			end;
          154  +			radiate = function(rp, pos)
          155  +				return 15 * f
          156  +			end;
          157  +		};
          158  +	} end;
          159  +}
    96    160   
    97    161   minetest.register_node('starlit_tech:crate', {
    98    162   	short_description = 'Crate';
    99    163   	description = starlit.ui.tooltip {
   100    164   		title = 'Crate';
   101    165   		desc = 'A sturdy but lightweight storage crate woven from graphene.';
   102    166   		props = { {title='Mass', affinity='info', desc='100g'} };

Modified mods/starlit/init.lua from [df4ee2ddd8] to [44e70e86d4].

    61     61   
    62     62   	-- complex algorithms that cut across namespaces or don't belong anywhere else
    63     63   	alg = {};
    64     64   
    65     65   	region = {
    66     66   		radiator = {
    67     67   			store = AreaStore();
    68         -			emitters = {};
           68  +			sources = {};
    69     69   		};
    70     70   	};
    71     71   
    72     72   	-- standardized effects
    73     73   	fx = {};
    74     74   
    75     75   	type = {};
................................................................................
   218    218   	if not chunk then error(err) end
   219    219   	return chunk(...)
   220    220   end
   221    221   
   222    222   function starlit.include(name, ...) -- semantic variant used for loading modules
   223    223   	return starlit.evaluate(name..'.lua', ...)
   224    224   end
          225  +
          226  +function starlit.region.radiator.scan(pos,node)
          227  +	local R = starlit.region
          228  +	local phash = minetest.hash_node_position(pos)
          229  +	if R.radiator.sources[phash] then return end -- already loaded
          230  +	node = node or minetest.get_node(pos)
          231  +
          232  +	local def = minetest.registered_nodes[node.name]
          233  +	local cl = def._starlit and def._starlit.radiator
          234  +	if not cl then return nil end
          235  +	local min,max = cl.maxEffectArea and cl.maxEffectArea(pos) or nil
          236  +	if not min then
          237  +		assert(cl.radius, 'no radius callback for radiator')
          238  +		local r = cl.radius(pos)
          239  +		local vr = vector.new(r,r,r)
          240  +		min,max = pos-vr, pos+vr
          241  +	end
          242  +	local id = R.radiator.store:insert_area(min,max, minetest.pos_to_string(pos))
          243  +	R.radiator.sources[phash] = id
          244  +end
          245  +
          246  +function starlit.region.radiator.unload(pos)
          247  +	local R = starlit.region
          248  +	local phash = minetest.hash_node_position(pos)
          249  +	local id = R.radiator.sources[phash]
          250  +	R.radiator.store:remove_area(id)
          251  +	R.radiator.sources[phash] = nil
          252  +end
   225    253   
   226    254   minetest.register_lbm {
   227    255   	label = 'build radiator index';
   228    256   	name = 'starlit:loadradiatorboxes';
   229    257   	nodenames = {'group:radiator'};
   230    258   	run_at_every_load = true;
   231    259   	action = function(pos, node, dt)
   232         -		local R = starlit.region
   233         -		local phash = minetest.hash_node_position(pos)
   234         -		if R.radiator.sources[phash] then return end -- already loaded
   235         -
   236         -		local def = minetest.registered_nodes[node.name]
   237         -		local cl = def._starlit.radiator
   238         -		local min,max = cl.maxEffectArea(pos)
   239         -		local id = R.radiator.store:insert_area(min,max, minetest.pos_to_string(pos))
   240         -		R.radiator.sources[phash] = id
          260  +		starlit.region.radiator.scan(pos, node)
   241    261   	end;
   242    262   	-- NOTE: temp emitter nodes are responsible for decaching themselves in their on_destruct cb
   243    263   }
          264  +
   244    265   
   245    266   function starlit.startJob(id, interval, job)
   246    267   	local lastRun
   247    268   	local function start()
   248    269   		starlit.jobs[id] = minetest.after(interval, function()
   249    270   			local t = minetest.get_gametime()
   250    271   			local d = lastRun and t - lastRun or nil

Modified mods/starlit/user.lua from [1ac6a2a876] to [ae84fc4236].

   245    245   				text = def.tex;
   246    246   				scale = def.scale;
   247    247   				alignment = def.align;
   248    248   				position = def.pos;
   249    249   				offset = def.ofs;
   250    250   				z_index = def.z;
   251    251   			}
   252         -			if def.update then
   253         -				img.update = function()
   254         -					def.update(user, function(prop, val)
   255         -						user:hud_change(img.id, prop, val)
   256         -					end, def)
   257         -				end
          252  +			function img.chg(prop, val)
          253  +				user:hud_change(img.id, prop, val)
   258    254   			end
          255  +			img.update = def.update and function()
          256  +				def.update(user, img.chg, def)
          257  +			end or function() end
   259    258   			return img
   260    259   		end;
   261    260   		attachMeter = function(self, def)
   262    261   			local luser = self.entity
   263    262   			local m = {def = def}
   264    263   			local w = def.size or 80
   265    264   			local szf = w / 80
................................................................................
   528    527   			end
   529    528   			self:updateLEDs()
   530    529   		end;
   531    530   		updateLEDs = function(self)
   532    531   			local time = minetest.get_gametime()
   533    532   			local function updateSide(name, ofs, tx)
   534    533   				local del = {}
          534  +				local idx = 0
   535    535   				for i, l in ipairs(self.hud.led[name]) do
   536         -					local idx = 0
   537    536   					if time - l.origin > 3 then
   538    537   						if l.elt then self.entity:hud_remove(l.elt.id) end
   539    538   						self.hud.led.map[l.kind] = nil
   540    539   						table.insert(del, i)
   541    540   					else
   542         -						local xc = (idx*48 + 400)*ofs
          541  +						local xc = (idx*80 + 399)*ofs
   543    542   						if l.elt and next(del) then
   544         -							l.elt:update('offset', {x=xc, y=1})
          543  +							l.elt.chg('offset', {x=xc, y=1})
   545    544   						else
   546    545   							local tex = leds[l.kind].icon:blit(hudAdjustBacklight(leds[l.kind].bg))
   547    546   							if tx then tex = lib.image(tex:render()):transform(tx) end
   548    547   							if not l.elt then
   549    548   								l.elt = self:attachImage {
   550    549   									tex = tex:render();
   551    550   									align = {x=ofs, y=-1};
................................................................................
  1031   1030   
  1032   1031   			   if time - self.cooldownTimes.alarm > 1.5 then
  1033   1032   				   self.cooldownTimes.alarm = time
  1034   1033   				   self:suitSound(urg.sound)
  1035   1034   			   end
  1036   1035   		   end
  1037   1036   
  1038         -
  1039   1037   			local newLed = {
  1040   1038   				kind = kind;
  1041   1039   				origin = time;
  1042   1040   			}
  1043   1041   			self.hud.led.map[kind] = newLed
  1044   1042   			table.insert(self.hud.led[led.side], newLed)
  1045         -
  1046   1043   
  1047   1044   		   self:updateLEDs()
  1048   1045   
  1049   1046   		--[[
  1050   1047   			freq = freq or 3
  1051   1048   			local urgencies = {
  1052   1049   				[1] = {sound = 'starlit-alarm'};

Modified mods/vtlib/math.lua from [818384c4da] to [3e36361725].

     4      4   fn.vsep = function(vec) -- separate a vector into a direction + magnitude
     5      5   	return vec:normalize(), vec:length()
     6      6   end
     7      7   
     8      8   -- minetest now only provides the version of this function that sqrts the result
     9      9   -- which is pointlessly wasteful much of the time
    10     10   fn.vdsq = function(a,b)
    11         -	local d = vector.subtract(v1,v2)
           11  +	local d = vector.subtract(a,b)
    12     12   	return (d.x ^ 2) + (d.y ^ 2) + (d.z ^ 2)
    13     13   end
    14     14   
    15     15   fn.vdcomp = function(dist,v1,v2) -- compare the distance between two points
    16     16   	-- (cheaper than calculating distance outright)
    17     17   	local d if v2
    18     18   		then d = vector.subtract(v1,v2)