-
Notifications
You must be signed in to change notification settings - Fork 6
/
ioexpander.lua
177 lines (167 loc) · 5.14 KB
/
ioexpander.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
local explode_port_states = function(state)
local port = {}
port.a = state%2 == 1
port.b = state%4 >= 2
port.c = state%8 >= 4
port.d = state%16 >= 8
return port
end
local implode_port_states = function(port)
local state = 0
if port.a then state = state + 1 end
if port.b then state = state + 2 end
if port.c then state = state + 4 end
if port.d then state = state + 8 end
return state
end
local gettiles = function(state)
local tiles = {
"digistuff_ioexp_top.png",
"jeija_microcontroller_bottom.png",
"jeija_microcontroller_sides.png",
"jeija_microcontroller_sides.png",
"jeija_microcontroller_sides.png",
"jeija_microcontroller_sides.png"
}
local port = explode_port_states(state)
for p,v in pairs(port) do
if v then
tiles[1] = tiles[1].."^jeija_luacontroller_LED_"..string.upper(p)..".png"
end
end
return tiles
end
local ioexp_get_on_rules = function(state)
local port = explode_port_states(state)
local rules = {}
if port.a then table.insert(rules,vector.new(-1,0,0)) end
if port.b then table.insert(rules,vector.new(0,0,1)) end
if port.c then table.insert(rules,vector.new(1,0,0)) end
if port.d then table.insert(rules,vector.new(0,0,-1)) end
return rules
end
local ioexp_get_off_rules = function(state)
local port = explode_port_states(state)
local rules = {}
if not port.a then table.insert(rules,vector.new(-1,0,0)) end
if not port.b then table.insert(rules,vector.new(0,0,1)) end
if not port.c then table.insert(rules,vector.new(1,0,0)) end
if not port.d then table.insert(rules,vector.new(0,0,-1)) end
return rules
end
local ioexp_digiline_send = function(pos)
local meta = minetest.get_meta(pos)
local channel = meta:get_string("channel")
local port = {
a = meta:get_int("aon") == 1,
b = meta:get_int("bon") == 1,
c = meta:get_int("con") == 1,
d = meta:get_int("don") == 1,
}
local outstate = explode_port_states(meta:get_int("outstate"))
for k,v in pairs(outstate) do port[k] = port[k] or v end
digilines.receptor_send(pos,digilines.rules.default,channel,port)
end
local ioexp_handle_digilines = function(pos,node,channel,msg)
local meta = minetest.get_meta(pos)
if channel ~= meta:get_string("channel") then return end
if msg == "GET" then
ioexp_digiline_send(pos)
return
end
if type(msg) ~= "table" then return end
local state = implode_port_states(msg)
node.name = "digistuff:ioexpander_"..state
meta:set_int("outstate",state)
minetest.swap_node(pos,node)
for _,i in ipairs(ioexp_get_on_rules(state)) do
mesecon.receptor_on(pos,{i})
end
for _,i in ipairs(ioexp_get_off_rules(state)) do
mesecon.receptor_off(pos,{i})
end
end
local ioexp_rule_to_port = function(rule)
if rule.x < 0 then return "a"
elseif rule.z > 0 then return "b"
elseif rule.x > 0 then return "c"
elseif rule.z < 0 then return "d" end
end
local ioexp_handle_mesecons = function(pos,_,rule,state)
local meta = minetest.get_meta(pos)
local port = ioexp_rule_to_port(rule)
if not port then return end
meta:set_int(port.."on",state == "on" and 1 or 0)
ioexp_digiline_send(pos)
end
for i=0,15,1 do
local offstate = i == 0
minetest.register_node("digistuff:ioexpander_"..i, {
description = offstate and "Digilines I/O Expander" or string.format("Digilines I/O Expander (on state %X - you hacker you!)",i),
groups = offstate and {cracky = 3,} or {cracky = 3,not_in_creative_inventory = 1,},
is_ground_content = false,
on_construct = function(pos)
local meta = minetest.get_meta(pos)
meta:set_string("formspec","field[channel;Channel;${channel}")
meta:set_int("aon",0)
meta:set_int("bon",0)
meta:set_int("con",0)
meta:set_int("don",0)
meta:set_int("outstate",i)
end,
_digistuff_channelcopier_fieldname = "channel",
tiles = gettiles(i),
inventory_image = "digistuff_ioexp_top.png",
drawtype = "nodebox",
drop = "digistuff:ioexpander_0",
selection_box = {
--From luacontroller
type = "fixed",
fixed = { -8/16, -8/16, -8/16, 8/16, -5/16, 8/16 },
},
node_box = {
--From Luacontroller
type = "fixed",
fixed = {
{-8/16, -8/16, -8/16, 8/16, -7/16, 8/16}, -- Bottom slab
{-5/16, -7/16, -5/16, 5/16, -6/16, 5/16}, -- Circuit board
{-3/16, -6/16, -3/16, 3/16, -5/16, 3/16}, -- IC
}
},
paramtype = "light",
sunlight_propagates = true,
on_receive_fields = function(pos, formname, fields, sender)
local name = sender:get_player_name()
if minetest.is_protected(pos,name) and not minetest.check_player_privs(name,{protection_bypass=true}) then
minetest.record_protection_violation(pos,name)
return
end
local meta = minetest.get_meta(pos)
if fields.channel then meta:set_string("channel",fields.channel) end
end,
mesecons = {
effector = {
rules = ioexp_get_off_rules(i),
action_change = ioexp_handle_mesecons,
},
receptor = {
state = mesecon.state.on,
rules = ioexp_get_on_rules(i),
},
},
digiline = {
receptor = {},
effector = {
action = ioexp_handle_digilines,
},
},
})
end
minetest.register_craft({
output = "digistuff:ioexpander_0",
recipe = {
{"","mesecons:wire_00000000_off","",},
{"digilines:wire_std_00000000","basic_materials:silicon","mesecons:wire_00000000_off",},
{"","mesecons:wire_00000000_off","",},
}
})