Compare commits
	
		
			32 Commits
		
	
	
		
			302a28934d
			...
			d356f901a3
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					d356f901a3 | ||
| 
						 | 
					6921909100 | ||
| 
						 | 
					3202bf6786 | ||
| 
						 | 
					fedbf49372 | ||
| 
						 | 
					9fda51b650 | ||
| 
						 | 
					4750925eab | ||
| 
						 | 
					16836b16d6 | ||
| 
						 | 
					c1eccba247 | ||
| 
						 | 
					01332a7ba1 | ||
| 
						 | 
					de4eeebd3b | ||
| 
						 | 
					75bd1e8be6 | ||
| 
						 | 
					95e6e2e4a5 | ||
| 
						 | 
					168a923665 | ||
| 
						 | 
					8dec053996 | ||
| 
						 | 
					e1cffdedbf | ||
| 
						 | 
					d3aedd2b98 | ||
| 
						 | 
					68c1729990 | ||
| 
						 | 
					9b58f8db29 | ||
| 
						 | 
					7784b13da5 | ||
| 
						 | 
					0dd530312b | ||
| 
						 | 
					e78bbd6f98 | ||
| 
						 | 
					bfd952b51a | ||
| 
						 | 
					b7873e8e02 | ||
| 
						 | 
					d6b2a39c99 | ||
| 
						 | 
					1b54011b68 | ||
| 
						 | 
					15e743629e | ||
| 
						 | 
					1bf862f932 | ||
| 
						 | 
					1a9704f184 | ||
| 
						 | 
					8baa789eb1 | ||
| 
						 | 
					b0158f5674 | ||
| 
						 | 
					073c92d487 | ||
| 
						 | 
					737f366741 | 
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						@@ -1 +1,3 @@
 | 
				
			|||||||
*~
 | 
					*~
 | 
				
			||||||
 | 
					*.patch
 | 
				
			||||||
 | 
					*.diff
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,96 +1,140 @@
 | 
				
			|||||||
mesecon.queue.actions={} -- contains all ActionQueue actions
 | 
					--[[
 | 
				
			||||||
 | 
					Mesecons uses something it calls an ActionQueue.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function mesecon.queue:add_function(name, func)
 | 
					The ActionQueue holds functions and actions.
 | 
				
			||||||
	mesecon.queue.funcs[name] = func
 | 
					Functions are added on load time with a specified name.
 | 
				
			||||||
 | 
					Actions are preserved over server restarts.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Each action consists of a position, the name of an added function to be called,
 | 
				
			||||||
 | 
					the params that should be used in this function call (additionally to the pos),
 | 
				
			||||||
 | 
					the time after which it should be executed, an optional overwritecheck and a
 | 
				
			||||||
 | 
					priority.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If time = 0, the action will be executed in the next globalstep, otherwise the
 | 
				
			||||||
 | 
					earliest globalstep when it will be executed is the after next globalstep.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					It is guaranteed, that for two actions ac1, ac2 where ac1 ~= ac2,
 | 
				
			||||||
 | 
					ac1.time == ac2.time, ac1.priority == ac2.priority and ac1 was added earlier
 | 
				
			||||||
 | 
					than ac2, ac1 will be executed before ac2 (but in the same globalstep).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Note: Do not pass references in params, as they can not be preserved.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Also note: Some of the guarantees here might be dropped at some time.
 | 
				
			||||||
 | 
					]]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-- localize for speed
 | 
				
			||||||
 | 
					local queue = mesecon.queue
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					queue.actions = {} -- contains all ActionQueue actions
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function queue:add_function(name, func)
 | 
				
			||||||
 | 
						queue.funcs[name] = func
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
-- If add_action with twice the same overwritecheck and same position are called, the first one is overwritten
 | 
					-- If add_action with twice the same overwritecheck and same position are called, the first one is overwritten
 | 
				
			||||||
-- use overwritecheck nil to never overwrite, but just add the event to the queue
 | 
					-- use overwritecheck nil to never overwrite, but just add the event to the queue
 | 
				
			||||||
-- priority specifies the order actions are executed within one globalstep, highest first
 | 
					-- priority specifies the order actions are executed within one globalstep, highest first
 | 
				
			||||||
-- should be between 0 and 1
 | 
					-- should be between 0 and 1
 | 
				
			||||||
