1- require  " config" 
2- 
31--  constant prototypes names
42local  SENSOR  =  " item-sensor" 
53
@@ -33,106 +31,157 @@ local floor = math.floor
3331local  ceil  =  math.ceil 
3432
3533
36- ----  Events ----
37- 
38- function  init_events ()
39- 	script .on_event ({defines .events .on_built_entity , defines .events .on_robot_built_entity }, OnEntityCreated )
40- 	if  global .ItemSensors  and  # global .ItemSensors  >  0  then 
41- 		script .on_event (defines .events .on_tick , OnTick )
42- 		script .on_event ({defines .events .on_preplayer_mined_item , defines .events .on_robot_pre_mined , defines .events .on_entity_died }, OnEntityRemoved )
43- 	end 
44- end 
45- 
46- script .on_init (function ()
47-   global .ItemSensors  =  global .ItemSensors  or  {}
48-   init_events ()
34+ ----  MOD SETTINGS ----
35+ 
36+ local  UpdateInterval  =  settings .global [" inv_sensor_update_interval"  ].value 
37+ local  ScanInterval  =  settings .global [" inv_sensor_find_entity_interval"  ].value 
38+ local  ScanOffset  =  settings .global [" inv_sensor_BBox_offset"  ].value 
39+ local  ScanRange  =  settings .global [" inv_sensor_BBox_range"  ].value 
40+ 
41+ script .on_event (defines .events .on_runtime_mod_setting_changed , function (event )
42+   if  event .setting  ==  " inv_sensor_update_interval"  then 
43+     UpdateInterval  =  settings .global [" inv_sensor_update_interval"  ].value 
44+     ResetStride ()
45+   end 
46+   if  event .setting  ==  " inv_sensor_find_entity_interval"  then 
47+     ScanInterval  =  settings .global [" inv_sensor_find_entity_interval"  ].value 
48+   end 
49+   if  event .setting  ==  " inv_sensor_BBox_offset"  then 
50+     ScanOffset  =  settings .global [" inv_sensor_BBox_offset"  ].value 
51+     ResetSensors ()
52+   end 
53+   if  event .setting  ==  " inv_sensor_BBox_range"  then 
54+     ScanRange  =  settings .global [" inv_sensor_BBox_range"  ].value 
55+     ResetSensors ()
56+   end 
4957end )
5058
51- script .on_load (function ()
52-   init_events ()
53- end )
5459
55- script .on_configuration_changed (function (data )
56- 	global .ItemSensors  =  global .ItemSensors  or  {}
57- 	for  i = 1 , # global .ItemSensors  do 
58- 		local  itemSensor  =  global .ItemSensors [i ]
59- 		itemSensor .ID  =  itemSensor .Sensor .unit_number 
60- 		itemSensor .ScanArea  =  GetScanArea (itemSensor .Sensor )
61- 		itemSensor .ConnectedEntity  =  nil 
62- 		itemSensor .Inventory  =  {}
63- 		SetConnectedEntity (itemSensor )
64- 	end 
65- 	init_events ()
66- end )
60+ ----  EVENTS ----
6761
6862function  OnEntityCreated (event )
6963	if  (event .created_entity .name  ==  " item-sensor"  ) then 
70- 		CreateItemSensor (event .created_entity )
64+     local  entity  =  event .created_entity 
65+     global .ItemSensors  =  global .ItemSensors  or  {}
66+ 
67+     entity .operable  =  false 
68+     entity .rotatable  =  false 
69+     local  itemSensor  =  {}
70+     itemSensor .ID  =  entity .unit_number 
71+     itemSensor .Sensor  =  entity 
72+     itemSensor .ScanArea  =  GetScanArea (entity )
73+     SetConnectedEntity (itemSensor )
74+ 
75+     global .ItemSensors [# global .ItemSensors + 1 ] =  itemSensor 
76+ 
7177		if  # global .ItemSensors  ==  1  then 
7278			script .on_event (defines .events .on_tick , OnTick )
7379			script .on_event ({defines .events .on_preplayer_mined_item , defines .events .on_robot_pre_mined , defines .events .on_entity_died }, OnEntityRemoved )
7480		end 
81+     
82+     ResetStride ()
7583	end 
7684end 
7785
7886function  OnEntityRemoved (event )
7987--  script.on_event({defines.events.on_preplayer_mined_item, defines.events.on_robot_pre_mined, defines.events.on_entity_died}, function(event)
8088	if  event .entity .name  ==  SENSOR  then 
81- 		RemoveItemSensor (event .entity )
89+     for  i =# global .ItemSensors , 1 , - 1  do 
90+       if  event .entity .unit_number  ==  global .ItemSensors [i ].ID  then 
91+         table.remove (global .ItemSensors ,i )
92+       end 
93+     end 
94+ 
8295		if  # global .ItemSensors  ==  0  then 
8396			script .on_event (defines .events .on_tick , nil )
8497			script .on_event ({defines .events .on_preplayer_mined_item , defines .events .on_robot_pre_mined , defines .events .on_entity_died }, nil )
8598		end 
99+     
100+     ResetStride ()
86101	end 
87102end 
88103
104+ 
89105function  OnTick (event )
90- 	local  tick  =  game .tick 
91- 	for  i = 1 , # global .ItemSensors  do 
92- 		local  itemSensor  =  global .ItemSensors [i ]
93- 		if  not  itemSensor .SkipEntityScanning  and  (i  +  tick ) %  find_entity_interval  ==  0  then 
94- 			SetConnectedEntity (itemSensor )
95- 		end 
96- 		if  (i  +  tick ) %  update_interval  ==  0  then 
97- 			UpdateSensor (itemSensor )
98- 		end 
99- 	end 
106+   global .tickCount  =  global .tickCount  or  1 
107+   global .SensorIndex  =  global .SensorIndex  or  1 
108+ 
109+   --  only work if index is within bounds
110+   if  global .SensorIndex  <=  # global .ItemSensors  then 
111+     local  lastIndex  =  global .SensorIndex  +  global .SensorStride  -  1 
112+     if  lastIndex  >=  # global .ItemSensors  then 
113+       lastIndex  =  # global .ItemSensors 
114+     end 
115+ 
116+     --  log("[IS] "..global.tickCount.." / "..game.tick.." updating sensors "..global.SensorIndex.." to "..lastIndex)
117+     for  i = global .SensorIndex , lastIndex  do 
118+       local  itemSensor  =  global .ItemSensors [i ]
119+       --  log("[IS] skipScan: "..tostring(itemSensor.SkipEntityScanning).." LastScan: "..tostring(itemSensor.LastScanned).."/"..game.tick)
120+       if  not  itemSensor .SkipEntityScanning  and  (game .tick  -  itemSensor .LastScanned ) >=  ScanInterval  then 
121+         SetConnectedEntity (itemSensor )
122+       end 
123+       
124+       UpdateSensor (itemSensor )      
125+     end 
126+     global .SensorIndex  =  lastIndex  +  1 
127+   end 
128+ 
129+   --  reset clock and chest index
130+   if  global .tickCount  <  UpdateInterval  then 
131+     global .tickCount  =  global .tickCount  +  1 
132+   else 
133+     global .tickCount  =  1 
134+     global .SensorIndex  =  1 
135+   end 
100136end 
101137
102- 
103- ----  Logic ----
104- 
105- function  CreateItemSensor (entity )
106- 	global .ItemSensors  =  global .ItemSensors  or  {}
107- 
108- 	entity .operable  =  false 
109- 	entity .rotatable  =  false 
110- 	local  itemSensor  =  {}
111- 	itemSensor .ID  =  entity .unit_number 
112- 	itemSensor .Sensor  =  entity 
113- 	itemSensor .ScanArea  =  GetScanArea (entity )
114- 	SetConnectedEntity (itemSensor )
115- 
116- 	global .ItemSensors [# global .ItemSensors + 1 ] =  itemSensor 
138+ --  function OnTick(event)
139+ 	--  local tick = game.tick
140+ 	--  for i=1, #global.ItemSensors do
141+ 		--  local itemSensor = global.ItemSensors[i]
142+ 		--  if not itemSensor.SkipEntityScanning and (i + tick) % ScanInterval == 0 then
143+ 			--  SetConnectedEntity(itemSensor)
144+ 		--  end
145+ 		--  if (i + tick) % UpdateInterval == 0 then
146+ 			--  UpdateSensor(itemSensor)
147+ 		--  end
148+ 	--  end
149+ --  end
150+ 
151+ ----  LOGIC ----
152+ 
153+ --  recalculates how many sensors are updated each tick
154+ function  ResetStride ()
155+   if  # global .ItemSensors  >  UpdateInterval  then 
156+     global .SensorStride  =   math.ceil (# global .ItemSensors / UpdateInterval )
157+   else 
158+     global .SensorStride  =  1 
159+   end 
160+   log (" [IS] sride set to " .. global .SensorStride )
117161end 
118162
119- function  RemoveItemSensor (entity )
120- 	for  i =# global .ItemSensors , 1 , - 1  do 
121- 		if  entity .unit_number  ==  global .ItemSensors [i ].ID  then 
122- 			table.remove (global .ItemSensors ,i )
123- 		end 
163+ 
164+ function  ResetSensors ()
165+   global .ItemSensors  =  global .ItemSensors  or  {}
166+ 	for  i = 1 , # global .ItemSensors  do 
167+ 		local  itemSensor  =  global .ItemSensors [i ]
168+ 		itemSensor .ID  =  itemSensor .Sensor .unit_number 
169+ 		itemSensor .ScanArea  =  GetScanArea (itemSensor .Sensor )
170+ 		itemSensor .ConnectedEntity  =  nil 
171+ 		itemSensor .Inventory  =  {}
172+ 		SetConnectedEntity (itemSensor )
124173	end 
125174end 
126175
127176function  GetScanArea (sensor )
128177	if  sensor .direction  ==  0  then  -- south
129- 		 return {{sensor .position .x  -  BBox_offset , sensor .position .y }, {sensor .position .x  +  BBox_offset , sensor .position .y  +  BBox_range }}
178+ 		 return {{sensor .position .x  -  ScanOffset , sensor .position .y }, {sensor .position .x  +  ScanOffset , sensor .position .y  +  ScanRange }}
130179	elseif  sensor .direction  ==  2  then  -- west
131- 		return {{sensor .position .x  -  BBox_range , sensor .position .y  -  BBox_offset }, {sensor .position .x , sensor .position .y  +  BBox_offset }}
180+ 		return {{sensor .position .x  -  ScanRange , sensor .position .y  -  ScanOffset }, {sensor .position .x , sensor .position .y  +  ScanOffset }}
132181	elseif  sensor .direction  ==  4  then  -- north
133- 		return {{sensor .position .x  -  BBox_offset , sensor .position .y  -  BBox_range }, {sensor .position .x  +  BBox_offset , sensor .position .y }}
182+ 		return {{sensor .position .x  -  ScanOffset , sensor .position .y  -  ScanRange }, {sensor .position .x  +  ScanOffset , sensor .position .y }}
134183	elseif  sensor .direction  ==  6  then  -- east
135- 		return {{sensor .position .x , sensor .position .y  -  BBox_offset }, {sensor .position .x  +  BBox_range , sensor .position .y  +  BBox_offset }}
184+ 		return {{sensor .position .x , sensor .position .y  -  ScanOffset }, {sensor .position .x  +  ScanRange , sensor .position .y  +  ScanOffset }}
136185	end 
137186end 
138187
@@ -143,14 +192,15 @@ function SetInventories(itemSensor, entity)
143192		inv  =  entity .get_inventory (i )
144193		if  inv  then 
145194			itemSensor .Inventory [# itemSensor .Inventory + 1 ] =  inv 
146- 			--  log("adding inventory "..tostring(inv.index))
195+ 			--  log("[IS]  adding inventory "..tostring(inv.index))
147196		end 
148197	end 
149198end 
150199
151200function  SetConnectedEntity (itemSensor )
201+   itemSensor .LastScanned  =  game .tick 
152202	local  connectedEntities  =  itemSensor .Sensor .surface .find_entities (itemSensor .ScanArea )
153- 	-- printmsg("Found "..#connectedEntities.." entities in direction "..sensor.direction)
203+ 	-- printmsg("[IS]  Found "..#connectedEntities.." entities in direction "..sensor.direction)
154204	if  connectedEntities  then 
155205		for  i = 1 , # connectedEntities  do 
156206			local  entity  =  connectedEntities [i ]
@@ -185,7 +235,7 @@ function UpdateSensor(itemSensor)
185235	if  connectedEntity .type  ==  LOCO  then 
186236		if  connectedEntity .train .state  ==  defines .train_state .wait_station 
187237		or  connectedEntity .train .state  ==  defines .train_state .wait_signal 
188- 		or  connectedEntity .train .state  ==  defines .train_state .manual_control  then  -- keeps showing inventory for find_entity_interval  ticks after movement start > neglect able
238+ 		or  connectedEntity .train .state  ==  defines .train_state .manual_control  then  -- keeps showing inventory for ScanInterval  ticks after movement start > neglect able
189239			signals [signalIndex ] =  {index  =  signalIndex , signal = {type = " virtual"  ,name = " inv-sensor-detected-locomotive"  },count = 1 }
190240			signalIndex  =  signalIndex + 1 
191241		else  --  train is moving > remove connection
@@ -198,7 +248,7 @@ function UpdateSensor(itemSensor)
198248	elseif  connectedEntity .type  ==  WAGON  or  connectedEntity .type  ==  WAGONFLUID  then 
199249		if  connectedEntity .train .state  ==  defines .train_state .wait_station 
200250		or  connectedEntity .train .state  ==  defines .train_state .wait_signal 
201- 		or  connectedEntity .train .state  ==  defines .train_state .manual_control  then  -- keeps showing inventory for find_entity_interval  ticks after movement start > neglect able
251+ 		or  connectedEntity .train .state  ==  defines .train_state .manual_control  then  -- keeps showing inventory for ScanInterval  ticks after movement start > neglect able
202252			signals [signalIndex ] =  {index  =  signalIndex , signal = {type = " virtual"  ,name = " inv-sensor-detected-wagon"  },count = 1 }
203253			signalIndex  =  signalIndex + 1 
204254		else  --  train is moving > remove connection
@@ -281,3 +331,33 @@ function UpdateSensor(itemSensor)
281331
282332	sensor .get_control_behavior ().parameters  =  {parameters = signals }
283333end 
334+ 
335+ 
336+ ----  INIT ----
337+ do 
338+ local  function  init_events ()
339+ 	script .on_event ({defines .events .on_built_entity , defines .events .on_robot_built_entity }, OnEntityCreated )
340+ 	if  global .ItemSensors  and  # global .ItemSensors  >  0  then 
341+ 		script .on_event (defines .events .on_tick , OnTick )
342+ 		script .on_event ({defines .events .on_preplayer_mined_item , defines .events .on_robot_pre_mined , defines .events .on_entity_died }, OnEntityRemoved )
343+ 	end 
344+ end 
345+ 
346+ script .on_load (function ()
347+   init_events ()
348+ end )
349+ 
350+ script .on_init (function ()
351+   global .ItemSensors  =  global .ItemSensors  or  {}
352+   ResetStride ()
353+   init_events ()
354+ end )
355+ 
356+ script .on_configuration_changed (function (data )
357+   ResetSensors ()
358+   ResetStride ()
359+ 	init_events ()
360+   log (" [IS] on_config_changed complete."  )
361+ end )
362+ 
363+ end 
0 commit comments