2017-04-17 11:17:09 +02:00
local wireless
local wireless_rids
local jammers
local storage = minetest.get_mod_storage ( )
wireless = minetest.deserialize ( storage : get_string ( " wireless " ) ) or { }
wireless_rids = minetest.deserialize ( storage : get_string ( " wireless_rids " ) ) or { }
jammers = minetest.deserialize ( storage : get_string ( " jammers " ) ) or { }
local function update_mod_storage ( )
storage : set_string ( " wireless " , minetest.serialize ( wireless ) )
storage : set_string ( " wireless_rids " , minetest.serialize ( wireless_rids ) )
storage : set_string ( " jammers " , minetest.serialize ( jammers ) )
end
2015-09-01 10:51:53 +02:00
2015-09-10 21:45:08 +02:00
-- localize these functions with small names because they work fairly fast
local get = vector.get_data_from_pos
local set = vector.set_data_to_pos
local remove = vector.remove_data_from_pos
2015-08-28 12:24:33 +02:00
2015-09-10 21:45:08 +02:00
-- if the wireless at pos isn't stored yet, put it into the tables
local function register_RID ( pos )
if get ( wireless_rids , pos.z , pos.y , pos.x ) then
return
2015-08-28 12:24:33 +02:00
end
2015-09-10 21:45:08 +02:00
local RID = # wireless + 1
wireless [ RID ] = pos
set ( wireless_rids , pos.z , pos.y , pos.x , RID )
2017-04-17 11:17:09 +02:00
update_mod_storage ( )
2015-08-28 12:24:33 +02:00
end
2015-09-10 21:45:08 +02:00
local is_jammed
local function wireless_activate ( pos )
if is_jammed ( pos ) then
-- jamming doesn't disallow receiving signals, only sending them
return
end
2016-04-27 18:42:20 +02:00
2015-09-10 21:45:08 +02:00
local channel_first_wireless = minetest.get_meta ( pos ) : get_string ( " channel " )
2016-04-27 14:04:39 +02:00
if channel_first_wireless == " " then
return
end
2016-04-27 18:42:20 +02:00
2015-08-28 12:24:33 +02:00
for i = 1 , # wireless do
2015-09-10 21:45:08 +02:00
if not vector.equals ( wireless [ i ] , pos )
and minetest.get_meta ( wireless [ i ] ) : get_string ( " channel " ) == channel_first_wireless then
2015-08-28 12:24:33 +02:00
mesecon.receptor_on ( wireless [ i ] )
end
2015-09-10 21:45:08 +02:00
end
2015-08-28 12:24:33 +02:00
end
2015-09-10 21:45:08 +02:00
local function wireless_deactivate ( pos )
if is_jammed ( pos ) then
return
end
local channel_first_wireless = minetest.get_meta ( pos ) : get_string ( " channel " )
2015-08-28 12:24:33 +02:00
for i = 1 , # wireless do
2015-09-10 21:45:08 +02:00
if not vector.equals ( wireless [ i ] , pos )
and minetest.get_meta ( wireless [ i ] ) : get_string ( " channel " ) == channel_first_wireless then
2015-08-28 12:24:33 +02:00
mesecon.receptor_off ( wireless [ i ] )
end
2015-09-10 21:45:08 +02:00
end
2015-08-28 12:24:33 +02:00
end
2016-04-24 14:19:51 +02:00
local function on_digiline_receive ( pos , node , channel , msg )
local setchan = minetest.get_meta ( pos ) : get_string ( " channel " ) -- Note : the digiline channel is the same as the wireless channel. TODO: Making two different channels and a more complex formspec ?
2016-04-27 14:04:39 +02:00
if channel ~= setchan or is_jammed ( pos ) or setchan == " " then
2016-04-24 14:19:51 +02:00
return
end
for i = 1 , # wireless do
if not vector.equals ( wireless [ i ] , pos )
and minetest.get_meta ( wireless [ i ] ) : get_string ( " channel " ) == channel then
digiline : receptor_send ( wireless [ i ] , digiline.rules . default , channel , msg )
end
end
end
2015-08-28 12:24:33 +02:00
minetest.register_node ( " moremesecons_wireless:wireless " , {
2015-08-30 11:49:32 +02:00
tiles = { " moremesecons_wireless.png " } ,
2015-08-28 12:24:33 +02:00
paramtype = " light " ,
paramtype2 = " facedir " ,
description = " Wireless " ,
walkable = true ,
2015-08-29 17:55:23 +02:00
groups = { cracky = 3 } ,
2015-08-28 12:24:33 +02:00
mesecons = { effector = {
action_on = wireless_activate ,
action_off = wireless_deactivate
} } ,
2016-04-24 14:19:51 +02:00
digiline = {
receptor = { } ,
effector = {
action = on_digiline_receive
} ,
} ,
2015-08-28 12:24:33 +02:00
sounds = default.node_sound_stone_defaults ( ) ,
on_construct = function ( pos )
2016-04-27 18:42:20 +02:00
minetest.get_meta ( pos ) : set_string ( " formspec " , " field[channel;channel;${channel}] " )
register_RID ( pos )
2015-08-28 12:24:33 +02:00
end ,
2015-08-31 11:25:29 +02:00
on_destruct = function ( pos )
2015-09-10 21:45:08 +02:00
local RID = get ( wireless_rids , pos.z , pos.y , pos.x )
2015-09-01 10:51:53 +02:00
if RID then
2015-08-31 11:25:29 +02:00
table.remove ( wireless , RID )
2017-04-17 11:17:09 +02:00
remove ( wireless_rids , pos.z , pos.y , pos.x )
update_mod_storage ( )
2015-08-31 11:25:29 +02:00
end
2015-09-10 21:52:49 +02:00
mesecon.receptor_off ( pos )
2015-08-31 11:25:29 +02:00
end ,
2016-04-27 18:42:20 +02:00
on_receive_fields = function ( pos , _ , fields , player )
if fields.channel
and not minetest.is_protected ( pos , player : get_player_name ( ) ) then
minetest.get_meta ( pos ) : set_string ( " channel " , fields.channel )
end
2015-08-28 12:24:33 +02:00
end ,
} )
2015-09-10 21:45:08 +02:00
local jammers = { }
local function add_jammer ( pos )
if get ( jammers , pos.z , pos.y , pos.x ) then
return
end
set ( jammers , pos.z , pos.y , pos.x , true )
2017-04-17 11:17:09 +02:00
update_mod_storage ( )
2015-09-10 21:45:08 +02:00
end
local function remove_jammer ( pos )
remove ( jammers , pos.z , pos.y , pos.x )
2017-04-17 11:17:09 +02:00
update_mod_storage ( )
2015-09-10 21:45:08 +02:00
end
-- looks big, but should work fast
function is_jammed ( pos )
2017-02-11 14:01:20 +01:00
local JAMMER_MAX_DISTANCE = tonumber ( minetest.setting_get ( " moremesecons_wireless.jammer_max_distance " ) ) or 15
if JAMMER_MAX_DISTANCE <= 0 then
JAMMER_MAX_DISTANCE = 1
2017-02-11 15:44:53 +01:00
elseif JAMMER_MAX_DISTANCE ~= JAMMER_MAX_DISTANCE then -- NaN
JAMMER_MAX_DISTANCE = 15
2017-02-11 14:01:20 +01:00
end
2015-09-10 21:45:08 +02:00
local pz , py , px = vector.unpack ( pos )
for z , yxs in pairs ( jammers ) do
if math.abs ( pz - z ) <= JAMMER_MAX_DISTANCE then
for y , xs in pairs ( yxs ) do
if math.abs ( py - y ) <= JAMMER_MAX_DISTANCE then
for x in pairs ( xs ) do
if math.abs ( px - x ) <= JAMMER_MAX_DISTANCE
and ( px - x ) ^ 2 + ( py - y ) ^ 2 + ( pz - z ) ^ 2 <= JAMMER_MAX_DISTANCE ^ 2 then
return true
end
end
end
end
end
end
return false
end
2015-09-10 18:33:07 +02:00
mesecon.register_node ( " moremesecons_wireless:jammer " , {
2015-09-10 22:46:27 +02:00
description = " Wireless Jammer " ,
2015-09-10 18:33:07 +02:00
paramtype = " light " ,
2015-09-10 22:46:27 +02:00
drawtype = " nodebox " ,
2015-09-10 18:33:07 +02:00
} , {
2015-09-10 22:46:27 +02:00
tiles = { " mesecons_wire_off.png^moremesecons_jammer_top.png " , " moremesecons_jammer_bottom.png " , " mesecons_wire_off.png^moremesecons_jammer_side_off.png " } ,
node_box = {
type = " fixed " ,
fixed = {
-- connection
{ - 1 / 16 , - 0.5 , - 0.5 , 1 / 16 , - 7 / 16 , 0.5 } ,
{ - 0.5 , - 0.5 , - 1 / 16 , 0.5 , - 7 / 16 , 1 / 16 } ,
--stabilization
{ - 1 / 16 , - 7 / 16 , - 1 / 16 , 1 / 16 , - 6 / 16 , 1 / 16 } ,
-- fields
{ - 7 / 16 , - 6 / 16 , - 7 / 16 , 7 / 16 , - 4 / 16 , 7 / 16 } ,
{ - 5 / 16 , - 4 / 16 , - 5 / 16 , 5 / 16 , - 3 / 16 , 5 / 16 } ,
{ - 3 / 16 , - 3 / 16 , - 3 / 16 , 3 / 16 , - 2 / 16 , 3 / 16 } ,
{ - 1 / 16 , - 2 / 16 , - 1 / 16 , 1 / 16 , - 1 / 16 , 1 / 16 } ,
} ,
} ,
2015-09-10 18:33:07 +02:00
groups = { dig_immediate = 2 } ,
mesecons = { effector = {
2016-04-23 11:52:15 +02:00
rules = mesecon.rules . flat ,
2015-09-10 18:33:07 +02:00
action_on = function ( pos )
2015-09-10 21:45:08 +02:00
add_jammer ( pos )
2015-09-10 18:33:07 +02:00
minetest.swap_node ( pos , { name = " moremesecons_wireless:jammer_on " } )
2015-09-10 21:45:08 +02:00
end
} }
2015-09-10 18:33:07 +02:00
} , {
2015-09-10 22:46:27 +02:00
tiles = { " mesecons_wire_on.png^moremesecons_jammer_top.png " , " moremesecons_jammer_bottom.png " , " mesecons_wire_on.png^moremesecons_jammer_side_on.png " } ,
node_box = {
type = " fixed " ,
fixed = {
-- connection
{ - 1 / 16 , - 0.5 , - 0.5 , 1 / 16 , - 7 / 16 , 0.5 } ,
{ - 0.5 , - 0.5 , - 1 / 16 , 0.5 , - 7 / 16 , 1 / 16 } ,
--stabilization
{ - 1 / 16 , - 7 / 16 , - 1 / 16 , 1 / 16 , 5 / 16 , 1 / 16 } ,
-- fields
{ - 7 / 16 , - 6 / 16 , - 7 / 16 , 7 / 16 , - 4 / 16 , 7 / 16 } ,
{ - 5 / 16 , - 3 / 16 , - 5 / 16 , 5 / 16 , - 1 / 16 , 5 / 16 } ,
{ - 3 / 16 , 0 , - 3 / 16 , 3 / 16 , 2 / 16 , 3 / 16 } ,
{ - 1 / 16 , 3 / 16 , - 1 / 16 , 1 / 16 , 5 / 16 , 1 / 16 } ,
} ,
} ,
2015-09-10 18:33:07 +02:00
groups = { dig_immediate = 2 , not_in_creative_inventory = 1 } ,
mesecons = { effector = {
2016-04-23 11:52:15 +02:00
rules = mesecon.rules . flat ,
2015-09-10 18:33:07 +02:00
action_off = function ( pos )
2015-09-10 21:45:08 +02:00
remove_jammer ( pos )
2015-09-10 18:33:07 +02:00
minetest.swap_node ( pos , { name = " moremesecons_wireless:jammer_off " } )
2015-09-10 21:45:08 +02:00
end
} } ,
on_destruct = remove_jammer ,
on_construct = add_jammer ,
2015-09-10 18:33:07 +02:00
} )
minetest.register_craft ( {
output = " moremesecons_wireless:jammer_off " ,
recipe = {
{ " moremesecons_wireless:wireless " , " mesecons_torch:mesecon_torch_on " , " moremesecons_wireless:wireless " }
}
} )
2015-08-28 12:24:33 +02:00
minetest.register_craft ( {
output = " moremesecons_wireless:wireless 2 " ,
recipe = {
{ " group:mesecon_conductor_craftable " , " " , " group:mesecon_conductor_craftable " } ,
2015-08-30 11:49:32 +02:00
{ " " , " mesecons_torch:mesecon_torch_on " , " " } ,
2015-08-28 12:24:33 +02:00
{ " group:mesecon_conductor_craftable " , " " , " group:mesecon_conductor_craftable " } ,
}
} )