function mesecon.queue:add_action(pos, func, params, time, overwritecheck, priority)
 | 
					function queue:add_action(pos, func, params, time, overwritecheck, priority)
 | 
				
			||||||
	-- Create Action Table:
 | 
						-- Create Action Table:
 | 
				
			||||||
	time = time or 0 -- time <= 0 --> execute, time > 0 --> wait time until execution
 | 
						time = time or 0 -- time <= 0 --> execute, time > 0 --> wait time until execution
 | 
				
			||||||
	priority = priority or 1
 | 
						priority = priority or 1
 | 
				
			||||||
	local action = {	pos=mesecon.tablecopy(pos),
 | 
						local action = {
 | 
				
			||||||
 | 
							pos = mesecon.tablecopy(pos),
 | 
				
			||||||
		func = func,
 | 
							func = func,
 | 
				
			||||||
		params = mesecon.tablecopy(params or {}),
 | 
							params = mesecon.tablecopy(params or {}),
 | 
				
			||||||
		time = time,
 | 
							time = time,
 | 
				
			||||||
		owcheck = (overwritecheck and mesecon.tablecopy(overwritecheck)) or nil,
 | 
							owcheck = (overwritecheck and mesecon.tablecopy(overwritecheck)) or nil,
 | 
				
			||||||
				priority=priority}
 | 
							priority = priority
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	local toremove = nil
 | 
						 -- check if old action has to be overwritten / removed:
 | 
				
			||||||
	-- Otherwise, add the action to the queue
 | 
						if overwritecheck then
 | 
				
			||||||
	if overwritecheck then -- check if old action has to be overwritten / removed:
 | 
							for i, ac in ipairs(queue.actions) do
 | 
				
			||||||
		for i, ac in ipairs(mesecon.queue.actions) do
 | 
								if vector.equals(pos, ac.pos)
 | 
				
			||||||
			if(vector.equals(pos, ac.pos)
 | 
										and mesecon.cmpAny(overwritecheck, ac.owcheck) then
 | 
				
			||||||
			and mesecon.cmpAny(overwritecheck, ac.owcheck)) then
 | 
									-- remove the old action
 | 
				
			||||||
				toremove = i
 | 
									table.remove(queue.actions, i)
 | 
				
			||||||
				break
 | 
									break
 | 
				
			||||||
			end
 | 
								end
 | 
				
			||||||
		end
 | 
							end
 | 
				
			||||||
	end
 | 
						end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (toremove ~= nil) then
 | 
						table.insert(queue.actions, action)
 | 
				
			||||||
		table.remove(mesecon.queue.actions, toremove)
 | 
					 | 
				
			||||||
	end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	table.insert(mesecon.queue.actions, action)
 | 
					 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
-- execute the stored functions on a globalstep
 | 
					-- execute the stored functions on a globalstep
 | 
				
			||||||
-- if however, the pos of a function is not loaded (get_node_or_nil == nil), do NOT execute the function
 | 
					-- if however, the pos of a function is not loaded (get_node_or_nil == nil), do NOT execute the function
 | 
				
			||||||
-- this makes sure that resuming mesecons circuits when restarting minetest works fine
 | 
					-- this makes sure that resuming mesecons circuits when restarting minetest works fine (hm, where do we do this?)
 | 
				
			||||||
-- However, even that does not work in some cases, that's why we delay the time the globalsteps
 | 
					-- However, even that does not work in some cases, that's why we delay the time the globalsteps
 | 
				
			||||||
-- start to be execute by 5 seconds
 | 
					-- start to be execute by 4 seconds
 | 
				
			||||||
local get_highest_priority = function (actions)
 | 
					 | 
				
			||||||
	local highestp = -1
 | 
					 | 
				
			||||||
	local highesti
 | 
					 | 
				
			||||||
	for i, ac in ipairs(actions) do
 | 
					 | 
				
			||||||
		if ac.priority > highestp then
 | 
					 | 
				
			||||||
			highestp = ac.priority
 | 
					 | 
				
			||||||
			highesti = i
 | 
					 | 
				
			||||||
		end
 | 
					 | 
				
			||||||
	end
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return highesti
 | 
					local function globalstep_func(dtime)
 | 
				
			||||||
end
 | 
						local actions = queue.actions
 | 
				
			||||||
 | 
						-- split into two categories:
 | 
				
			||||||
local m_time = 0
 | 
						-- actions_now: actions to execute now
 | 
				
			||||||
local resumetime = mesecon.setting("resumetime", 4)
 | 
						-- queue.actions: actions to execute later
 | 
				
			||||||
minetest.register_globalstep(function (dtime)
 | 
					 | 
				
			||||||
	m_time = m_time + dtime
 | 
					 | 
				
			||||||
	-- don't even try if server has not been running for XY seconds; resumetime = time to wait
 | 
					 | 
				
			||||||
	-- after starting the server before processing the ActionQueue, don't set this too low
 | 
					 | 
				
			||||||
	if (m_time < resumetime) then return end
 | 
					 | 
				
			||||||
	local actions = mesecon.tablecopy(mesecon.queue.actions)
 | 
					 | 
				
			||||||
	local actions_now = {}
 | 
						local actions_now = {}
 | 
				
			||||||
 | 
						queue.actions = {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mesecon.queue.actions = {}
 | 
						for _, ac in ipairs(actions) do
 | 
				
			||||||
 | 
					 | 
				
			||||||
	-- sort actions into two categories:
 | 
					 | 
				
			||||||
	-- those toexecute now (actions_now) and those to execute later (mesecon.queue.actions)
 | 
					 | 
				
			||||||
	for i, ac in ipairs(actions) do
 | 
					 | 
				
			||||||
		if ac.time > 0 then
 | 
							if ac.time > 0 then
 | 
				
			||||||
			ac.time = ac.time - dtime -- executed later
 | 
								-- action ac is to be executed later
 | 
				
			||||||
			table.insert(mesecon.queue.actions, ac)
 | 
								-- ~> insert into queue.actions
 | 
				
			||||||
 | 
								ac.time = ac.time - dtime
 | 
				
			||||||
 | 
								table.insert(queue.actions, ac)
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
 | 
								-- action ac is to be executed now
 | 
				
			||||||
 | 
								-- ~> insert into actions_now
 | 
				
			||||||
			table.insert(actions_now, ac)
 | 
								table.insert(actions_now, ac)
 | 
				
			||||||
		end
 | 
							end
 | 
				
			||||||
	end
 | 
						end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	while(#actions_now > 0) do -- execute highest priorities first, until all are executed
 | 
						-- stable-sort the executed actions after their priority
 | 
				
			||||||
		local hp = get_highest_priority(actions_now)
 | 
						-- some constructions might depend on the execution order, hence we first
 | 
				
			||||||
		mesecon.queue:execute(actions_now[hp])
 | 
						-- execute the actions that had a lower index in actions_now
 | 
				
			||||||
		table.remove(actions_now, hp)
 | 
						local old_action_order = {}
 | 
				
			||||||
 | 
						for i, ac in ipairs(actions_now) do
 | 
				
			||||||
 | 
							old_action_order[ac] = i
 | 
				
			||||||
 | 
						end
 | 
				
			||||||
 | 
						table.sort(actions_now, function(ac1, ac2)
 | 
				
			||||||
 | 
							if ac1.priority ~= ac2.priority then
 | 
				
			||||||
 | 
								return ac1.priority > ac2.priority
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
 | 
								return old_action_order[ac1] < old_action_order[ac2]
 | 
				
			||||||
		end
 | 
							end
 | 
				
			||||||
	end)
 | 
						end)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function mesecon.queue:execute(action)
 | 
						-- execute highest priorities first, until all are executed
 | 
				
			||||||
 | 
						for _, ac in ipairs(actions_now) do
 | 
				
			||||||
 | 
							queue:execute(ac)
 | 
				
			||||||
 | 
						end
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-- delay the time the globalsteps start to be execute by 4 seconds
 | 
				
			||||||
 | 
					do
 | 
				
			||||||
 | 
						local m_time = 0
 | 
				
			||||||
 | 
						local resumetime = mesecon.setting("resumetime", 4)
 | 
				
			||||||
 | 
						local globalstep_func_index = #minetest.registered_globalsteps + 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						minetest.register_globalstep(function(dtime)
 | 
				
			||||||
 | 
							m_time = m_time + dtime
 | 
				
			||||||
 | 
							-- don't even try if server has not been running for XY seconds; resumetime = time to wait
 | 
				
			||||||
 | 
							-- after starting the server before processing the ActionQueue, don't set this too low
 | 
				
			||||||
 | 
							if m_time < resumetime then
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							end
 | 
				
			||||||
 | 
							-- replace this globalstep function
 | 
				
			||||||
 | 
							minetest.registered_globalsteps[globalstep_func_index] = globalstep_func
 | 
				
			||||||
 | 
						end)
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function queue:execute(action)
 | 
				
			||||||
	-- ignore if action queue function name doesn't exist,
 | 
						-- ignore if action queue function name doesn't exist,
 | 
				
			||||||
	-- (e.g. in case the action queue savegame was written by an old mesecons version)
 | 
						-- (e.g. in case the action queue savegame was written by an old mesecons version)
 | 
				
			||||||
	if mesecon.queue.funcs[action.func] then
 | 
						if queue.funcs[action.func] then
 | 
				
			||||||
		mesecon.queue.funcs[action.func](action.pos, unpack(action.params))
 | 
							queue.funcs[action.func](action.pos, unpack(action.params))
 | 
				
			||||||
	end
 | 
						end
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -98,8 +142,8 @@ end
 | 
				
			|||||||
-- Store and read the ActionQueue to / from a file
 | 
					-- Store and read the ActionQueue to / from a file
 | 
				
			||||||
-- so that upcoming actions are remembered when the game
 | 
					-- so that upcoming actions are remembered when the game
 | 
				
			||||||
-- is restarted
 | 
					-- is restarted
 | 
				
			||||||
mesecon.queue.actions = mesecon.file2table("mesecon_actionqueue")
 | 
					queue.actions = mesecon.file2table("mesecon_actionqueue")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
minetest.register_on_shutdown(function()
 | 
					minetest.register_on_shutdown(function()
 | 
				
			||||||
	mesecon.table2file("mesecon_actionqueue", mesecon.queue.actions)
 | 
						mesecon.table2file("mesecon_actionqueue", queue.actions)
 | 
				
			||||||
end)
 | 
					end)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1 +0,0 @@
 | 
				
			|||||||
default
 | 
					 | 
				
			||||||
							
								
								
									
										2
									
								
								mesecons/mod.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,2 @@
 | 
				
			|||||||
 | 
					name = mesecons
 | 
				
			||||||
 | 
					depends = default
 | 
				
			||||||
| 
		 Before Width: | Height: | Size: 323 B After Width: | Height: | Size: 191 B  | 
| 
		 Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 844 B  | 
| 
		 Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 838 B  | 
| 
		 Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 851 B  | 
| 
		 Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 846 B  | 
| 
		 Before Width: | Height: | Size: 550 B After Width: | Height: | Size: 222 B  | 
| 
		 Before Width: | Height: | Size: 613 B After Width: | Height: | Size: 504 B  | 
| 
		 Before Width: | Height: | Size: 204 B After Width: | Height: | Size: 144 B  | 
| 
		 Before Width: | Height: | Size: 465 B After Width: | Height: | Size: 377 B  | 
| 
		 Before Width: | Height: | Size: 464 B After Width: | Height: | Size: 362 B  | 
@@ -186,29 +186,30 @@ function mesecon.invertRule(r)
 | 
				
			|||||||
	return vector.multiply(r, -1)
 | 
						return vector.multiply(r, -1)
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function mesecon.tablecopy(table) -- deep table copy
 | 
					function mesecon.tablecopy(obj) -- deep copy
 | 
				
			||||||
	if type(table) ~= "table" then return table end -- no need to copy
 | 
						if type(obj) == "table" then
 | 
				
			||||||
	local newtable = {}
 | 
							return table.copy(obj)
 | 
				
			||||||
 | 
					 | 
				
			||||||
	for idx, item in pairs(table) do
 | 
					 | 
				
			||||||
		if type(item) == "table" then
 | 
					 | 
				
			||||||
			newtable[idx] = mesecon.tablecopy(item)
 | 
					 | 
				
			||||||
		else
 | 
					 | 
				
			||||||
			newtable[idx] = item
 | 
					 | 
				
			||||||
	end
 | 
						end
 | 
				
			||||||
 | 
						return obj
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return newtable
 | 
					-- Returns whether two values are equal.
 | 
				
			||||||
end
 | 
					-- In tables, keys are compared for identity but values are compared recursively.
 | 
				
			||||||
 | 
					-- There is no protection from infinite recursion.
 | 
				
			||||||
function mesecon.cmpAny(t1, t2)
 | 
					function mesecon.cmpAny(t1, t2)
 | 
				
			||||||
	if type(t1) ~= type(t2) then return false end
 | 
						if type(t1) ~= type(t2) then return false end
 | 
				
			||||||
	if type(t1) ~= "table" and type(t2) ~= "table" then return t1 == t2 end
 | 
						if type(t1) ~= "table" then return t1 == t2 end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						-- Check that for each key of `t1` both tables have the same value
 | 
				
			||||||
	for i, e in pairs(t1) do
 | 
						for i, e in pairs(t1) do
 | 
				
			||||||
		if not mesecon.cmpAny(e, t2[i]) then return false end
 | 
							if not mesecon.cmpAny(e, t2[i]) then return false end
 | 
				
			||||||
	end
 | 
						end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						-- Check that all keys of `t2` are also keys of `t1` so were checked in the previous loop
 | 
				
			||||||
 | 
						for i, _ in pairs(t2) do
 | 
				
			||||||
 | 
							if t1[i] == nil then return false end
 | 
				
			||||||
 | 
						end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return true
 | 
						return true
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1 +0,0 @@
 | 
				
			|||||||
mesecons
 | 
					 | 
				
			||||||
							
								
								
									
										2
									
								
								mesecons_alias/mod.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,2 @@
 | 
				
			|||||||
 | 
					name = mesecons_alias
 | 
				
			||||||
 | 
					depends = mesecons
 | 
				
			||||||
@@ -1 +0,0 @@
 | 
				
			|||||||
mesecons
 | 
					 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								mesecons_blinkyplant/doc/blinkyplant/preview.png
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							
							
						
						| 
		 Before Width: | Height: | Size: 65 KiB After Width: | Height: | Size: 54 KiB  | 
| 
		 Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 1.7 KiB  | 
							
								
								
									
										2
									
								
								mesecons_blinkyplant/mod.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,2 @@
 | 
				
			|||||||
 | 
					name = mesecons_blinkyplant
 | 
				
			||||||
 | 
					depends = mesecons
 | 
				
			||||||
| 
		 Before Width: | Height: | Size: 454 B After Width: | Height: | Size: 367 B  | 
| 
		 Before Width: | Height: | Size: 463 B After Width: | Height: | Size: 394 B  | 
@@ -1,2 +0,0 @@
 | 
				
			|||||||
mesecons
 | 
					 | 
				
			||||||
mesecons_receiver
 | 
					 | 
				
			||||||
| 
		 Before Width: | Height: | Size: 78 KiB After Width: | Height: | Size: 68 KiB  | 
| 
		 Before Width: | Height: | Size: 7.8 KiB After Width: | Height: | Size: 4.3 KiB  | 
@@ -8,7 +8,7 @@ mesecon.button_turnoff = function (pos)
 | 
				
			|||||||
		return
 | 
							return
 | 
				
			||||||
	end
 | 
						end
 | 
				
			||||||
	minetest.swap_node(pos, {name = "mesecons_button:button_off", param2 = node.param2})
 | 
						minetest.swap_node(pos, {name = "mesecons_button:button_off", param2 = node.param2})
 | 
				
			||||||
	minetest.sound_play("mesecons_button_pop", {pos = pos})
 | 
						minetest.sound_play("mesecons_button_pop", { pos = pos }, true)
 | 
				
			||||||
	local rules = mesecon.rules.buttonlike_get(node)
 | 
						local rules = mesecon.rules.buttonlike_get(node)
 | 
				
			||||||
	mesecon.receptor_off(pos, rules)
 | 
						mesecon.receptor_off(pos, rules)
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
@@ -46,7 +46,7 @@ minetest.register_node("mesecons_button:button_off", {
 | 
				
			|||||||
	on_rightclick = function (pos, node)
 | 
						on_rightclick = function (pos, node)
 | 
				
			||||||
		minetest.swap_node(pos, {name = "mesecons_button:button_on", param2=node.param2})
 | 
							minetest.swap_node(pos, {name = "mesecons_button:button_on", param2=node.param2})
 | 
				
			||||||
		mesecon.receptor_on(pos, mesecon.rules.buttonlike_get(node))
 | 
							mesecon.receptor_on(pos, mesecon.rules.buttonlike_get(node))
 | 
				
			||||||
		minetest.sound_play("mesecons_button_push", {pos=pos})
 | 
							minetest.sound_play("mesecons_button_push", { pos = pos }, true)
 | 
				
			||||||
		minetest.get_node_timer(pos):start(1)
 | 
							minetest.get_node_timer(pos):start(1)
 | 
				
			||||||
	end,
 | 
						end,
 | 
				
			||||||
	sounds = default.node_sound_stone_defaults(),
 | 
						sounds = default.node_sound_stone_defaults(),
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								mesecons_button/mod.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,2 @@
 | 
				
			|||||||
 | 
					name = mesecons_button
 | 
				
			||||||
 | 
					depends = mesecons, mesecons_receiver
 | 
				
			||||||
| 
		 Before Width: | Height: | Size: 411 B After Width: | Height: | Size: 371 B  | 
| 
		 Before Width: | Height: | Size: 449 B After Width: | Height: | Size: 409 B  | 
| 
		 Before Width: | Height: | Size: 434 B After Width: | Height: | Size: 220 B  | 
@@ -1 +0,0 @@
 | 
				
			|||||||
mesecons
 | 
					 | 
				
			||||||
| 
		 Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 33 KiB  | 
@@ -110,7 +110,7 @@ local function resolve_commands(commands, pos)
 | 
				
			|||||||
	local nearest, farthest = nil, nil
 | 
						local nearest, farthest = nil, nil
 | 
				
			||||||
	local min_distance, max_distance = math.huge, -1
 | 
						local min_distance, max_distance = math.huge, -1
 | 
				
			||||||
	for index, player in pairs(players) do
 | 
						for index, player in pairs(players) do
 | 
				
			||||||
		local distance = vector.distance(pos, player:getpos())
 | 
							local distance = vector.distance(pos, player:get_pos())
 | 
				
			||||||
		if distance < min_distance then
 | 
							if distance < min_distance then
 | 
				
			||||||
			min_distance = distance
 | 
								min_distance = distance
 | 
				
			||||||
			nearest = player:get_player_name()
 | 
								nearest = player:get_player_name()
 | 
				
			||||||
@@ -174,7 +174,8 @@ end
 | 
				
			|||||||
local function can_dig(pos, player)
 | 
					local function can_dig(pos, player)
 | 
				
			||||||
	local meta = minetest.get_meta(pos)
 | 
						local meta = minetest.get_meta(pos)
 | 
				
			||||||
	local owner = meta:get_string("owner")
 | 
						local owner = meta:get_string("owner")
 | 
				
			||||||
	return owner == "" or owner == player:get_player_name()
 | 
						return owner == "" or owner == player:get_player_name() or
 | 
				
			||||||
 | 
							minetest.check_player_privs(player, "protection_bypass")
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
minetest.register_node("mesecons_commandblock:commandblock_off", {
 | 
					minetest.register_node("mesecons_commandblock:commandblock_off", {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								mesecons_commandblock/mod.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,2 @@
 | 
				
			|||||||
 | 
					name = mesecons_commandblock
 | 
				
			||||||
 | 
					depends = mesecons
 | 
				
			||||||
| 
		 Before Width: | Height: | Size: 282 B After Width: | Height: | Size: 183 B  | 
| 
		 Before Width: | Height: | Size: 278 B After Width: | Height: | Size: 183 B  | 
@@ -1 +0,0 @@
 | 
				
			|||||||
mesecons
 | 
					 | 
				
			||||||
| 
		 Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 50 KiB  | 
| 
		 Before Width: | Height: | Size: 8.3 KiB After Width: | Height: | Size: 4.2 KiB  | 
@@ -33,19 +33,9 @@ end
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
-- Register the 2 (states) x 4 (delay times) delayers
 | 
					-- Register the 2 (states) x 4 (delay times) delayers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
for i = 1, 4 do
 | 
					local delaytime = { 0.1, 0.3, 0.5, 1.0 }
 | 
				
			||||||
local groups = {}
 | 
					 | 
				
			||||||
if i == 1 then
 | 
					 | 
				
			||||||
	groups = {bendy=2,snappy=1,dig_immediate=2}
 | 
					 | 
				
			||||||
else
 | 
					 | 
				
			||||||
	groups = {bendy=2,snappy=1,dig_immediate=2, not_in_creative_inventory=1}
 | 
					 | 
				
			||||||
end
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
local delaytime
 | 
					for i = 1, 4 do
 | 
				
			||||||
if 		i == 1 then delaytime = 0.1
 | 
					 | 
				
			||||||
elseif	i == 2 then delaytime = 0.3
 | 
					 | 
				
			||||||
elseif	i == 3 then delaytime = 0.5
 | 
					 | 
				
			||||||
elseif	i == 4 then delaytime = 1.0 end
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
local boxes = {
 | 
					local boxes = {
 | 
				
			||||||
	 { -6/16, -8/16, -6/16, 6/16, -7/16, 6/16 },		-- the main slab
 | 
						 { -6/16, -8/16, -6/16, 6/16, -7/16, 6/16 },		-- the main slab
 | 
				
			||||||
@@ -61,9 +51,36 @@ local boxes = {
 | 
				
			|||||||
	 { 6/16, -8/16, -1/16, 8/16, -7/16, 1/16 }
 | 
						 { 6/16, -8/16, -1/16, 8/16, -7/16, 1/16 }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
minetest.register_node("mesecons_delayer:delayer_off_"..tostring(i), {
 | 
					-- Delayer definition defaults
 | 
				
			||||||
	description = "Delayer",
 | 
					local def = {
 | 
				
			||||||
	drawtype = "nodebox",
 | 
						drawtype = "nodebox",
 | 
				
			||||||
 | 
						walkable = true,
 | 
				
			||||||
 | 
						selection_box = {
 | 
				
			||||||
 | 
							type = "fixed",
 | 
				
			||||||
 | 
							fixed = { -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 },
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						node_box = {
 | 
				
			||||||
 | 
							type = "fixed",
 | 
				
			||||||
 | 
							fixed = boxes
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						paramtype = "light",
 | 
				
			||||||
 | 
						paramtype2 = "facedir",
 | 
				
			||||||
 | 
						sunlight_propagates = true,
 | 
				
			||||||
 | 
						is_ground_content = false,
 | 
				
			||||||
 | 
						delayer_time = delaytime[i],
 | 
				
			||||||
 | 
						sounds = default.node_sound_stone_defaults(),
 | 
				
			||||||
 | 
						on_blast = mesecon.on_blastnode,
 | 
				
			||||||
 | 
						drop = "mesecons_delayer:delayer_off_1",
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-- Deactivated delayer definition defaults
 | 
				
			||||||
 | 
					local off_groups = {bendy=2,snappy=1,dig_immediate=2}
 | 
				
			||||||
 | 
					if i > 1 then
 | 
				
			||||||
 | 
						off_groups.not_in_creative_inventory = 1
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					local off_state = {
 | 
				
			||||||
 | 
						description = "Delayer",
 | 
				
			||||||
	tiles = {
 | 
						tiles = {
 | 
				
			||||||
		"mesecons_delayer_off_"..tostring(i)..".png",
 | 
							"mesecons_delayer_off_"..tostring(i)..".png",
 | 
				
			||||||
		"mesecons_delayer_bottom.png",
 | 
							"mesecons_delayer_bottom.png",
 | 
				
			||||||
@@ -74,35 +91,18 @@ minetest.register_node("mesecons_delayer:delayer_off_"..tostring(i), {
 | 
				
			|||||||
	},
 | 
						},
 | 
				
			||||||
	inventory_image = "mesecons_delayer_off_1.png",
 | 
						inventory_image = "mesecons_delayer_off_1.png",
 | 
				
			||||||
	wield_image = "mesecons_delayer_off_1.png",
 | 
						wield_image = "mesecons_delayer_off_1.png",
 | 
				
			||||||
	walkable = true,
 | 
						groups = off_groups,
 | 
				
			||||||
	selection_box = {
 | 
						on_punch = function(pos, node, puncher)
 | 
				
			||||||
		type = "fixed",
 | 
							if minetest.is_protected(pos, puncher and puncher:get_player_name()) then
 | 
				
			||||||
		fixed = { -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 },
 | 
								return
 | 
				
			||||||
	},
 | 
					 | 
				
			||||||
	node_box = {
 | 
					 | 
				
			||||||
		type = "fixed",
 | 
					 | 
				
			||||||
		fixed = boxes
 | 
					 | 
				
			||||||
	},
 | 
					 | 
				
			||||||
	groups = groups,
 | 
					 | 
				
			||||||
	paramtype = "light",
 | 
					 | 
				
			||||||
	paramtype2 = "facedir",
 | 
					 | 
				
			||||||
	sunlight_propagates = true,
 | 
					 | 
				
			||||||
	is_ground_content = false,
 | 
					 | 
				
			||||||
	drop = 'mesecons_delayer:delayer_off_1',
 | 
					 | 
				
			||||||
	on_punch = function (pos, node)
 | 
					 | 
				
			||||||
		if node.name=="mesecons_delayer:delayer_off_1" then
 | 
					 | 
				
			||||||
			minetest.swap_node(pos, {name = "mesecons_delayer:delayer_off_2", param2=node.param2})
 | 
					 | 
				
			||||||
		elseif node.name=="mesecons_delayer:delayer_off_2" then
 | 
					 | 
				
			||||||
			minetest.swap_node(pos, {name = "mesecons_delayer:delayer_off_3", param2=node.param2})
 | 
					 | 
				
			||||||
		elseif node.name=="mesecons_delayer:delayer_off_3" then
 | 
					 | 
				
			||||||
			minetest.swap_node(pos, {name = "mesecons_delayer:delayer_off_4", param2=node.param2})
 | 
					 | 
				
			||||||
		elseif node.name=="mesecons_delayer:delayer_off_4" then
 | 
					 | 
				
			||||||
			minetest.swap_node(pos, {name = "mesecons_delayer:delayer_off_1", param2=node.param2})
 | 
					 | 
				
			||||||
		end
 | 
							end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							minetest.swap_node(pos, {
 | 
				
			||||||
 | 
								name = "mesecons_delayer:delayer_off_"..tostring(i % 4 + 1),
 | 
				
			||||||
 | 
								param2 = node.param2
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
	end,
 | 
						end,
 | 
				
			||||||
	delayer_time = delaytime,
 | 
					 | 
				
			||||||
	delayer_onstate = "mesecons_delayer:delayer_on_"..tostring(i),
 | 
						delayer_onstate = "mesecons_delayer:delayer_on_"..tostring(i),
 | 
				
			||||||
	sounds = default.node_sound_stone_defaults(),
 | 
					 | 
				
			||||||
	mesecons = {
 | 
						mesecons = {
 | 
				
			||||||
		receptor =
 | 
							receptor =
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
@@ -115,13 +115,15 @@ minetest.register_node("mesecons_delayer:delayer_off_"..tostring(i), {
 | 
				
			|||||||
			action_on = delayer_activate
 | 
								action_on = delayer_activate
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	on_blast = mesecon.on_blastnode,
 | 
					}
 | 
				
			||||||
})
 | 
					for k, v in pairs(def) do
 | 
				
			||||||
 | 
						off_state[k] = off_state[k] or v
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					minetest.register_node("mesecons_delayer:delayer_off_"..tostring(i), off_state)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-- Activated delayer definition defaults
 | 
				
			||||||
minetest.register_node("mesecons_delayer:delayer_on_"..tostring(i), {
 | 
					local on_state = {
 | 
				
			||||||
	description = "You hacker you",
 | 
						description = "You hacker you",
 | 
				
			||||||
	drawtype = "nodebox",
 | 
					 | 
				
			||||||
	tiles = {
 | 
						tiles = {
 | 
				
			||||||
		"mesecons_delayer_on_"..tostring(i)..".png",
 | 
							"mesecons_delayer_on_"..tostring(i)..".png",
 | 
				
			||||||
		"mesecons_delayer_bottom.png",
 | 
							"mesecons_delayer_bottom.png",
 | 
				
			||||||
@@ -130,35 +132,18 @@ minetest.register_node("mesecons_delayer:delayer_on_"..tostring(i), {
 | 
				
			|||||||
		"mesecons_delayer_sides_on.png",
 | 
							"mesecons_delayer_sides_on.png",
 | 
				
			||||||
		"mesecons_delayer_sides_on.png"
 | 
							"mesecons_delayer_sides_on.png"
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	walkable = true,
 | 
					 | 
				
			||||||
	selection_box = {
 | 
					 | 
				
			||||||
		type = "fixed",
 | 
					 | 
				
			||||||
		fixed = { -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 },
 | 
					 | 
				
			||||||
	},
 | 
					 | 
				
			||||||
	node_box = {
 | 
					 | 
				
			||||||
		type = "fixed",
 | 
					 | 
				
			||||||
		fixed = boxes
 | 
					 | 
				
			||||||
	},
 | 
					 | 
				
			||||||
	groups = {bendy = 2, snappy = 1, dig_immediate = 2, not_in_creative_inventory = 1},
 | 
						groups = {bendy = 2, snappy = 1, dig_immediate = 2, not_in_creative_inventory = 1},
 | 
				
			||||||
	paramtype = "light",
 | 
						on_punch = function(pos, node, puncher)
 | 
				
			||||||
	paramtype2 = "facedir",
 | 
							if minetest.is_protected(pos, puncher and puncher:get_player_name()) then
 | 
				
			||||||
	sunlight_propagates = true,
 | 
								return
 | 
				
			||||||
	is_ground_content = false,
 | 
					 | 
				
			||||||
	drop = 'mesecons_delayer:delayer_off_1',
 | 
					 | 
				
			||||||
	on_punch = function (pos, node)
 | 
					 | 
				
			||||||
		if node.name=="mesecons_delayer:delayer_on_1" then
 | 
					 | 
				
			||||||
			minetest.swap_node(pos, {name = "mesecons_delayer:delayer_on_2", param2=node.param2})
 | 
					 | 
				
			||||||
		elseif node.name=="mesecons_delayer:delayer_on_2" then
 | 
					 | 
				
			||||||
			minetest.swap_node(pos, {name = "mesecons_delayer:delayer_on_3", param2=node.param2})
 | 
					 | 
				
			||||||
		elseif node.name=="mesecons_delayer:delayer_on_3" then
 | 
					 | 
				
			||||||
			minetest.swap_node(pos, {name = "mesecons_delayer:delayer_on_4", param2=node.param2})
 | 
					 | 
				
			||||||
		elseif node.name=="mesecons_delayer:delayer_on_4" then
 | 
					 | 
				
			||||||
			minetest.swap_node(pos, {name = "mesecons_delayer:delayer_on_1", param2=node.param2})
 | 
					 | 
				
			||||||
		end
 | 
							end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							minetest.swap_node(pos, {
 | 
				
			||||||
 | 
								name = "mesecons_delayer:delayer_on_"..tostring(i % 4 + 1),
 | 
				
			||||||
 | 
								param2 = node.param2
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
	end,
 | 
						end,
 | 
				
			||||||
	delayer_time = delaytime,
 | 
					 | 
				
			||||||
	delayer_offstate = "mesecons_delayer:delayer_off_"..tostring(i),
 | 
						delayer_offstate = "mesecons_delayer:delayer_off_"..tostring(i),
 | 
				
			||||||
	sounds = default.node_sound_stone_defaults(),
 | 
					 | 
				
			||||||
	mesecons = {
 | 
						mesecons = {
 | 
				
			||||||
		receptor =
 | 
							receptor =
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
@@ -171,8 +156,12 @@ minetest.register_node("mesecons_delayer:delayer_on_"..tostring(i), {
 | 
				
			|||||||
			action_off = delayer_deactivate
 | 
								action_off = delayer_deactivate
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	on_blast = mesecon.on_blastnode,
 | 
					}
 | 
				
			||||||
})
 | 
					for k, v in pairs(def) do
 | 
				
			||||||
 | 
						on_state[k] = on_state[k] or v
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					minetest.register_node("mesecons_delayer:delayer_on_"..tostring(i), on_state)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
minetest.register_craft({
 | 
					minetest.register_craft({
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								mesecons_delayer/mod.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,2 @@
 | 
				
			|||||||
 | 
					name = mesecons_delayer
 | 
				
			||||||
 | 
					depends = mesecons
 | 
				
			||||||
| 
		 Before Width: | Height: | Size: 438 B After Width: | Height: | Size: 221 B  | 
| 
		 Before Width: | Height: | Size: 226 B After Width: | Height: | Size: 176 B  | 
| 
		 Before Width: | Height: | Size: 228 B After Width: | Height: | Size: 187 B  | 
| 
		 Before Width: | Height: | Size: 562 B After Width: | Height: | Size: 448 B  | 
| 
		 Before Width: | Height: | Size: 558 B After Width: | Height: | Size: 449 B  | 
| 
		 Before Width: | Height: | Size: 561 B After Width: | Height: | Size: 448 B  | 
| 
		 Before Width: | Height: | Size: 556 B After Width: | Height: | Size: 446 B  | 
| 
		 Before Width: | Height: | Size: 635 B After Width: | Height: | Size: 541 B  | 
| 
		 Before Width: | Height: | Size: 632 B After Width: | Height: | Size: 541 B  | 
| 
		 Before Width: | Height: | Size: 635 B After Width: | Height: | Size: 541 B  | 
| 
		 Before Width: | Height: | Size: 630 B After Width: | Height: | Size: 538 B  | 
| 
		 Before Width: | Height: | Size: 229 B After Width: | Height: | Size: 173 B  | 
| 
		 Before Width: | Height: | Size: 234 B After Width: | Height: | Size: 181 B  | 
@@ -1,2 +0,0 @@
 | 
				
			|||||||
mesecons
 | 
					 | 
				
			||||||
mesecons_materials
 | 
					 | 
				
			||||||
@@ -1,8 +1,11 @@
 | 
				
			|||||||
The node detector is a receptor. It changes its state when either any node
 | 
					The node detector is a receptor. It changes its state when either any node
 | 
				
			||||||
or a specific node is detected. Right-click it to set a nodename to scan for.
 | 
					or a specific node is detected. Right-click it to set a nodename to scan for.
 | 
				
			||||||
It can also receive digiline signals. You can either send "GET" and it will
 | 
					It can also receive digiline signals. For example, you can send
 | 
				
			||||||
respond with the detected nodename or you can send any other string and it will
 | 
					<code>{distance=4, scanname="default:dirt"}</code>
 | 
				
			||||||
set this string as the node to scan for.
 | 
					to set distance to 4 and scan for dirt. You can omit either parameter.
 | 
				
			||||||
 | 
					There is also a command parameter: <code>{command="get"}</code> will respond
 | 
				
			||||||
 | 
					with the detected nodename and <code>{command="scan"}</code> will respond with
 | 
				
			||||||
 | 
					a boolean using the distance and nodename of the detector.
 | 
				
			||||||
Nodenames must include the mod they reside in, so for instance default:dirt, not just dirt.
 | 
					Nodenames must include the mod they reside in, so for instance default:dirt, not just dirt.
 | 
				
			||||||
The distance parameter specifies how many blocks are between the node detector and the node to detect.
 | 
					The distance parameter specifies how many blocks are between the node detector and the node to detect.
 | 
				
			||||||
Automatic scanning with Mesecons output only works when the detector is in an active block, but Digilines queries always work.
 | 
					Automatic scanning with Mesecons output only works when the detector is in an active block, but Digilines queries always work.
 | 
				
			||||||
 
 | 
				
			|||||||
| 
		 Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 43 KiB  | 
| 
		 Before Width: | Height: | Size: 9.8 KiB After Width: | Height: | Size: 7.3 KiB  | 
| 
		 Before Width: | Height: | Size: 84 KiB After Width: | Height: | Size: 78 KiB  | 
| 
		 Before Width: | Height: | Size: 9.6 KiB After Width: | Height: | Size: 7.1 KiB  | 
@@ -189,36 +189,57 @@ local function node_detector_scan(pos)
 | 
				
			|||||||
		(frontname ~= "air" and frontname ~= "ignore" and scanname == "")
 | 
							(frontname ~= "air" and frontname ~= "ignore" and scanname == "")
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					local function node_detector_send_node_name(pos, node, channel, meta)
 | 
				
			||||||
 | 
						local distance = meta:get_int("distance")
 | 
				
			||||||
 | 
						local distance_max = mesecon.setting("node_detector_distance_max", 10)
 | 
				
			||||||
 | 
						if distance < 0 then distance = 0 end
 | 
				
			||||||
 | 
						if distance > distance_max then distance = distance_max end
 | 
				
			||||||
 | 
						local nodename = minetest.get_node(
 | 
				
			||||||
 | 
							vector.subtract(pos, vector.multiply(minetest.facedir_to_dir(node.param2), distance + 1))
 | 
				
			||||||
 | 
						).name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						digiline:receptor_send(pos, digiline.rules.default, channel, nodename)
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
-- set player name when receiving a digiline signal on a specific channel
 | 
					-- set player name when receiving a digiline signal on a specific channel
 | 
				
			||||||
local node_detector_digiline = {
 | 
					local node_detector_digiline = {
 | 
				
			||||||
	effector = {
 | 
						effector = {
 | 
				
			||||||
		action = function(pos, node, channel, msg)
 | 
							action = function(pos, node, channel, msg)
 | 
				
			||||||
			local meta = minetest.get_meta(pos)
 | 
								local meta = minetest.get_meta(pos)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			local distance = meta:get_int("distance")
 | 
					 | 
				
			||||||
			local distance_max = mesecon.setting("node_detector_distance_max", 10)
 | 
					 | 
				
			||||||
			if distance < 0 then distance = 0 end
 | 
					 | 
				
			||||||
			if distance > distance_max then distance = distance_max end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
			if channel ~= meta:get_string("digiline_channel") then return end
 | 
								if channel ~= meta:get_string("digiline_channel") then return end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if type(msg) == "table" then
 | 
				
			||||||
 | 
									if msg.distance or msg.scanname then
 | 
				
			||||||
 | 
										if msg.distance then
 | 
				
			||||||
 | 
											meta:set_string("distance", msg.distance)
 | 
				
			||||||
 | 
										end
 | 
				
			||||||
 | 
										if msg.scanname then
 | 
				
			||||||
 | 
											meta:set_string("scanname", msg.scanname)
 | 
				
			||||||
 | 
										end
 | 
				
			||||||
 | 
										node_detector_make_formspec(pos)
 | 
				
			||||||
 | 
									end
 | 
				
			||||||
 | 
									if msg.command == "get" then
 | 
				
			||||||
 | 
										node_detector_send_node_name(pos, node, channel, meta)
 | 
				
			||||||
 | 
									elseif msg.command == "scan" then
 | 
				
			||||||
 | 
										local result = node_detector_scan(pos)
 | 
				
			||||||
 | 
										digiline:receptor_send(pos, digiline.rules.default, channel, result)
 | 
				
			||||||
 | 
									end
 | 
				
			||||||
 | 
								else
 | 
				
			||||||
				if msg == GET_COMMAND then
 | 
									if msg == GET_COMMAND then
 | 
				
			||||||
				local nodename = minetest.get_node(
 | 
										node_detector_send_node_name(pos, node, channel, meta)
 | 
				
			||||||
					vector.subtract(pos, vector.multiply(minetest.facedir_to_dir(node.param2), distance + 1))
 | 
					 | 
				
			||||||
				).name
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
				digiline:receptor_send(pos, digiline.rules.default, channel, nodename)
 | 
					 | 
				
			||||||
				else
 | 
									else
 | 
				
			||||||
					meta:set_string("scanname", msg)
 | 
										meta:set_string("scanname", msg)
 | 
				
			||||||
					node_detector_make_formspec(pos)
 | 
										node_detector_make_formspec(pos)
 | 
				
			||||||
				end
 | 
									end
 | 
				
			||||||
 | 
								end
 | 
				
			||||||
		end,
 | 
							end,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	receptor = {}
 | 
						receptor = {}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
local function after_place_node_detector(pos, placer)
 | 
					local function after_place_node_detector(pos, placer)
 | 
				
			||||||
	local placer_pos = placer:getpos()
 | 
						local placer_pos = placer:get_pos()
 | 
				
			||||||
	if not placer_pos then
 | 
						if not placer_pos then
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	end
 | 
						end
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								mesecons_detector/mod.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,2 @@
 | 
				
			|||||||
 | 
					name = mesecons_detector
 | 
				
			||||||
 | 
					depends = mesecons, mesecons_materials
 | 
				
			||||||
| 
		 Before Width: | Height: | Size: 717 B After Width: | Height: | Size: 640 B  | 
| 
		 Before Width: | Height: | Size: 727 B After Width: | Height: | Size: 687 B  | 
| 
		 Before Width: | Height: | Size: 712 B After Width: | Height: | Size: 655 B  | 
| 
		 Before Width: | Height: | Size: 735 B After Width: | Height: | Size: 693 B  | 
@@ -1,2 +0,0 @@
 | 
				
			|||||||
mesecons
 | 
					 | 
				
			||||||
doors
 | 
					 | 
				
			||||||
@@ -13,9 +13,9 @@ local function on_rightclick(pos, dir, check_name, replace, replace_dir, params)
 | 
				
			|||||||
	minetest.swap_node(pos, {name = replace, param2 = p2})
 | 
						minetest.swap_node(pos, {name = replace, param2 = p2})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (minetest.get_meta(pos):get_int("right") ~= 0) == (params[1] ~= 3) then
 | 
						if (minetest.get_meta(pos):get_int("right") ~= 0) == (params[1] ~= 3) then
 | 
				
			||||||
		minetest.sound_play("doors_door_close", {pos = pos, gain = 0.3, max_hear_distance = 10})
 | 
							minetest.sound_play("doors_door_close", { pos = pos, gain = 0.3, max_hear_distance = 10 }, true)
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		minetest.sound_play("doors_door_open", {pos = pos, gain = 0.3, max_hear_distance = 10})
 | 
							minetest.sound_play("doors_door_open", { pos = pos, gain = 0.3, max_hear_distance = 10 }, true)
 | 
				
			||||||
	end
 | 
						end
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -73,16 +73,17 @@ meseconify_door("doors:door_wood")
 | 
				
			|||||||
meseconify_door("doors:door_steel")
 | 
					meseconify_door("doors:door_steel")
 | 
				
			||||||
meseconify_door("doors:door_glass")
 | 
					meseconify_door("doors:door_glass")
 | 
				
			||||||
meseconify_door("doors:door_obsidian_glass")
 | 
					meseconify_door("doors:door_obsidian_glass")
 | 
				
			||||||
 | 
					meseconify_door("xpanes:door_steel_bar")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
-- Trapdoor
 | 
					-- Trapdoor
 | 
				
			||||||
local function trapdoor_switch(pos, node)
 | 
					local function trapdoor_switch(pos, node)
 | 
				
			||||||
	local state = minetest.get_meta(pos):get_int("state")
 | 
						local state = minetest.get_meta(pos):get_int("state")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if state == 1 then
 | 
						if state == 1 then
 | 
				
			||||||
		minetest.sound_play("doors_door_close", {pos = pos, gain = 0.3, max_hear_distance = 10})
 | 
							minetest.sound_play("doors_door_close", { pos = pos, gain = 0.3, max_hear_distance = 10 }, true)
 | 
				
			||||||
		minetest.set_node(pos, {name="doors:trapdoor", param2 = node.param2})
 | 
							minetest.set_node(pos, {name="doors:trapdoor", param2 = node.param2})
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		minetest.sound_play("doors_door_open", {pos = pos, gain = 0.3, max_hear_distance = 10})
 | 
							minetest.sound_play("doors_door_open", { pos = pos, gain = 0.3, max_hear_distance = 10 }, true)
 | 
				
			||||||
		minetest.set_node(pos, {name="doors:trapdoor_open", param2 = node.param2})
 | 
							minetest.set_node(pos, {name="doors:trapdoor_open", param2 = node.param2})
 | 
				
			||||||
	end
 | 
						end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -110,6 +111,12 @@ if doors and doors.get then
 | 
				
			|||||||
	minetest.override_item("doors:trapdoor_open", override)
 | 
						minetest.override_item("doors:trapdoor_open", override)
 | 
				
			||||||
	minetest.override_item("doors:trapdoor_steel", override)
 | 
						minetest.override_item("doors:trapdoor_steel", override)
 | 
				
			||||||
	minetest.override_item("doors:trapdoor_steel_open", override)
 | 
						minetest.override_item("doors:trapdoor_steel_open", override)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if minetest.registered_items["xpanes:trapdoor_steel_bar"] then
 | 
				
			||||||
 | 
							minetest.override_item("xpanes:trapdoor_steel_bar", override)
 | 
				
			||||||
 | 
							minetest.override_item("xpanes:trapdoor_steel_bar_open", override)
 | 
				
			||||||
 | 
						end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
else
 | 
					else
 | 
				
			||||||
	if minetest.registered_nodes["doors:trapdoor"] then
 | 
						if minetest.registered_nodes["doors:trapdoor"] then
 | 
				
			||||||
		minetest.override_item("doors:trapdoor", {
 | 
							minetest.override_item("doors:trapdoor", {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										3
									
								
								mesecons_doors/mod.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					name = mesecons_doors
 | 
				
			||||||
 | 
					depends = mesecons, doors
 | 
				
			||||||
 | 
					optional_depends = xpanes
 | 
				
			||||||
@@ -1,12 +1,5 @@
 | 
				
			|||||||
local screwdriver_exists = minetest.global_exists("screwdriver")
 | 
					local screwdriver_exists = minetest.global_exists("screwdriver")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
local corner_nodebox = {
 | 
					 | 
				
			||||||
	type = "fixed",
 | 
					 | 
				
			||||||
	-- ±0.001 is to prevent z-fighting
 | 
					 | 
				
			||||||
	fixed = {{ -16/32-0.001, -17/32, -3/32, 0, -13/32, 3/32 },
 | 
					 | 
				
			||||||
		   { -3/32, -17/32, -16/32+0.001, 3/32, -13/32, 3/32}}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
local corner_selectionbox = {
 | 
					local corner_selectionbox = {
 | 
				
			||||||
		type = "fixed",
 | 
							type = "fixed",
 | 
				
			||||||
		fixed = { -16/32, -16/32, -16/32, 5/32, -12/32, 5/32 },
 | 
							fixed = { -16/32, -16/32, -16/32, 5/32, -12/32, 5/32 },
 | 
				
			||||||
@@ -25,14 +18,11 @@ local corner_get_rules = function (node)
 | 
				
			|||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
minetest.register_node("mesecons_extrawires:corner_on", {
 | 
					minetest.register_node("mesecons_extrawires:corner_on", {
 | 
				
			||||||
	drawtype = "nodebox",
 | 
						drawtype = "mesh",
 | 
				
			||||||
 | 
						mesh = "mesecons_extrawires_corner.obj",
 | 
				
			||||||
	tiles = {
 | 
						tiles = {
 | 
				
			||||||
		"jeija_insulated_wire_curved_tb_on.png",
 | 
							{ name = "jeija_insulated_wire_sides_on.png", backface_culling = true },
 | 
				
			||||||
		"jeija_insulated_wire_curved_tb_on.png^[transformR270",
 | 
							{ name = "jeija_insulated_wire_ends_on.png", backface_culling = true },
 | 
				
			||||||
		"jeija_insulated_wire_sides_on.png",
 | 
					 | 
				
			||||||
		"jeija_insulated_wire_ends_on.png",
 | 
					 | 
				
			||||||
		"jeija_insulated_wire_sides_on.png",
 | 
					 | 
				
			||||||
		"jeija_insulated_wire_ends_on.png"
 | 
					 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	paramtype = "light",
 | 
						paramtype = "light",
 | 
				
			||||||
	paramtype2 = "facedir",
 | 
						paramtype2 = "facedir",
 | 
				
			||||||
@@ -55,15 +45,12 @@ minetest.register_node("mesecons_extrawires:corner_on", {
 | 
				
			|||||||
})
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
minetest.register_node("mesecons_extrawires:corner_off", {
 | 
					minetest.register_node("mesecons_extrawires:corner_off", {
 | 
				
			||||||
	drawtype = "nodebox",
 | 
						drawtype = "mesh",
 | 
				
			||||||
	description = "Insulated Mesecon Corner",
 | 
						description = "Insulated Mesecon Corner",
 | 
				
			||||||
 | 
						mesh = "mesecons_extrawires_corner.obj",
 | 
				
			||||||
	tiles = {
 | 
						tiles = {
 | 
				
			||||||
		"jeija_insulated_wire_curved_tb_off.png",
 | 
							{ name = "jeija_insulated_wire_sides_off.png", backface_culling = true },
 | 
				
			||||||
		"jeija_insulated_wire_curved_tb_off.png^[transformR270",
 | 
							{ name = "jeija_insulated_wire_ends_off.png", backface_culling = true },
 | 
				
			||||||
		"jeija_insulated_wire_sides_off.png",
 | 
					 | 
				
			||||||
		"jeija_insulated_wire_ends_off.png",
 | 
					 | 
				
			||||||
		"jeija_insulated_wire_sides_off.png",
 | 
					 | 
				
			||||||
		"jeija_insulated_wire_ends_off.png"
 | 
					 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	paramtype = "light",
 | 
						paramtype = "light",
 | 
				
			||||||
	paramtype2 = "facedir",
 | 
						paramtype2 = "facedir",
 | 
				
			||||||
@@ -87,8 +74,7 @@ minetest.register_node("mesecons_extrawires:corner_off", {
 | 
				
			|||||||
minetest.register_craft({
 | 
					minetest.register_craft({
 | 
				
			||||||
	output = "mesecons_extrawires:corner_off 3",
 | 
						output = "mesecons_extrawires:corner_off 3",
 | 
				
			||||||
	recipe = {
 | 
						recipe = {
 | 
				
			||||||
		{"", "", ""},
 | 
							{"mesecons_insulated:insulated_off", "mesecons_insulated:insulated_off"},
 | 
				
			||||||
		{"mesecons_insulated:insulated_off", "mesecons_insulated:insulated_off", ""},
 | 
							{"", "mesecons_insulated:insulated_off"},
 | 
				
			||||||
		{"", "mesecons_insulated:insulated_off", ""},
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +0,0 @@
 | 
				
			|||||||
default
 | 
					 | 
				
			||||||
mesecons
 | 
					 | 
				
			||||||
screwdriver?
 | 
					 | 
				
			||||||
| 
		 Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 36 KiB  | 
| 
		 Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 1.9 KiB  | 
| 
		 Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 58 KiB  | 
| 
		 Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 1.7 KiB  | 
| 
		 Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 28 KiB  | 
| 
		 Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 2.5 KiB  | 
| 
		 Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 47 KiB  | 
| 
		 Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 1.9 KiB  | 
| 
		 Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 11 KiB  | 
| 
		 Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 1.9 KiB  | 
							
								
								
									
										91
									
								
								mesecons_extrawires/doublecorner.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,91 @@
 | 
				
			|||||||
 | 
					local rotate
 | 
				
			||||||
 | 
					if minetest.global_exists("screwdriver") then rotate = screwdriver.rotate_simple end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					local doublecorner_selectionbox = {
 | 
				
			||||||
 | 
						type = "fixed",
 | 
				
			||||||
 | 
						fixed = { -8/16, -8/16, -8/16, 8/16, -6/16, 8/16 },
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					local rules = {
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							{ x = 1, y = 0, z = 0 },
 | 
				
			||||||
 | 
							{ x = 0, y = 0, z = 1 },
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							{ x = -1, y = 0, z = 0 },
 | 
				
			||||||
 | 
							{ x = 0, y = 0, z = -1 },
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					local doublecorner_rules = {}
 | 
				
			||||||
 | 
					for k = 1, 4 do
 | 
				
			||||||
 | 
						doublecorner_rules[k] = table.copy(rules)
 | 
				
			||||||
 | 
						for i, r in ipairs(rules) do
 | 
				
			||||||
 | 
							rules[i] = mesecon.rotate_rules_left(r)
 | 
				
			||||||
 | 
						end
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					local function doublecorner_get_rules(node)
 | 
				
			||||||
 | 
						return doublecorner_rules[node.param2 % 4 + 1]
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					local doublecorner_states = {
 | 
				
			||||||
 | 
						"mesecons_extrawires:doublecorner_00",
 | 
				
			||||||
 | 
						"mesecons_extrawires:doublecorner_01",
 | 
				
			||||||
 | 
						"mesecons_extrawires:doublecorner_10",
 | 
				
			||||||
 | 
						"mesecons_extrawires:doublecorner_11",
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					local wire1_states = { "off", "off", "on", "on" }
 | 
				
			||||||
 | 
					local wire2_states = { "off", "on", "off", "on" }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					for k, state in ipairs(doublecorner_states) do
 | 
				
			||||||
 | 
						local w1 = wire1_states[k]
 | 
				
			||||||
 | 
						local w2 = wire2_states[k]
 | 
				
			||||||
 | 
						local groups =  { dig_immediate = 3 }
 | 
				
			||||||
 | 
						if k ~= 1 then groups.not_in_creative_inventory = 1 end
 | 
				
			||||||
 | 
						minetest.register_node(state, {
 | 
				
			||||||
 | 
							drawtype = "mesh",
 | 
				
			||||||
 | 
							mesh = "mesecons_extrawires_doublecorner.obj",
 | 
				
			||||||
 | 
							description = "Insulated Mesecon Double Corner",
 | 
				
			||||||
 | 
							tiles = {
 | 
				
			||||||
 | 
								{ name = "jeija_insulated_wire_sides_" .. w1 .. ".png", backface_culling = true },
 | 
				
			||||||
 | 
								{ name = "jeija_insulated_wire_ends_" .. w1 .. ".png", backface_culling = true },
 | 
				
			||||||
 | 
								{ name = "jeija_insulated_wire_sides_" .. w2 .. ".png", backface_culling = true },
 | 
				
			||||||
 | 
								{ name = "jeija_insulated_wire_ends_" .. w2 .. ".png", backface_culling = true },
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							paramtype = "light",
 | 
				
			||||||
 | 
							paramtype2 = "facedir",
 | 
				
			||||||
 | 
							is_ground_content = false,
 | 
				
			||||||
 | 
							walkable = false,
 | 
				
			||||||
 | 
							sunlight_propagates = true,
 | 
				
			||||||
 | 
							selection_box = doublecorner_selectionbox,
 | 
				
			||||||
 | 
							groups = groups,
 | 
				
			||||||
 | 
							drop = doublecorner_states[1],
 | 
				
			||||||
 | 
							sounds = default.node_sound_defaults(),
 | 
				
			||||||
 | 
							mesecons = {
 | 
				
			||||||
 | 
								conductor = {
 | 
				
			||||||
 | 
									states = doublecorner_states,
 | 
				
			||||||
 | 
									rules = doublecorner_get_rules,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							on_blast = mesecon.on_blastnode,
 | 
				
			||||||
 | 
							on_rotate = rotate,
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					minetest.register_craft({
 | 
				
			||||||
 | 
						type = "shapeless",
 | 
				
			||||||
 | 
						output = "mesecons_extrawires:doublecorner_00",
 | 
				
			||||||
 | 
						recipe = {
 | 
				
			||||||
 | 
							"mesecons_extrawires:corner_off",
 | 
				
			||||||
 | 
							"mesecons_extrawires:corner_off",
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					minetest.register_craft({
 | 
				
			||||||
 | 
						type = "shapeless",
 | 
				
			||||||
 | 
						output = "mesecons_extrawires:corner_off 2",
 | 
				
			||||||
 | 
						recipe = {
 | 
				
			||||||
 | 
							"mesecons_extrawires:doublecorner_00",
 | 
				
			||||||
 | 
						},
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
@@ -1,5 +1,6 @@
 | 
				
			|||||||
dofile(minetest.get_modpath("mesecons_extrawires").."/crossover.lua");
 | 
					dofile(minetest.get_modpath("mesecons_extrawires").."/crossover.lua");
 | 
				
			||||||
dofile(minetest.get_modpath("mesecons_extrawires").."/tjunction.lua");
 | 
					dofile(minetest.get_modpath("mesecons_extrawires").."/tjunction.lua");
 | 
				
			||||||
dofile(minetest.get_modpath("mesecons_extrawires").."/corner.lua");
 | 
					dofile(minetest.get_modpath("mesecons_extrawires").."/corner.lua");
 | 
				
			||||||
 | 
					dofile(minetest.get_modpath("mesecons_extrawires").."/doublecorner.lua");
 | 
				
			||||||
dofile(minetest.get_modpath("mesecons_extrawires").."/vertical.lua");
 | 
					dofile(minetest.get_modpath("mesecons_extrawires").."/vertical.lua");
 | 
				
			||||||
dofile(minetest.get_modpath("mesecons_extrawires").."/mesewire.lua");
 | 
					dofile(minetest.get_modpath("mesecons_extrawires").."/mesewire.lua");
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										3
									
								
								mesecons_extrawires/mod.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					name = mesecons_extrawires
 | 
				
			||||||
 | 
					depends = default, mesecons
 | 
				
			||||||
 | 
					optional_depends = screwdriver
 | 
				
			||||||
							
								
								
									
										125
									
								
								mesecons_extrawires/models/mesecons_extrawires_corner.obj
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,125 @@
 | 
				
			|||||||
 | 
					# Вершины
 | 
				
			||||||
 | 
					# Провод 1
 | 
				
			||||||
 | 
					# 1 (ниж. внутр.)
 | 
				
			||||||
 | 
					v 0.093750 -0.531250 -0.501000
 | 
				
			||||||
 | 
					v 0.093750 -0.531250 -0.331726
 | 
				
			||||||
 | 
					v 0.331726 -0.531250 -0.093750
 | 
				
			||||||
 | 
					v 0.501000 -0.531250 -0.093750
 | 
				
			||||||
 | 
					# 5 (ниж. наруж.)
 | 
				
			||||||
 | 
					v -0.093750 -0.531250 -0.501000
 | 
				
			||||||
 | 
					v -0.093750 -0.531250 -0.254061
 | 
				
			||||||
 | 
					v 0.254061 -0.531250 0.093750
 | 
				
			||||||
 | 
					v 0.501000 -0.531250 0.093750
 | 
				
			||||||
 | 
					# 9 (верх. внутр.)
 | 
				
			||||||
 | 
					v 0.093750 -0.406250 -0.501000
 | 
				
			||||||
 | 
					v 0.093750 -0.406250 -0.331726
 | 
				
			||||||
 | 
					v 0.331726 -0.406250 -0.093750
 | 
				
			||||||
 | 
					v 0.501000 -0.406250 -0.093750
 | 
				
			||||||
 | 
					# 13 (верх. наруж.)
 | 
				
			||||||
 | 
					v -0.093750 -0.406250 -0.501000
 | 
				
			||||||
 | 
					v -0.093750 -0.406250 -0.254061
 | 
				
			||||||
 | 
					v 0.254061 -0.406250 0.093750
 | 
				
			||||||
 | 
					v 0.501000 -0.406250 0.093750
 | 
				
			||||||
 | 
					# Текстурные координаты
 | 
				
			||||||
 | 
					# 1 (ниж.)
 | 
				
			||||||
 | 
					vt 0.000000 0.406250
 | 
				
			||||||
 | 
					vt 0.168274 0.406250
 | 
				
			||||||
 | 
					vt 0.331726 0.406250
 | 
				
			||||||
 | 
					vt 0.668274 0.406250
 | 
				
			||||||
 | 
					vt 0.831726 0.406250
 | 
				
			||||||
 | 
					vt 1.000000 0.406250
 | 
				
			||||||
 | 
					vt 0.000000 0.593750
 | 
				
			||||||
 | 
					vt 0.245939 0.593750
 | 
				
			||||||
 | 
					vt 0.254061 0.593750
 | 
				
			||||||
 | 
					vt 0.745939 0.593750
 | 
				
			||||||
 | 
					vt 0.754061 0.593750
 | 
				
			||||||
 | 
					vt 1.000000 0.593750
 | 
				
			||||||
 | 
					# 13 (верх.)
 | 
				
			||||||
 | 
					vt 0.000000 0.406250
 | 
				
			||||||
 | 
					vt 0.245939 0.406250
 | 
				
			||||||
 | 
					vt 0.254061 0.406250
 | 
				
			||||||
 | 
					vt 0.745939 0.406250
 | 
				
			||||||
 | 
					vt 0.754061 0.406250
 | 
				
			||||||
 | 
					vt 1.000000 0.406250
 | 
				
			||||||
 | 
					vt 0.000000 0.593750
 | 
				
			||||||
 | 
					vt 0.168274 0.593750
 | 
				
			||||||
 | 
					vt 0.331726 0.593750
 | 
				
			||||||
 | 
					vt 0.668274 0.593750
 | 
				
			||||||
 | 
					vt 0.831726 0.593750
 | 
				
			||||||
 | 
					vt 1.000000 0.593750
 | 
				
			||||||
 | 
					# 25 (внутр.)
 | 
				
			||||||
 | 
					vt 1.000000 0.093750
 | 
				
			||||||
 | 
					vt 0.831726 0.093750
 | 
				
			||||||
 | 
					vt 0.668274 0.093750
 | 
				
			||||||
 | 
					vt 0.331726 0.093750
 | 
				
			||||||
 | 
					vt 0.168274 0.093750
 | 
				
			||||||
 | 
					vt 0.000000 0.093750
 | 
				
			||||||
 | 
					vt 1.000000 -0.031250
 | 
				
			||||||
 | 
					vt 0.831726 -0.031250
 | 
				
			||||||
 | 
					vt 0.668274 -0.031250
 | 
				
			||||||
 | 
					vt 0.331726 -0.031250
 | 
				
			||||||
 | 
					vt 0.168274 -0.031250
 | 
				
			||||||
 | 
					vt 0.000000 -0.031250
 | 
				
			||||||
 | 
					# 37 (внеш.)
 | 
				
			||||||
 | 
					vt 0.000000 -0.031250
 | 
				
			||||||
 | 
					vt 0.245939 -0.031250
 | 
				
			||||||
 | 
					vt 0.254061 -0.031250
 | 
				
			||||||
 | 
					vt 0.745939 -0.031250
 | 
				
			||||||
 | 
					vt 0.754061 -0.031250
 | 
				
			||||||
 | 
					vt 1.000000 -0.031250
 | 
				
			||||||
 | 
					vt 0.000000 0.093750
 | 
				
			||||||
 | 
					vt 0.245939 0.093750
 | 
				
			||||||
 | 
					vt 0.254061 0.093750
 | 
				
			||||||
 | 
					vt 0.745939 0.093750
 | 
				
			||||||
 | 
					vt 0.754061 0.093750
 | 
				
			||||||
 | 
					vt 1.000000 0.093750
 | 
				
			||||||
 | 
					# 49 (торец)
 | 
				
			||||||
 | 
					vt 0.406250 -0.031250
 | 
				
			||||||
 | 
					vt 0.406250 0.093750
 | 
				
			||||||
 | 
					vt 0.593750 -0.031250
 | 
				
			||||||
 | 
					vt 0.593750 0.093750
 | 
				
			||||||
 | 
					# Нормали
 | 
				
			||||||
 | 
					# 1
 | 
				
			||||||
 | 
					vn 1.000000 0.000000 0.000000
 | 
				
			||||||
 | 
					vn 0.000000 1.000000 0.000000
 | 
				
			||||||
 | 
					vn 0.000000 0.000000 1.000000
 | 
				
			||||||
 | 
					vn 0.707107 0.000000 0.707107
 | 
				
			||||||
 | 
					# 5
 | 
				
			||||||
 | 
					vn -1.000000 0.000000 0.000000
 | 
				
			||||||
 | 
					vn 0.000000 -1.000000 0.000000
 | 
				
			||||||
 | 
					vn 0.000000 0.000000 -1.000000
 | 
				
			||||||
 | 
					vn -0.707107 0.000000 -0.707107
 | 
				
			||||||
 | 
					# Грани
 | 
				
			||||||
 | 
					g Sides1
 | 
				
			||||||
 | 
					# Часть 1
 | 
				
			||||||
 | 
					f 5/37/1 6/38/1 14/44/1
 | 
				
			||||||
 | 
					f 5/37/1 14/44/1 13/43/1
 | 
				
			||||||
 | 
					f 13/13/2 14/14/2 10/20/2
 | 
				
			||||||
 | 
					f 13/13/2 10/20/2 9/19/2
 | 
				
			||||||
 | 
					f 9/25/5 10/26/5 2/32/5
 | 
				
			||||||
 | 
					f 9/25/5 2/32/5 1/31/5
 | 
				
			||||||
 | 
					f 1/1/6 2/2/6 6/8/6
 | 
				
			||||||
 | 
					f 1/1/6 6/8/6 5/7/6
 | 
				
			||||||
 | 
					# Часть 2
 | 
				
			||||||
 | 
					f 6/39/4 7/40/4 15/46/4
 | 
				
			||||||
 | 
					f 6/39/4 15/46/4 14/45/4
 | 
				
			||||||
 | 
					f 14/15/2 15/16/2 11/22/2
 | 
				
			||||||
 | 
					f 14/15/2 11/22/2 10/21/2
 | 
				
			||||||
 | 
					f 10/27/8 11/28/8 3/34/8
 | 
				
			||||||
 | 
					f 10/27/8 3/34/8 2/33/8
 | 
				
			||||||
 | 
					f 2/3/6 3/4/6 7/10/6
 | 
				
			||||||
 | 
					f 2/3/6 7/10/6 6/9/6
 | 
				
			||||||
 | 
					# Часть 3
 | 
				
			||||||
 | 
					f 7/41/3 8/42/3 16/48/3
 | 
				
			||||||
 | 
					f 7/41/3 16/48/3 15/47/3
 | 
				
			||||||
 | 
					f 15/17/2 16/18/2 12/24/2
 | 
				
			||||||
 | 
					f 15/17/2 12/24/2 11/23/2
 | 
				
			||||||
 | 
					f 11/29/7 12/30/7 4/36/7
 | 
				
			||||||
 | 
					f 11/29/7 4/36/7 3/35/7
 | 
				
			||||||
 | 
					f 3/5/6 4/6/6 8/12/6
 | 
				
			||||||
 | 
					f 3/5/6 8/12/6 7/11/6
 | 
				
			||||||
 | 
					g Ends1
 | 
				
			||||||
 | 
					f 1/49/3 5/51/3 13/52/3
 | 
				
			||||||
 | 
					f 1/49/3 13/52/3 9/50/3
 | 
				
			||||||
 | 
					f 4/49/1 12/50/1 16/52/1
 | 
				
			||||||
 | 
					f 4/49/1 16/52/1 8/51/1
 | 
				
			||||||
							
								
								
									
										180
									
								
								mesecons_extrawires/models/mesecons_extrawires_doublecorner.obj
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,180 @@
 | 
				
			|||||||
 | 
					# Вершины
 | 
				
			||||||
 | 
					# Провод 1
 | 
				
			||||||
 | 
					# 1 (ниж. внутр.)
 | 
				
			||||||
 | 
					v 0.093750 -0.531250 -0.501000
 | 
				
			||||||
 | 
					v 0.093750 -0.531250 -0.331726
 | 
				
			||||||
 | 
					v 0.331726 -0.531250 -0.093750
 | 
				
			||||||
 | 
					v 0.501000 -0.531250 -0.093750
 | 
				
			||||||
 | 
					# 5 (ниж. наруж.)
 | 
				
			||||||
 | 
					v -0.093750 -0.531250 -0.501000
 | 
				
			||||||
 | 
					v -0.093750 -0.531250 -0.254061
 | 
				
			||||||
 | 
					v 0.254061 -0.531250 0.093750
 | 
				
			||||||
 | 
					v 0.501000 -0.531250 0.093750
 | 
				
			||||||
 | 
					# 9 (верх. внутр.)
 | 
				
			||||||
 | 
					v 0.093750 -0.406250 -0.501000
 | 
				
			||||||
 | 
					v 0.093750 -0.406250 -0.331726
 | 
				
			||||||
 | 
					v 0.331726 -0.406250 -0.093750
 | 
				
			||||||
 | 
					v 0.501000 -0.406250 -0.093750
 | 
				
			||||||
 | 
					# 13 (верх. наруж.)
 | 
				
			||||||
 | 
					v -0.093750 -0.406250 -0.501000
 | 
				
			||||||
 | 
					v -0.093750 -0.406250 -0.254061
 | 
				
			||||||
 | 
					v 0.254061 -0.406250 0.093750
 | 
				
			||||||
 | 
					v 0.501000 -0.406250 0.093750
 | 
				
			||||||
 | 
					# Провод 2
 | 
				
			||||||
 | 
					# 17 (ниж. внутр.)
 | 
				
			||||||
 | 
					v -0.093750 -0.531250 0.501000
 | 
				
			||||||
 | 
					v -0.093750 -0.531250 0.331726
 | 
				
			||||||
 | 
					v -0.331726 -0.531250 0.093750
 | 
				
			||||||
 | 
					v -0.501000 -0.531250 0.093750
 | 
				
			||||||
 | 
					# 21 (ниж. наруж.)
 | 
				
			||||||
 | 
					v 0.093750 -0.531250 0.501000
 | 
				
			||||||
 | 
					v 0.093750 -0.531250 0.254061
 | 
				
			||||||
 | 
					v -0.254061 -0.531250 -0.093750
 | 
				
			||||||
 | 
					v -0.501000 -0.531250 -0.093750
 | 
				
			||||||
 | 
					# 25 (верх. внутр.)
 | 
				
			||||||
 | 
					v -0.093750 -0.406250 0.501000
 | 
				
			||||||
 | 
					v -0.093750 -0.406250 0.331726
 | 
				
			||||||
 | 
					v -0.331726 -0.406250 0.093750
 | 
				
			||||||
 | 
					v -0.501000 -0.406250 0.093750
 | 
				
			||||||
 | 
					# 29 (верх. наруж.)
 | 
				
			||||||
 | 
					v 0.093750 -0.406250 0.501000
 | 
				
			||||||
 | 
					v 0.093750 -0.406250 0.254061
 | 
				
			||||||
 | 
					v -0.254061 -0.406250 -0.093750
 | 
				
			||||||
 | 
					v -0.501000 -0.406250 -0.093750
 | 
				
			||||||
 | 
					# Текстурные координаты
 | 
				
			||||||
 | 
					# 1 (ниж.)
 | 
				
			||||||
 | 
					vt 0.000000 0.406250
 | 
				
			||||||
 | 
					vt 0.168274 0.406250
 | 
				
			||||||
 | 
					vt 0.331726 0.406250
 | 
				
			||||||
 | 
					vt 0.668274 0.406250
 | 
				
			||||||
 | 
					vt 0.831726 0.406250
 | 
				
			||||||
 | 
					vt 1.000000 0.406250
 | 
				
			||||||
 | 
					vt 0.000000 0.593750
 | 
				
			||||||
 | 
					vt 0.245939 0.593750
 | 
				
			||||||
 | 
					vt 0.254061 0.593750
 | 
				
			||||||
 | 
					vt 0.745939 0.593750
 | 
				
			||||||
 | 
					vt 0.754061 0.593750
 | 
				
			||||||
 | 
					vt 1.000000 0.593750
 | 
				
			||||||
 | 
					# 13 (верх.)
 | 
				
			||||||
 | 
					vt 0.000000 0.406250
 | 
				
			||||||
 | 
					vt 0.245939 0.406250
 | 
				
			||||||
 | 
					vt 0.254061 0.406250
 | 
				
			||||||
 | 
					vt 0.745939 0.406250
 | 
				
			||||||
 | 
					vt 0.754061 0.406250
 | 
				
			||||||
 | 
					vt 1.000000 0.406250
 | 
				
			||||||
 | 
					vt 0.000000 0.593750
 | 
				
			||||||
 | 
					vt 0.168274 0.593750
 | 
				
			||||||
 | 
					vt 0.331726 0.593750
 | 
				
			||||||
 | 
					vt 0.668274 0.593750
 | 
				
			||||||
 | 
					vt 0.831726 0.593750
 | 
				
			||||||
 | 
					vt 1.000000 0.593750
 | 
				
			||||||
 | 
					# 25 (внутр.)
 | 
				
			||||||
 | 
					vt 1.000000 0.093750
 | 
				
			||||||
 | 
					vt 0.831726 0.093750
 | 
				
			||||||
 | 
					vt 0.668274 0.093750
 | 
				
			||||||
 | 
					vt 0.331726 0.093750
 | 
				
			||||||
 | 
					vt 0.168274 0.093750
 | 
				
			||||||
 | 
					vt 0.000000 0.093750
 | 
				
			||||||
 | 
					vt 1.000000 -0.031250
 | 
				
			||||||
 | 
					vt 0.831726 -0.031250
 | 
				
			||||||
 | 
					vt 0.668274 -0.031250
 | 
				
			||||||
 | 
					vt 0.331726 -0.031250
 | 
				
			||||||
 | 
					vt 0.168274 -0.031250
 | 
				
			||||||
 | 
					vt 0.000000 -0.031250
 | 
				
			||||||
 | 
					# 37 (внеш.)
 | 
				
			||||||
 | 
					vt 0.000000 -0.031250
 | 
				
			||||||
 | 
					vt 0.245939 -0.031250
 | 
				
			||||||
 | 
					vt 0.254061 -0.031250
 | 
				
			||||||
 | 
					vt 0.745939 -0.031250
 | 
				
			||||||
 | 
					vt 0.754061 -0.031250
 | 
				
			||||||
 | 
					vt 1.000000 -0.031250
 | 
				
			||||||
 | 
					vt 0.000000 0.093750
 | 
				
			||||||
 | 
					vt 0.245939 0.093750
 | 
				
			||||||
 | 
					vt 0.254061 0.093750
 | 
				
			||||||
 | 
					vt 0.745939 0.093750
 | 
				
			||||||
 | 
					vt 0.754061 0.093750
 | 
				
			||||||
 | 
					vt 1.000000 0.093750
 | 
				
			||||||
 | 
					# 49 (торец)
 | 
				
			||||||
 | 
					vt 0.406250 -0.031250
 | 
				
			||||||
 | 
					vt 0.406250 0.093750
 | 
				
			||||||
 | 
					vt 0.593750 -0.031250
 | 
				
			||||||
 | 
					vt 0.593750 0.093750
 | 
				
			||||||
 | 
					# Нормали
 | 
				
			||||||
 | 
					# 1
 | 
				
			||||||
 | 
					vn 1.000000 0.000000 0.000000
 | 
				
			||||||
 | 
					vn 0.000000 1.000000 0.000000
 | 
				
			||||||
 | 
					vn 0.000000 0.000000 1.000000
 | 
				
			||||||
 | 
					vn 0.707107 0.000000 0.707107
 | 
				
			||||||
 | 
					# 5
 | 
				
			||||||
 | 
					vn -1.000000 0.000000 0.000000
 | 
				
			||||||
 | 
					vn 0.000000 -1.000000 0.000000
 | 
				
			||||||
 | 
					vn 0.000000 0.000000 -1.000000
 | 
				
			||||||
 | 
					vn -0.707107 0.000000 -0.707107
 | 
				
			||||||
 | 
					# Грани
 | 
				
			||||||
 | 
					# Грани
 | 
				
			||||||
 | 
					g Sides1
 | 
				
			||||||
 | 
					# Часть 1
 | 
				
			||||||
 | 
					f 5/37/1 6/38/1 14/44/1
 | 
				
			||||||
 | 
					f 5/37/1 14/44/1 13/43/1
 | 
				
			||||||
 | 
					f 13/13/2 14/14/2 10/20/2
 | 
				
			||||||
 | 
					f 13/13/2 10/20/2 9/19/2
 | 
				
			||||||
 | 
					f 9/25/5 10/26/5 2/32/5
 | 
				
			||||||
 | 
					f 9/25/5 2/32/5 1/31/5
 | 
				
			||||||
 | 
					f 1/1/6 2/2/6 6/8/6
 | 
				
			||||||
 | 
					f 1/1/6 6/8/6 5/7/6
 | 
				
			||||||
 | 
					# Часть 2
 | 
				
			||||||
 | 
					f 6/39/4 7/40/4 15/46/4
 | 
				
			||||||
 | 
					f 6/39/4 15/46/4 14/45/4
 | 
				
			||||||
 | 
					f 14/15/2 15/16/2 11/22/2
 | 
				
			||||||
 | 
					f 14/15/2 11/22/2 10/21/2
 | 
				
			||||||
 | 
					f 10/27/8 11/28/8 3/34/8
 | 
				
			||||||
 | 
					f 10/27/8 3/34/8 2/33/8
 | 
				
			||||||
 | 
					f 2/3/6 3/4/6 7/10/6
 | 
				
			||||||
 | 
					f 2/3/6 7/10/6 6/9/6
 | 
				
			||||||
 | 
					# Часть 3
 | 
				
			||||||
 | 
					f 7/41/3 8/42/3 16/48/3
 | 
				
			||||||
 | 
					f 7/41/3 16/48/3 15/47/3
 | 
				
			||||||
 | 
					f 15/17/2 16/18/2 12/24/2
 | 
				
			||||||
 | 
					f 15/17/2 12/24/2 11/23/2
 | 
				
			||||||
 | 
					f 11/29/7 12/30/7 4/36/7
 | 
				
			||||||
 | 
					f 11/29/7 4/36/7 3/35/7
 | 
				
			||||||
 | 
					f 3/5/6 4/6/6 8/12/6
 | 
				
			||||||
 | 
					f 3/5/6 8/12/6 7/11/6
 | 
				
			||||||
 | 
					g Ends1
 | 
				
			||||||
 | 
					f 1/49/3 5/51/3 13/52/3
 | 
				
			||||||
 | 
					f 1/49/3 13/52/3 9/50/3
 | 
				
			||||||
 | 
					f 4/49/1 12/50/1 16/52/1
 | 
				
			||||||
 | 
					f 4/49/1 16/52/1 8/51/1
 | 
				
			||||||
 | 
					g Sides2
 | 
				
			||||||
 | 
					# Часть 1
 | 
				
			||||||
 | 
					f 21/37/1 22/38/1 30/44/1
 | 
				
			||||||
 | 
					f 21/37/1 30/44/1 29/43/1
 | 
				
			||||||
 | 
					f 29/13/2 30/14/2 26/20/2
 | 
				
			||||||
 | 
					f 29/13/2 26/20/2 25/19/2
 | 
				
			||||||
 | 
					f 25/25/5 26/26/5 18/32/5
 | 
				
			||||||
 | 
					f 25/25/5 18/32/5 17/31/5
 | 
				
			||||||
 | 
					f 17/1/6 18/2/6 22/8/6
 | 
				
			||||||
 | 
					f 17/1/6 22/8/6 21/7/6
 | 
				
			||||||
 | 
					# Часть 2
 | 
				
			||||||
 | 
					f 22/39/4 23/40/4 31/46/4
 | 
				
			||||||
 | 
					f 22/39/4 31/46/4 30/45/4
 | 
				
			||||||
 | 
					f 30/15/2 31/16/2 27/22/2
 | 
				
			||||||
 | 
					f 30/15/2 27/22/2 26/21/2
 | 
				
			||||||
 | 
					f 26/27/8 27/28/8 19/34/8
 | 
				
			||||||
 | 
					f 26/27/8 19/34/8 18/33/8
 | 
				
			||||||
 | 
					f 18/3/6 19/4/6 23/10/6
 | 
				
			||||||
 | 
					f 18/3/6 23/10/6 22/9/6
 | 
				
			||||||
 | 
					# Часть 3
 | 
				
			||||||
 | 
					f 23/41/3 24/42/3 32/48/3
 | 
				
			||||||
 | 
					f 23/41/3 32/48/3 31/47/3
 | 
				
			||||||
 | 
					f 31/17/2 32/18/2 28/24/2
 | 
				
			||||||
 | 
					f 31/17/2 28/24/2 27/23/2
 | 
				
			||||||
 | 
					f 27/29/7 28/30/7 20/36/7
 | 
				
			||||||
 | 
					f 27/29/7 20/36/7 19/35/7
 | 
				
			||||||
 | 
					f 19/5/6 20/6/6 24/12/6
 | 
				
			||||||
 | 
					f 19/5/6 24/12/6 23/11/6
 | 
				
			||||||
 | 
					g Ends2
 | 
				
			||||||
 | 
					f 17/49/3 21/51/3 29/52/3
 | 
				
			||||||
 | 
					f 17/49/3 29/52/3 25/50/3
 | 
				
			||||||
 | 
					f 20/49/1 28/50/1 32/52/1
 | 
				
			||||||
 | 
					f 20/49/1 32/52/1 24/51/1
 | 
				
			||||||
@@ -88,7 +88,6 @@ minetest.register_node("mesecons_extrawires:tjunction_off", {
 | 
				
			|||||||
minetest.register_craft({
 | 
					minetest.register_craft({
 | 
				
			||||||
	output = "mesecons_extrawires:tjunction_off 3",
 | 
						output = "mesecons_extrawires:tjunction_off 3",
 | 
				
			||||||
	recipe = {
 | 
						recipe = {
 | 
				
			||||||
		{"", "", ""},
 | 
					 | 
				
			||||||
		{"mesecons_insulated:insulated_off", "mesecons_insulated:insulated_off", "mesecons_insulated:insulated_off"},
 | 
							{"mesecons_insulated:insulated_off", "mesecons_insulated:insulated_off", "mesecons_insulated:insulated_off"},
 | 
				
			||||||
		{"", "mesecons_insulated:insulated_off", ""},
 | 
							{"", "mesecons_insulated:insulated_off", ""},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,2 +0,0 @@
 | 
				
			|||||||
mesecons
 | 
					 | 
				
			||||||
screwdriver?
 | 
					 | 
				
			||||||
| 
		 Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 20 KiB  | 
| 
		 Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 2.9 KiB  | 
| 
		 Before Width: | Height: | Size: 598 B After Width: | Height: | Size: 519 B  | 
| 
		 Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.7 KiB  | 
@@ -1,10 +1,11 @@
 | 
				
			|||||||
local plg = {}
 | 
					local plg = {}
 | 
				
			||||||
plg.rules = {}
 | 
					plg.rules = {}
 | 
				
			||||||
 | 
					-- per-player formspec positions
 | 
				
			||||||
 | 
					plg.open_formspecs = {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
local lcore = dofile(minetest.get_modpath(minetest.get_current_modname()) .. "/logic.lua")
 | 
					local lcore = dofile(minetest.get_modpath(minetest.get_current_modname()) .. "/logic.lua")
 | 
				
			||||||
dofile(minetest.get_modpath(minetest.get_current_modname()) .. "/tool.lua")(plg)
 | 
					dofile(minetest.get_modpath(minetest.get_current_modname()) .. "/tool.lua")(plg)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
plg.register_nodes = function(template)
 | 
					plg.register_nodes = function(template)
 | 
				
			||||||
	-- each loop is for one of the 4 IO ports
 | 
						-- each loop is for one of the 4 IO ports
 | 
				
			||||||
	for a = 0, 1 do
 | 
						for a = 0, 1 do
 | 
				
			||||||
@@ -93,16 +94,20 @@ plg.register_nodes({
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		meta:set_string("instr", lcore.serialize(is))
 | 
							meta:set_string("instr", lcore.serialize(is))
 | 
				
			||||||
		meta:set_int("valid", 0)
 | 
							meta:set_int("valid", 0)
 | 
				
			||||||
		meta:set_string("formspec", plg.to_formspec_string(is))
 | 
					 | 
				
			||||||
		meta:set_string("infotext", "FPGA")
 | 
							meta:set_string("infotext", "FPGA")
 | 
				
			||||||
	end,
 | 
						end,
 | 
				
			||||||
	on_receive_fields = function(pos, formname, fields, sender)
 | 
						on_rightclick = function(pos, node, clicker)
 | 
				
			||||||
		if fields.program == nil then return end -- we only care when the user clicks "Program"
 | 
							if not minetest.is_player(clicker) then
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							end
 | 
				
			||||||
		local meta = minetest.get_meta(pos)
 | 
							local meta = minetest.get_meta(pos)
 | 
				
			||||||
		local is = plg.from_formspec_fields(fields)
 | 
							local name = clicker:get_player_name()
 | 
				
			||||||
 | 
							-- Erase formspecs of old FPGAs
 | 
				
			||||||
 | 
							meta:set_string("formspec", "")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		meta:set_string("instr", lcore.serialize(is))
 | 
							plg.open_formspecs[name] = pos
 | 
				
			||||||
		plg.update_formspec(pos, is)
 | 
							local is = lcore.deserialize(meta:get_string("instr"))
 | 
				
			||||||
 | 
							minetest.show_formspec(name, "mesecons:fpga", plg.to_formspec_string(is, nil))
 | 
				
			||||||
	end,
 | 
						end,
 | 
				
			||||||
	sounds = default.node_sound_stone_defaults(),
 | 
						sounds = default.node_sound_stone_defaults(),
 | 
				
			||||||
	mesecons = {
 | 
						mesecons = {
 | 
				
			||||||
@@ -116,6 +121,12 @@ plg.register_nodes({
 | 
				
			|||||||
	},
 | 
						},
 | 
				
			||||||
	after_dig_node = function(pos, node)
 | 
						after_dig_node = function(pos, node)
 | 
				
			||||||
		mesecon.receptor_off(pos, plg.rules[node.name])
 | 
							mesecon.receptor_off(pos, plg.rules[node.name])
 | 
				
			||||||
 | 
							for name, open_pos in pairs(plg.open_formspecs) do
 | 
				
			||||||
 | 
								if vector.equals(pos, open_pos) then
 | 
				
			||||||
 | 
									minetest.close_formspec(name, "mesecons:fpga")
 | 
				
			||||||
 | 
									plg.open_formspecs[name] = nil
 | 
				
			||||||
 | 
								end
 | 
				
			||||||
 | 
							end
 | 
				
			||||||
	end,
 | 
						end,
 | 
				
			||||||
	on_blast = mesecon.on_blastnode,
 | 
						on_blast = mesecon.on_blastnode,
 | 
				
			||||||
	on_rotate = function(pos, node, user, mode)
 | 
						on_rotate = function(pos, node, user, mode)
 | 
				
			||||||
@@ -153,13 +164,12 @@ plg.register_nodes({
 | 
				
			|||||||
		end
 | 
							end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		meta:set_string("instr", lcore.serialize(instr))
 | 
							meta:set_string("instr", lcore.serialize(instr))
 | 
				
			||||||
		plg.update_formspec(pos, instr)
 | 
							plg.update_meta(pos, instr)
 | 
				
			||||||
		return true
 | 
							return true
 | 
				
			||||||
	end,
 | 
						end,
 | 
				
			||||||
})
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					plg.to_formspec_string = function(is, err)
 | 
				
			||||||
plg.to_formspec_string = function(is)
 | 
					 | 
				
			||||||
	local function dropdown_op(x, y, name, val)
 | 
						local function dropdown_op(x, y, name, val)
 | 
				
			||||||
		local s = "dropdown[" .. tostring(x) .. "," .. tostring(y) .. ";"
 | 
							local s = "dropdown[" .. tostring(x) .. "," .. tostring(y) .. ";"
 | 
				
			||||||
				.. "0.75,0.5;" .. name .. ";" -- the height seems to be ignored?
 | 
									.. "0.75,0.5;" .. name .. ";" -- the height seems to be ignored?
 | 
				
			||||||
@@ -180,26 +190,20 @@ plg.to_formspec_string = function(is)
 | 
				
			|||||||
		return s .. "]"
 | 
							return s .. "]"
 | 
				
			||||||
	end
 | 
						end
 | 
				
			||||||
	local function dropdown_action(x, y, name, val)
 | 
						local function dropdown_action(x, y, name, val)
 | 
				
			||||||
		local s = "dropdown[" .. tostring(x) .. "," .. tostring(y) .. ";"
 | 
							local selected = 0
 | 
				
			||||||
				.. "1.125,0.5;" .. name .. ";" -- the height seems to be ignored?
 | 
							local titles = { " " }
 | 
				
			||||||
		s = s .. " , AND,  OR, NOT, XOR,NAND,   =,XNOR;"
 | 
							for i, data in ipairs(lcore.get_operations()) do
 | 
				
			||||||
		if val == nil then
 | 
								titles[i + 1] = data.fs_name
 | 
				
			||||||
			return s .. "0]" -- actually selects no field at all
 | 
								if val == data.gate then
 | 
				
			||||||
 | 
									selected = i + 1
 | 
				
			||||||
			end
 | 
								end
 | 
				
			||||||
		local mapping = {
 | 
							end
 | 
				
			||||||
			["and"] = 1,
 | 
							return ("dropdown[%f,%f;1.125,0.5;%s;%s;%i]"):format(
 | 
				
			||||||
			["or"] = 2,
 | 
								x, y, name, table.concat(titles, ","), selected)
 | 
				
			||||||
			["not"] = 3,
 | 
					 | 
				
			||||||
			["xor"] = 4,
 | 
					 | 
				
			||||||
			["nand"] = 5,
 | 
					 | 
				
			||||||
			["buf"] = 6,
 | 
					 | 
				
			||||||
			["xnor"] = 7,
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return s .. tostring(1 + mapping[val]) .. "]"
 | 
					 | 
				
			||||||
	end
 | 
						end
 | 
				
			||||||
	local s = "size[9,9]"..
 | 
						local s = "size[9,9]"..
 | 
				
			||||||
		"label[3.4,-0.15;FPGA gate configuration]"..
 | 
							"label[3.4,-0.15;FPGA gate configuration]"..
 | 
				
			||||||
		"button_exit[7,7.5;2,2.5;program;Program]"..
 | 
							"button[7,7.5;2,2.5;program;Program]"..
 | 
				
			||||||
		"box[4.2,0.5;0.03,7;#ffffff]"..
 | 
							"box[4.2,0.5;0.03,7;#ffffff]"..
 | 
				
			||||||
		"label[0.25,0.25;op. 1]"..
 | 
							"label[0.25,0.25;op. 1]"..
 | 
				
			||||||
		"label[1.0,0.25;gate type]"..
 | 
							"label[1.0,0.25;gate type]"..
 | 
				
			||||||
@@ -225,6 +229,12 @@ plg.to_formspec_string = function(is)
 | 
				
			|||||||
			y = 1 - 0.25
 | 
								y = 1 - 0.25
 | 
				
			||||||
		end
 | 
							end
 | 
				
			||||||
	end
 | 
						end
 | 
				
			||||||
 | 
						if err then
 | 
				
			||||||
 | 
							local fmsg = minetest.colorize("#ff0000", minetest.formspec_escape(err.msg))
 | 
				
			||||||
 | 
							s = s .. plg.red_box_around(err.i) ..
 | 
				
			||||||
 | 
								"label[0.25,8.25;The gate configuration is erroneous in the marked area:]"..
 | 
				
			||||||
 | 
								"label[0.25,8.5;" .. fmsg .. "]"
 | 
				
			||||||
 | 
						end
 | 
				
			||||||
	return s
 | 
						return s
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -239,20 +249,11 @@ plg.from_formspec_fields = function(fields)
 | 
				
			|||||||
		end
 | 
							end
 | 
				
			||||||
	end
 | 
						end
 | 
				
			||||||
	local function read_action(s)
 | 
						local function read_action(s)
 | 
				
			||||||
		if s == nil or s == " " then
 | 
							for i, data in ipairs(lcore.get_operations()) do
 | 
				
			||||||
			return nil
 | 
								if data.fs_name == s then
 | 
				
			||||||
 | 
									return data.gate
 | 
				
			||||||
 | 
								end
 | 
				
			||||||
		end
 | 
							end
 | 
				
			||||||
		local mapping = {
 | 
					 | 
				
			||||||
			["AND"] = "and",
 | 
					 | 
				
			||||||
			["OR"] = "or",
 | 
					 | 
				
			||||||
			["NOT"] = "not",
 | 
					 | 
				
			||||||
			["XOR"] = "xor",
 | 
					 | 
				
			||||||
			["NAND"] = "nand",
 | 
					 | 
				
			||||||
			["="] = "buf",
 | 
					 | 
				
			||||||
			["XNOR"] = "xnor",
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		s = s:gsub("^%s*", "") -- remove leading spaces
 | 
					 | 
				
			||||||
		return mapping[s]
 | 
					 | 
				
			||||||
	end
 | 
						end
 | 
				
			||||||
	local is = {}
 | 
						local is = {}
 | 
				
			||||||
	for i = 1, 14 do
 | 
						for i = 1, 14 do
 | 
				
			||||||
@@ -266,12 +267,11 @@ plg.from_formspec_fields = function(fields)
 | 
				
			|||||||
	return is
 | 
						return is
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
plg.update_formspec = function(pos, is)
 | 
					plg.update_meta = function(pos, is)
 | 
				
			||||||
	if type(is) == "string" then -- serialized string
 | 
						if type(is) == "string" then -- serialized string
 | 
				
			||||||
		is = lcore.deserialize(is)
 | 
							is = lcore.deserialize(is)
 | 
				
			||||||
	end
 | 
						end
 | 
				
			||||||
	local meta = minetest.get_meta(pos)
 | 
						local meta = minetest.get_meta(pos)
 | 
				
			||||||
	local form = plg.to_formspec_string(is)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	local err = lcore.validate(is)
 | 
						local err = lcore.validate(is)
 | 
				
			||||||
	if err == nil then
 | 
						if err == nil then
 | 
				
			||||||
@@ -280,17 +280,20 @@ plg.update_formspec = function(pos, is)
 | 
				
			|||||||
	else
 | 
						else
 | 
				
			||||||
		meta:set_int("valid", 0)
 | 
							meta:set_int("valid", 0)
 | 
				
			||||||
		meta:set_string("infotext", "FPGA")
 | 
							meta:set_string("infotext", "FPGA")
 | 
				
			||||||
		local fmsg = minetest.colorize("#ff0000", minetest.formspec_escape(err.msg))
 | 
					 | 
				
			||||||
		form = form .. plg.red_box_around(err.i) ..
 | 
					 | 
				
			||||||
			"label[0.25,8.25;The gate configuration is erroneous in the marked area:]"..
 | 
					 | 
				
			||||||
			"label[0.25,8.5;" .. fmsg .. "]"
 | 
					 | 
				
			||||||
	end
 | 
						end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	meta:set_string("formspec", form)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	-- reset ports and run programmed logic
 | 
						-- reset ports and run programmed logic
 | 
				
			||||||
	plg.setports(pos, false, false, false, false)
 | 
						plg.setports(pos, false, false, false, false)
 | 
				
			||||||
	plg.update(pos)
 | 
						plg.update(pos)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						-- Refresh open formspecs
 | 
				
			||||||
 | 
						local form = plg.to_formspec_string(is, err)
 | 
				
			||||||
 | 
						for name, open_pos in pairs(plg.open_formspecs) do
 | 
				
			||||||
 | 
							if vector.equals(pos, open_pos) then
 | 
				
			||||||
 | 
								minetest.show_formspec(name, "mesecons:fpga", form)
 | 
				
			||||||
 | 
							end
 | 
				
			||||||
 | 
						end
 | 
				
			||||||
 | 
						return err
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
plg.red_box_around = function(i)
 | 
					plg.red_box_around = function(i)
 | 
				
			||||||
@@ -409,6 +412,38 @@ plg.setports = function(pos, A, B, C, D) -- sets states of OUTPUT
 | 
				
			|||||||
	end
 | 
						end
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					minetest.register_on_player_receive_fields(function(player, formname, fields)
 | 
				
			||||||
 | 
						local player_name = player:get_player_name()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if formname ~= "mesecons:fpga" or fields.quit then
 | 
				
			||||||
 | 
							plg.open_formspecs[player_name] = nil -- potential garbage
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						end
 | 
				
			||||||
 | 
						if not fields.program then
 | 
				
			||||||
 | 
							return -- we only care when the user clicks "Program"
 | 
				
			||||||
 | 
						end
 | 
				
			||||||
 | 
						local pos = plg.open_formspecs[player_name]
 | 
				
			||||||
 | 
						if minetest.is_protected(pos, player_name) then
 | 
				
			||||||
 | 
							minetest.record_protection_violation(pos, player_name)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						local meta = minetest.get_meta(pos)
 | 
				
			||||||
 | 
						local is = plg.from_formspec_fields(fields)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						meta:set_string("instr", lcore.serialize(is))
 | 
				
			||||||
 | 
						local err = plg.update_meta(pos, is)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if not err then
 | 
				
			||||||
 | 
							plg.open_formspecs[player_name] = nil
 | 
				
			||||||
 | 
							-- Close on success
 | 
				
			||||||
 | 
							minetest.close_formspec(player_name, "mesecons:fpga")
 | 
				
			||||||
 | 
						end
 | 
				
			||||||
 | 
					end)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					minetest.register_on_leaveplayer(function(player)
 | 
				
			||||||
 | 
						plg.open_formspecs[player:get_player_name()] = nil
 | 
				
			||||||
 | 
					end)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
minetest.register_craft({
 | 
					minetest.register_craft({
 | 
				
			||||||
	output = "mesecons_fpga:fpga0000 2",
 | 
						output = "mesecons_fpga:fpga0000 2",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,27 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
local lg = {}
 | 
					local lg = {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					local operations = {
 | 
				
			||||||
 | 
						-- table index: Index in the formspec dropdown
 | 
				
			||||||
 | 
						-- gate:    Internal name
 | 
				
			||||||
 | 
						-- short:   Serialized form, single character
 | 
				
			||||||
 | 
						-- fs_name: Display name, padded to 4 characters
 | 
				
			||||||
 | 
						-- func:    Function that applies the operation
 | 
				
			||||||
 | 
						-- unary:   Whether this gate only has one input
 | 
				
			||||||
 | 
						{ gate = "and",  short = "&", fs_name = " AND", func = function(a, b) return a and b end },
 | 
				
			||||||
 | 
						{ gate = "or",   short = "|", fs_name = "  OR", func = function(a, b) return a or b end },
 | 
				
			||||||
 | 
						{ gate = "not",  short = "~", fs_name = " NOT", func = function(a, b) return not b end, unary = true },
 | 
				
			||||||
 | 
						{ gate = "xor",  short = "^", fs_name = " XOR", func = function(a, b) return a ~= b end },
 | 
				
			||||||
 | 
						{ gate = "nand", short = "?", fs_name = "NAND", func = function(a, b) return not (a and b) end },
 | 
				
			||||||
 | 
						{ gate = "buf",  short = "_", fs_name = "   =", func = function(a, b) return b end, unary = true },
 | 
				
			||||||
 | 
						{ gate = "xnor", short = "=", fs_name = "XNOR", func = function(a, b) return a == b end },
 | 
				
			||||||
 | 
						{ gate = "nor",  short = "!", fs_name = " NOR", func = function(a, b) return not (a or b) end },
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					lg.get_operations = function()
 | 
				
			||||||
 | 
						return operations
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
-- (de)serialize
 | 
					-- (de)serialize
 | 
				
			||||||
lg.serialize = function(t)
 | 
					lg.serialize = function(t)
 | 
				
			||||||
	local function _op(t)
 | 
						local function _op(t)
 | 
				
			||||||
@@ -11,20 +33,14 @@ lg.serialize = function(t)
 | 
				
			|||||||
			return tostring(t.n)
 | 
								return tostring(t.n)
 | 
				
			||||||
		end
 | 
							end
 | 
				
			||||||
	end
 | 
						end
 | 
				
			||||||
	local function _action(s)
 | 
						-- Serialize actions (gates) from eg. "and" to "&"
 | 
				
			||||||
		if s == nil then
 | 
						local function _action(action)
 | 
				
			||||||
			return " "
 | 
							for i, data in ipairs(operations) do
 | 
				
			||||||
 | 
								if data.gate == action then
 | 
				
			||||||
 | 
									return data.short
 | 
				
			||||||
			end
 | 
								end
 | 
				
			||||||
		local mapping = {
 | 
							end
 | 
				
			||||||
			["and"] = "&",
 | 
							return " "
 | 
				
			||||||
			["or"] = "|",
 | 
					 | 
				
			||||||
			["not"] = "~",
 | 
					 | 
				
			||||||
			["xor"] = "^",
 | 
					 | 
				
			||||||
			["nand"] = "?", --dunno
 | 
					 | 
				
			||||||
			["buf"] = "_",
 | 
					 | 
				
			||||||
			["xnor"] = "=",
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return mapping[s]
 | 
					 | 
				
			||||||
	end
 | 
						end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	local s = ""
 | 
						local s = ""
 | 
				
			||||||
@@ -48,18 +64,14 @@ lg.deserialize = function(s)
 | 
				
			|||||||
			return {type = "reg", n = tonumber(c)}
 | 
								return {type = "reg", n = tonumber(c)}
 | 
				
			||||||
		end
 | 
							end
 | 
				
			||||||
	end
 | 
						end
 | 
				
			||||||
	local function _action(c)
 | 
						-- Deserialize actions (gates) from eg. "&" to "and"
 | 
				
			||||||
		local mapping = {
 | 
						local function _action(action)
 | 
				
			||||||
			["&"] = "and",
 | 
							for i, data in ipairs(operations) do
 | 
				
			||||||
			["|"] = "or",
 | 
								if data.short == action then
 | 
				
			||||||
			["~"] = "not",
 | 
									return data.gate
 | 
				
			||||||
			["^"] = "xor",
 | 
								end
 | 
				
			||||||
			["?"] = "nand",
 | 
							end
 | 
				
			||||||
			["_"] = "buf",
 | 
							-- nil
 | 
				
			||||||
			["="] = "xnor",
 | 
					 | 
				
			||||||
			[" "] = nil,
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return mapping[c]
 | 
					 | 
				
			||||||
	end
 | 
						end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	local ret = {}
 | 
						local ret = {}
 | 
				
			||||||
@@ -109,16 +121,25 @@ lg.validate_single = function(t, i)
 | 
				
			|||||||
		return false
 | 
							return false
 | 
				
			||||||
	end
 | 
						end
 | 
				
			||||||
	local elem = t[i]
 | 
						local elem = t[i]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						local gate_data
 | 
				
			||||||
 | 
						for j, data in ipairs(operations) do
 | 
				
			||||||
 | 
							if data.gate == elem.action then
 | 
				
			||||||
 | 
								gate_data = data
 | 
				
			||||||
 | 
								break
 | 
				
			||||||
 | 
							end
 | 
				
			||||||
 | 
						end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	-- check for completeness
 | 
						-- check for completeness
 | 
				
			||||||
	if elem.action == nil then
 | 
						if not gate_data then
 | 
				
			||||||
		return {i = i, msg = "Gate type required"}
 | 
							return {i = i, msg = "Gate type is required"}
 | 
				
			||||||
	elseif elem.action == "not" or elem.action == "buf" then
 | 
						elseif gate_data.unary then
 | 
				
			||||||
		if elem.op1 ~= nil or elem.op2 == nil or elem.dst == nil then
 | 
							if elem.op1 ~= nil or elem.op2 == nil or elem.dst == nil then
 | 
				
			||||||
			return {i = i, msg = "Second operand (only) and destination required"}
 | 
								return {i = i, msg = "Second operand (only) and destination are required"}
 | 
				
			||||||
		end
 | 
							end
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
		if elem.op1 == nil or elem.op2 == nil or elem.dst == nil then
 | 
							if elem.op1 == nil or elem.op2 == nil or elem.dst == nil then
 | 
				
			||||||
			return {i = i, msg = "Operands and destination required"}
 | 
								return {i = i, msg = "Operands and destination are required"}
 | 
				
			||||||
		end
 | 
							end
 | 
				
			||||||
	end
 | 
						end
 | 
				
			||||||
	-- check whether operands/destination are identical
 | 
						-- check whether operands/destination are identical
 | 
				
			||||||
@@ -159,22 +180,13 @@ end
 | 
				
			|||||||
-- interpreter
 | 
					-- interpreter
 | 
				
			||||||
lg.interpret = function(t, a, b, c, d)
 | 
					lg.interpret = function(t, a, b, c, d)
 | 
				
			||||||
	local function _action(s, v1, v2)
 | 
						local function _action(s, v1, v2)
 | 
				
			||||||
		if s == "and" then
 | 
							for i, data in ipairs(operations) do
 | 
				
			||||||
			return v1 and v2
 | 
								if data.gate == s then
 | 
				
			||||||
		elseif s == "or" then
 | 
									return data.func(v1, v2)
 | 
				
			||||||
			return v1 or v2
 | 
					 | 
				
			||||||
		elseif s == "not" then
 | 
					 | 
				
			||||||
			return not v2
 | 
					 | 
				
			||||||
		elseif s == "xor" then
 | 
					 | 
				
			||||||
			return v1 ~= v2
 | 
					 | 
				
			||||||
		elseif s == "nand" then
 | 
					 | 
				
			||||||
			return not (v1 and v2)
 | 
					 | 
				
			||||||
		elseif s == "buf" then
 | 
					 | 
				
			||||||
			return v2
 | 
					 | 
				
			||||||
		else -- s == "xnor"
 | 
					 | 
				
			||||||
			return v1 == v2
 | 
					 | 
				
			||||||
			end
 | 
								end
 | 
				
			||||||
		end
 | 
							end
 | 
				
			||||||
 | 
							return false -- unknown gate
 | 
				
			||||||
 | 
						end
 | 
				
			||||||
	local function _op(t, regs, io_in)
 | 
						local function _op(t, regs, io_in)
 | 
				
			||||||
		if t.type == "reg" then
 | 
							if t.type == "reg" then
 | 
				
			||||||
			return regs[t.n]
 | 
								return regs[t.n]
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										3
									
								
								mesecons_fpga/mod.conf
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					name = mesecons_fpga
 | 
				
			||||||
 | 
					depends = mesecons
 | 
				
			||||||
 | 
					optional_depends = screwdriver
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								mesecons_fpga/sounds/mesecons_fpga_copy.ogg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								mesecons_fpga/sounds/mesecons_fpga_fail.ogg
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								mesecons_fpga/sounds/mesecons_fpga_write.ogg
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 Before Width: | Height: | Size: 311 B After Width: | Height: | Size: 256 B  |