[WIP][0.12.22+] Subsurfaces 0.0.4 : build beneath your base

Topics and discussion about specific mods
seronis
Fast Inserter
Fast Inserter
Posts: 225
Joined: Fri Mar 04, 2016 8:04 pm
Contact:

Re: [WIP][0.12.22+] Subsurfaces 0.0.4 : build beneath your base

Post by seronis »

From my experience its safe. But as with any mod for any game, USER BEWARE. Things can always go wrong so expect that there is a non zero chance of save corruption. But anyone who uses mods for any game should know to keep multiple saves and not just keep saving overtop of your more recent one. Be smart and the rare chance of corruption wont matter
User avatar
Galacticruler
Long Handed Inserter
Long Handed Inserter
Posts: 56
Joined: Sat Apr 16, 2016 5:18 pm
Contact:

Re: [WIP][0.12.22+] Subsurfaces 0.0.4 : build beneath your base

Post by Galacticruler »

so I've been watching this for a while and I think it looks quite interesting. I also have a suggestion; The player should be required to place something like power poles to keep areas from collapsing back in.
PC is best.
User avatar
StanFear
Fast Inserter
Fast Inserter
Posts: 236
Joined: Sun Dec 15, 2013 2:49 pm
Contact:

Re: [WIP][0.12.22+] Subsurfaces 0.0.4 : build beneath your base

Post by StanFear »

Galacticruler wrote:so I've been watching this for a while and I think it looks quite interesting. I also have a suggestion; The player should be required to place something like power poles to keep areas from collapsing back in.
Yes, this in something I intend to implement, I just have more important stuff to do first (like making the automated digging work correctly for instance :D)

but yes it will be there, and I think I have an idea on how to implement that

I also will try to implement special lights and power poles that can only be built underground and that are attached to the roof, making it have no colision with the ground (can walk under, drive under, build under, etc.)
it is not my priority thoughfirst things first as they say !
deareim wrote:Mod seems very interesting ! In the original post, it is said that it could corrupt our actual save. Is it still the case or is it secure to use it ?
seronis wrote:From my experience its safe. But as with any mod for any game, USER BEWARE. Things can always go wrong so expect that there is a non zero chance of save corruption. But anyone who uses mods for any game should know to keep multiple saves and not just keep saving overtop of your more recent one. Be smart and the rare chance of corruption wont matter
well, indeed, it is probably safe to use, but in the developping process, I had a few times where I could not load the game because it said there was an error, I should have removed all of thoses, but I might have missed one or two.
so ... yeah, have fun but be careful: keep a backup just in case I missed something somewhere

StanFear wrote: oh, ok, I see what happened ... I messed up, changed some graphics but not the the size of it ...
I'll fix it and upload a new version (I have a few changes to make first though, so the upload will probably not be until tomorrow)
well, I think it won't be for today eather, got caught up in refactoring some code ...
since this is only a graphical bug, I think you won't mind having to wait a bit ? (that way I can do more than just a bugfix release)
deareim
Burner Inserter
Burner Inserter
Posts: 5
Joined: Sun Apr 10, 2016 6:55 am
Contact:

Re: [WIP][0.12.22+] Subsurfaces 0.0.4 : build beneath your base

Post by deareim »

Ok thanks for the information.
Exasperation
Long Handed Inserter
Long Handed Inserter
Posts: 88
Joined: Fri Apr 22, 2016 9:55 pm
Contact:

Re: [WIP][0.12.22+] Subsurfaces 0.0.4 : build beneath your base

Post by Exasperation »

First off, I want to say that this mod has a lot of potential and I look forward to seeing where you go with it.

Second, I had some trouble with the independent item elevators as well, and decided to look into the code to see if I could figure out what was going on.

It looks like there are some sign errors in the elevator placement for the east-west elevators.

Code: Select all

			if string.find(_entity.name, "upperside") then
				if _entity.direction == defines.direction.north then
					input_item_elevator = _entity.surface.create_entity{name = "fast-transport-belt", position = {x = _entity.position.x - 0.5, y = _entity.position.y + 0.5}, force=_entity.force}
					output_item_elevator = _entity.surface.create_entity{name = "fast-transport-belt", position = {x = _entity.position.x + 0.5, y = _entity.position.y - 0.5}, force=_entity.force}
				elseif _entity.direction == defines.direction.east then
					input_item_elevator = _entity.surface.create_entity{name = "fast-transport-belt", position = {x = _entity.position.x + 0.5, y = _entity.position.y + 0.5}, force=_entity.force}
					output_item_elevator = _entity.surface.create_entity{name = "fast-transport-belt", position = {x = _entity.position.x - 0.5, y = _entity.position.y - 0.5}, force=_entity.force}
				elseif _entity.direction == defines.direction.south then
					input_item_elevator = _entity.surface.create_entity{name = "fast-transport-belt", position = {x = _entity.position.x + 0.5, y = _entity.position.y - 0.5}, force=_entity.force}
					output_item_elevator = _entity.surface.create_entity{name = "fast-transport-belt", position = {x = _entity.position.x - 0.5, y = _entity.position.y + 0.5}, force=_entity.force}
				elseif _entity.direction == defines.direction.west then
					input_item_elevator = _entity.surface.create_entity{name = "fast-transport-belt", position = {x = _entity.position.x - 0.5, y = _entity.position.y - 0.5}, force=_entity.force}
					output_item_elevator = _entity.surface.create_entity{name = "fast-transport-belt", position = {x = _entity.position.x + 0.5, y = _entity.position.y + 0.5}, force=_entity.force}
				end
			else -- if string.find(_entity.name, "lowerside")
				if _entity.direction == defines.direction.north then
					output_item_elevator = _entity.surface.create_entity{name = "fast-transport-belt", position = {x = _entity.position.x - 0.5, y = _entity.position.y - 0.5}, force=_entity.force}
					input_item_elevator = _entity.surface.create_entity{name = "fast-transport-belt", position = {x = _entity.position.x + 0.5, y = _entity.position.y + 0.5}, force=_entity.force}
				elseif _entity.direction == defines.direction.east then
					output_item_elevator = _entity.surface.create_entity{name = "fast-transport-belt", position = {x = _entity.position.x - 0.5, y = _entity.position.y + 0.5}, force=_entity.force}
					input_item_elevator = _entity.surface.create_entity{name = "fast-transport-belt", position = {x = _entity.position.x + 0.5, y = _entity.position.y - 0.5}, force=_entity.force}
				elseif _entity.direction == defines.direction.south then
					output_item_elevator = _entity.surface.create_entity{name = "fast-transport-belt", position = {x = _entity.position.x + 0.5, y = _entity.position.y + 0.5}, force=_entity.force}
					input_item_elevator = _entity.surface.create_entity{name = "fast-transport-belt", position = {x = _entity.position.x - 0.5, y = _entity.position.y - 0.5}, force=_entity.force}
				elseif _entity.direction == defines.direction.west then
					output_item_elevator = _entity.surface.create_entity{name = "fast-transport-belt", position = {x = _entity.position.x + 0.5, y = _entity.position.y - 0.5}, force=_entity.force}
					input_item_elevator = _entity.surface.create_entity{name = "fast-transport-belt", position = {x = _entity.position.x - 0.5, y = _entity.position.y + 0.5}, force=_entity.force}
				end
			end
should be

Code: Select all

			if string.find(_entity.name, "upperside") then
				if _entity.direction == defines.direction.north then
					input_item_elevator = _entity.surface.create_entity{name = "fast-transport-belt", position = {x = _entity.position.x - 0.5, y = _entity.position.y + 0.5}, force=_entity.force}
					output_item_elevator = _entity.surface.create_entity{name = "fast-transport-belt", position = {x = _entity.position.x + 0.5, y = _entity.position.y - 0.5}, force=_entity.force}
				elseif _entity.direction == defines.direction.east then
					input_item_elevator = _entity.surface.create_entity{name = "fast-transport-belt", position = {x = _entity.position.x - 0.5, y = _entity.position.y - 0.5}, force=_entity.force}
					output_item_elevator = _entity.surface.create_entity{name = "fast-transport-belt", position = {x = _entity.position.x + 0.5, y = _entity.position.y + 0.5}, force=_entity.force}
				elseif _entity.direction == defines.direction.south then
					input_item_elevator = _entity.surface.create_entity{name = "fast-transport-belt", position = {x = _entity.position.x + 0.5, y = _entity.position.y - 0.5}, force=_entity.force}
					output_item_elevator = _entity.surface.create_entity{name = "fast-transport-belt", position = {x = _entity.position.x - 0.5, y = _entity.position.y + 0.5}, force=_entity.force}
				elseif _entity.direction == defines.direction.west then
					input_item_elevator = _entity.surface.create_entity{name = "fast-transport-belt", position = {x = _entity.position.x + 0.5, y = _entity.position.y + 0.5}, force=_entity.force}
					output_item_elevator = _entity.surface.create_entity{name = "fast-transport-belt", position = {x = _entity.position.x - 0.5, y = _entity.position.y - 0.5}, force=_entity.force}
				end
			else -- if string.find(_entity.name, "lowerside")
				if _entity.direction == defines.direction.north then
					output_item_elevator = _entity.surface.create_entity{name = "fast-transport-belt", position = {x = _entity.position.x - 0.5, y = _entity.position.y - 0.5}, force=_entity.force}
					input_item_elevator = _entity.surface.create_entity{name = "fast-transport-belt", position = {x = _entity.position.x + 0.5, y = _entity.position.y + 0.5}, force=_entity.force}
				elseif _entity.direction == defines.direction.east then
					output_item_elevator = _entity.surface.create_entity{name = "fast-transport-belt", position = {x = _entity.position.x + 0.5, y = _entity.position.y - 0.5}, force=_entity.force}
					input_item_elevator = _entity.surface.create_entity{name = "fast-transport-belt", position = {x = _entity.position.x - 0.5, y = _entity.position.y + 0.5}, force=_entity.force}
				elseif _entity.direction == defines.direction.south then
					output_item_elevator = _entity.surface.create_entity{name = "fast-transport-belt", position = {x = _entity.position.x + 0.5, y = _entity.position.y + 0.5}, force=_entity.force}
					input_item_elevator = _entity.surface.create_entity{name = "fast-transport-belt", position = {x = _entity.position.x - 0.5, y = _entity.position.y - 0.5}, force=_entity.force}
				elseif _entity.direction == defines.direction.west then
					output_item_elevator = _entity.surface.create_entity{name = "fast-transport-belt", position = {x = _entity.position.x - 0.5, y = _entity.position.y + 0.5}, force=_entity.force}
					input_item_elevator = _entity.surface.create_entity{name = "fast-transport-belt", position = {x = _entity.position.x + 0.5, y = _entity.position.y - 0.5}, force=_entity.force}
				end
			end
additionally, I noticed the following lines of code in move_items:

Code: Select all

					local item_to_move = {name = "", count = 1}
					for name, count in pairs(lane_input.get_contents()) do
						item_to_move.name = name
						break
					end
while this works, you could replace it with

Code: Select all

					local item_to_move = {name = next(lane_input.get_contents()), count = 1}
and it does the same thing, but with a little less overhead.
User avatar
StanFear
Fast Inserter
Fast Inserter
Posts: 236
Joined: Sun Dec 15, 2013 2:49 pm
Contact:

Re: [WIP][0.12.22+] Subsurfaces 0.0.4 : build beneath your base

Post by StanFear »

Exasperation wrote:First off, I want to say that this mod has a lot of potential and I look forward to seeing where you go with it.

Second, I had some trouble with the independent item elevators as well, and decided to look into the code to see if I could figure out what was going on.

additionally, I noticed the following lines of code in move_items:

Code: Select all

					local item_to_move = {name = "", count = 1}
					for name, count in pairs(lane_input.get_contents()) do
						item_to_move.name = name
						break
					end
while this works, you could replace it with

Code: Select all

					local item_to_move = {name = next(lane_input.get_contents()), count = 1}
and it does the same thing, but with a little less overhead.
ok, the part for the move item is indeed better, at the time I codded this, I had no idea of the next() function...

the part where I build the elevator items, I will double check to understand how I could get it wrong
I think that once I make the change, I'll upload a new version !
Szentigrade
Fast Inserter
Fast Inserter
Posts: 109
Joined: Mon Mar 28, 2016 7:27 am
Contact:

Re: [WIP][0.12.22+] Subsurfaces 0.0.4 : build beneath your base

Post by Szentigrade »

Hi, we have been noticing that your mod has a high readout on script update compared to all other mods we're using. Had a bit of a dig and it turns out you have a lot of functions running every tick, other mod authors have got things running less often using timers. Saw what you did with the digging robot center but the item elevators seem to cause a bit of lag, we were also having desync errors earlier that we couldn't pinpoint. Might be unrelated, but thought it would be necessary to inform you.
Simcra
Long Handed Inserter
Long Handed Inserter
Posts: 76
Joined: Wed Apr 06, 2016 6:05 am
Contact:

Re: [WIP][0.12.22+] Subsurfaces 0.0.4 : build beneath your base

Post by Simcra »

We are getting a desync error in multiplayer whenever items get stuck in the independent item elevators, as well as when they get stuck in the item elevators that come with the surface drill. Isolated the issue from earlier, I think it has something to do with the move_items function.
Exasperation
Long Handed Inserter
Long Handed Inserter
Posts: 88
Joined: Fri Apr 22, 2016 9:55 pm
Contact:

Re: [WIP][0.12.22+] Subsurfaces 0.0.4 : build beneath your base

Post by Exasperation »

StanFear wrote:the part where I build the elevator items, I will double check to understand how I could get it wrong
I think that once I make the change, I'll upload a new version !
Basically, the coordinates for the input and output belts got swapped around for the elevators facing east/west. I tested it by using inserters to load items onto (what should be) the output belts. Then I made the changes to elevator placement and placed new elevators and the new ones worked right.
Anduin1357
Burner Inserter
Burner Inserter
Posts: 5
Joined: Sun Apr 24, 2016 7:44 am
Contact:

Re: [WIP][0.12.22+] Subsurfaces 0.0.4 : build beneath your base

Post by Anduin1357 »

There's an issue with the fluid elevator;
I made some changes and found

Code: Select all

base_level = -1,
and incorrect positions for pipe_connections at fault.
Also, there are jarring graphical inaccuracies with the subsurface ground textures and the fluid elevator texture.

Thanks for the awesome mod!

Edit: The passive air vents actually moves pollution to the subsurface instead of moving it out.
The powered active vents do as advertised though.
User avatar
StanFear
Fast Inserter
Fast Inserter
Posts: 236
Joined: Sun Dec 15, 2013 2:49 pm
Contact:

Re: [WIP][0.12.22+] Subsurfaces 0.0.4 : build beneath your base

Post by StanFear »

Anduin1357 wrote:There's an issue with the fluid elevator;
I made some changes and found

Code: Select all

base_level = -1,
and incorrect positions for pipe_connections at fault.
Also, there are jarring graphical inaccuracies with the subsurface ground textures and the fluid elevator texture.

Thanks for the awesome mod!

Edit: The passive air vents actually moves pollution to the subsurface instead of moving it out.
The powered active vents do as advertised though.

well, the base_level = -1 is not an error, it just make you have to use a pump to output from it
the fact that the pipes are not alligned with the graphics is known and is warned on the main post

as to the passive air vent, what it does is slowly set the polution to the same ammount on the surface and subsurface
so if the pollution level on the surface is higher than on the subsurface, it is to be expected to have the pollution move down to the subsurface
User avatar
Lutra
Long Handed Inserter
Long Handed Inserter
Posts: 54
Joined: Fri Apr 01, 2016 9:22 pm
Contact:

Re: [WIP][0.12.22+] Subsurfaces 0.0.4 : build beneath your base

Post by Lutra »

can you make a vent that takes pollution down a level? or is that too cheaty
Ph'nglui mglw'nafh Cthulhu R'lyeh wgah'nagl fhtagn
User avatar
StanFear
Fast Inserter
Fast Inserter
Posts: 236
Joined: Sun Dec 15, 2013 2:49 pm
Contact:

Re: [WIP][0.12.22+] Subsurfaces 0.0.4 : build beneath your base

Post by StanFear »

Lutra wrote:can you make a vent that takes pollution down a level? or is that too cheaty
do you want it just to get rid of the pollution to some surface you'll never go to ? or is there a real reason (and of so, which is it?)
If the answer is yes to the first, then I won't. if you can provide me with a good reason to have that, I'll think about it!
Exasperation
Long Handed Inserter
Long Handed Inserter
Posts: 88
Joined: Fri Apr 22, 2016 9:55 pm
Contact:

Re: [WIP][0.12.22+] Subsurfaces 0.0.4 : build beneath your base

Post by Exasperation »

Simcra wrote:We are getting a desync error in multiplayer whenever items get stuck in the independent item elevators, as well as when they get stuck in the item elevators that come with the surface drill. Isolated the issue from earlier, I think it has something to do with the move_items function.
After seeing the discussion on this in the Modding Help thread you made, I had a go at fixing it. Here's a version of control.lua that might fix the desync. (I couldn't test it in multiplayer, but I did do a basic sanity check in single player - started a new game, dug a hole, went below - so I think I at least didn't break anything.)
Attachments
control.lua
Maybe better?
(61.82 KiB) Downloaded 132 times
Simcra
Long Handed Inserter
Long Handed Inserter
Posts: 76
Joined: Wed Apr 06, 2016 6:05 am
Contact:

Re: [WIP][0.12.22+] Subsurfaces 0.0.4 : build beneath your base

Post by Simcra »

Exasperation wrote:
Simcra wrote:We are getting a desync error in multiplayer whenever items get stuck in the independent item elevators, as well as when they get stuck in the item elevators that come with the surface drill. Isolated the issue from earlier, I think it has something to do with the move_items function.
After seeing the discussion on this in the Modding Help thread you made, I had a go at fixing it. Here's a version of control.lua that might fix the desync. (I couldn't test it in multiplayer, but I did do a basic sanity check in single player - started a new game, dug a hole, went below - so I think I at least didn't break anything.)
Yeah tried removing the global onTick stuff since we shouldn't be using global variables to store method information - see post in-context (viewtopic.php?f=25&t=24171&p=152497#p152362)

Even after that it still seems to desync, I'm suspecting it's something stupidly simple. If you want I can supply the whole control.lua, just be prepared I've had to modify quite a lot to reduce the lag in our multiplayer. (gone from having script update over 4ms to just under 1ms with the changes I've done, digging robots don't cause lag anymore, etc.) Hope not to step on anyones toes.
Simcra
Long Handed Inserter
Long Handed Inserter
Posts: 76
Joined: Wed Apr 06, 2016 6:05 am
Contact:

Re: [WIP][0.12.22+] Subsurfaces 0.0.4 : build beneath your base

Post by Simcra »

Simcra wrote:
Exasperation wrote:
Simcra wrote:We are getting a desync error in multiplayer whenever items get stuck in the independent item elevators, as well as when they get stuck in the item elevators that come with the surface drill. Isolated the issue from earlier, I think it has something to do with the move_items function.
After seeing the discussion on this in the Modding Help thread you made, I had a go at fixing it. Here's a version of control.lua that might fix the desync. (I couldn't test it in multiplayer, but I did do a basic sanity check in single player - started a new game, dug a hole, went below - so I think I at least didn't break anything.)
Yeah tried removing the global onTick stuff since we shouldn't be using global variables to store method information - see post in-context (viewtopic.php?f=25&t=24171&p=152497#p152362)

Even after that it still seems to desync, I'm suspecting it's something stupidly simple. If you want I can supply the whole control.lua, just be prepared I've had to modify quite a lot to reduce the lag in our multiplayer. (gone from having script update over 4ms to just under 1ms with the changes I've done, digging robots don't cause lag anymore, etc.) Hope not to step on anyones toes.
The algorithm for the digging robots really needs help, the further away the tile is the longer it takes for the robot to be deployed. It's not only that it takes longer for it to be deployed, it also doesn't deploy robots if the tile is 20 or so tiles away meaning that you have to rip up the digging robot center and move it every now and then.
User avatar
StanFear
Fast Inserter
Fast Inserter
Posts: 236
Joined: Sun Dec 15, 2013 2:49 pm
Contact:

Re: [WIP][0.12.22+] Subsurfaces 0.0.4 : build beneath your base

Post by StanFear »

Simcra wrote: The algorithm for the digging robots really needs help, the further away the tile is the longer it takes for the robot to be deployed. It's not only that it takes longer for it to be deployed, it also doesn't deploy robots if the tile is 20 or so tiles away meaning that you have to rip up the digging robot center and move it every now and then.
Yes, I know, I'm working on it, this is the reason why it is not available when you start a game (unless you switch it on)

plus, if the walls are 20 + tiles away, it stil works, it is just painfully slow (and the game goes dosnwn to ~10 UPS when you're lucky)
Simcra
Long Handed Inserter
Long Handed Inserter
Posts: 76
Joined: Wed Apr 06, 2016 6:05 am
Contact:

Re: [WIP][0.12.22+] Subsurfaces 0.0.4 : build beneath your base

Post by Simcra »

StanFear wrote:
Simcra wrote: The algorithm for the digging robots really needs help, the further away the tile is the longer it takes for the robot to be deployed. It's not only that it takes longer for it to be deployed, it also doesn't deploy robots if the tile is 20 or so tiles away meaning that you have to rip up the digging robot center and move it every now and then.
Yes, I know, I'm working on it, this is the reason why it is not available when you start a game (unless you switch it on)

plus, if the walls are 20 + tiles away, it stil works, it is just painfully slow (and the game goes dosnwn to ~10 UPS when you're lucky)
Below are some of the various changes I have made to increase efficiency, we have this working with 8+ digging robots in multiplayer with less than 1ms script update and 59-60fps/ups, I have also introduced a limit since it becomes more and more work the farther away from the center you search with this algorithm, it is far from perfect but it is better. Anything not pasted below remains unchanged from your version, all ontick functions have been surrounded with the appropriate associative_table_count check similaraly to digging_robots_manager(event). Air vent prototypes were changed to reflect changes done since they really do not need to be checked every tick, more like once every five ticks.

Code: Select all

digging_robot_range=35 -- maximum reach of each Digging Robot Deployment Center
max_digging_robot_waiting_time=60 -- maximum waiting time between each digging robot check in seconds

function setup()
	global.elevator_association = global.elevator_association or {}
	global.item_elevator = global.item_elevator or {}
	global.surface_drillers = global.surface_drillers or {}
	global.air_vents = global.air_vents or {}
	global.underground_players = global.underground_players or {}
	global.surface_associations = global.surface_associations or {}
	global.Underground_driving_players = global.Underground_driving_players or {}
	global.fluids_elevator = global.fluids_elevator or {}
	global.waiting_entities = global.waiting_entities or {}
	global.time_spent_dict = global.time_spent_dict or {}
	global.selection_area_markers_per_player = global.selection_area_markers_per_player or {}
	global.marked_for_digging = global.marked_for_digging or {}
	global.digging_pending = global.digging_pending or {}
	global.digging_in_progress = global.digging_in_progress or {}
	global.digging_robots_deployment_centers = global.digging_robots_deployment_centers or {}
end

script.on_event(defines.events.on_tick, 
	function(event) 
		if game.tick%60==0 then --every second
		end
		if game.tick%30==0 then --every 30/60th second
			check_waiting_entities(event)
		end
		if game.tick%20==0 then --every 20/60th second
		end
		if game.tick%15==0 then --every 15/60th second
			digging_planner_check(event)
		end
		if game.tick%10==0 then --every 10/60th second
			teleportation_check(event)
			digging_robots_manager(event)
			pollution_killing_subsurface(event)
		end
		if game.tick%6==0 then --every 6/60th second
			move_items(event)
			fluids_elevator_management(event)
		end
		if game.tick%5==0 then --every 5/60th second
			pollution_moving(event)
		end
		if game.tick%2==0 then --every 2/60th second
			boring(event)
			drilling_check(event)
			temp_teleportation_check(event)
		end
		--debug(event)
	end)

function digging_robots_manager(event)
	if associative_table_count(global.digging_robots_deployment_centers) ~= 0 then
		for id,data in ipairs(global.digging_robots_deployment_centers) do
			if data.deployment_center.valid then
				if data.stop_searching_for_target and not(data.retry_search_for_target) then --if the robot deployment center has been told to stop searching and has not yet continued work
					if not(data.consecutive_failed_searches) then data.consecutive_failed_searches = 0 end --make sure that data.consecutive_failed_searches always holds a value
					if game.tick % 30+(30*data.consecutive_failed_searches)==0 then data.retry_search_for_target=true end --retry search for target where time between searches increases based on number of failed searches.
				else
					if global.digging_pending[data.deployment_center.surface.name] then
						if not(data.deployed_unit) then
							if data.deployment_center.get_inventory(defines.inventory.assembling_machine_output).get_item_count("prepared-digging-robots") >= 1 and data.deployment_center.energy>440 then --didn't know how to get max_energy so manually grabbed half of max energy for now
								data.digging_target = find_nearest_digging_target(data.deployment_center.position, data.deployment_center.surface)
								if data.digging_target then
									data.consecutive_failed_searches=0 --reset the number of consecutive failed searches to 0 since we were successful in finding a target
									global.digging_in_progress[data.deployment_center.surface.name][string.format("{%d,%d}", math.floor(data.digging_target.x), math.floor(data.digging_target.y))] = true
									data.deployment_center.surface.create_entity{name = "selection-marker", position = data.digging_target, force=data.deployment_center.force}
									-- deploy digger
									local entity_name = "digging-robot"
									local deployment_position = data.deployment_center.surface.find_non_colliding_position(entity_name, data.deployment_center.position, 5, 0.1)
									data.digging_target_wall = data.deployment_center.surface.find_entity(cavern_Wall_name,{x = math.floor(data.digging_target.x) + 0.5, y = math.floor(data.digging_target.y) + 0.5})
									if deployment_position then
										data.deployed_unit = data.deployment_center.surface.create_entity{
											name=entity_name, 
											position=deployment_position,
											force=data.deployment_center.force}
										data.deployment_center.get_inventory(defines.inventory.assembling_machine_output).remove({name="prepared-digging-robots", count=1})
										data.deployed_unit.set_command({type=defines.command.attack, target=data.digging_target_wall, distraction=defines.distraction.none})
									end
								else
									if data.retry_search_for_target==true then --if it gets to here this is not the first time the robot deployment center has failed to find a target
										if data.consecutive_failed_searches < max_digging_robot_waiting_time*2 then --if number of consecutive failed searches is less than maximum digging robot waiting time multiplied by two
											data.consecutive_failed_searches=data.consecutive_failed_searches+1 --increment number of consecutive failed searches by one
										else
											data.consecutive_failed_searches=max_digging_robot_waiting_time*2 --set it equal to the max digging robot waiting time multiplied by two (because max digging robot waiting time is a value in seconds and consecutive failed searches add 1/2 a second delay)
										end
										data.retry_search_for_target=false --set the value back to false and let the robot deployment center wait his turn.
									end
									data.stop_searching_for_target=true --tell digging robot deployment center to stop searching for targets, he's lagging the server.
								end
							end
						else
							if not data.deployed_unit.valid then --if the deployed digging robot exists but is not valid
								data.deployed_unit = nil --remove the pointer
							end
						end
					end
				end
			else
				if data.deployed_unit and data.deployed_unit.valid then data.deployed_unit.destroy() end --destroy the deployed_unit if it exists and is valid
				if data.digging_target_wall and data.digging_target_wall.valid then --if the robot deployment center has a digging target and the target is valid
					local selection_marker = data.digging_target_wall.surface.find_entity("selection-marker", data.digging_target_wall.position) --find the selection marker at the digging target's position
					if selection_marker and selection_marker.valid then selection_marker.destroy() end --if the selection marker exists and is valid, destroy it since it is associated with the invalid robot deployment center
					global.digging_in_progress[data.digging_target_wall.surface.name][string.format("{%d,%d}", math.floor(data.digging_target_wall.position.x), math.floor(data.digging_target_wall.position.y))] = false --make sure that the target is available for other robots to dig since we no longer have a digging robot assigned to it
					data.digging_target_wall=nil --remove the pointer for the digging target
				end
				data.deployed_unit=nil --remove the pointer for the deployed unit
				table.remove(global.digging_robots_deployment_centers, id)
			end
		end
	end
end

function pollution_moving(event)
	if associative_table_count(global.air_vents) ~= 0 then
		for _,entitydata in pairs(global.air_vents) do
			local entity = entitydata.entity
			local subsurface = get_subsurface(entity.surface)

			if entitydata.active then
				if entity.name == "active-air-vent" then
					if entity.energy > 0 then
						local current_energy = entity.energy
						entity.energy = 1000000000
						local max_energy = entity.energy
						max_movable_pollution = current_energy / max_energy * (max_pollution_move_active*5) -- how much polution can be moved with the current available (altered since it now runs once per 5 ticks)

						local pollution_to_move = subsurface.get_pollution(entity.position)
						if pollution_to_move > max_movable_pollution then 
							pollution_to_move = max_movable_pollution
						end
						--entity.energy = entity.energy - ((pollution_to_move / max_pollution_move_active)*max_energy)
						subsurface.pollute(entity.position, -pollution_to_move)
						entity.surface.pollute(entity.position, pollution_to_move)
						
						if pollution_to_move > 0 then
							entity.active = true
							if game.tick % 10 == 0 then
								entity.surface.create_entity{name="smoke-custom", position={x = entity.position.x+0.25, y = entity.position.y+1}, force=game.forces.neutral}
							end
						else
							entity.active = false
						end

					end
				elseif entity.name == "air-vent" then

					local pollution_surface = entity.surface.get_pollution(entity.position)
					local pollution_subsurface = subsurface.get_pollution(entity.position)
					local diff = pollution_surface - pollution_subsurface

					if math.abs(diff) > max_pollution_move_passive then
						diff = diff / math.abs(diff) * max_pollution_move_passive
					end

					if diff < 0 and game.tick % 10 == 0  then
						entity.surface.create_entity{name="smoke-custom", position={x = entity.position.x, y = entity.position.y+1}, force=game.forces.neutral}
					end

					entity.surface.pollute(entity.position, -diff)
					subsurface.pollute(entity.position, diff)
				end
			else
				local chunk_position = to_chunk_position(entity.position)
				entitydata.active = subsurface.is_chunk_generated(chunk_position)
			end
		end
	end
end

function move_items(function_name)
	if associative_table_count(global.item_elevator) ~= 0 then
		for key,elevator in pairs(global.item_elevator) do
			if not(elevator.input and elevator.output and elevator.input.valid and elevator.output.valid) then
				if elevator.input.valid then elevator.input.destroy() end
				if elevator.output.valid then elevator.output.destroy() end
				global.item_elevator[key]=nil
			elseif elevator.input.active or elevator.output.active then
				for laneI=1,2 do
					lane_input = elevator.input.get_transport_line(laneI)
					lane_output = elevator.output.get_transport_line(laneI)
					if lane_input.get_item_count() > 0 and lane_output.can_insert_at_back() then
						local item_to_move = {name = next(lane_input.get_contents()), count = 1}
						lane_input.remove_item(item_to_move)
						lane_output.insert_at_back(item_to_move)
					end
				end
			end
		end
	end
end

function find_nearest_digging_target(_position, _surface)
	local _origin = {x=_position.x, y=_position.y}
	local _current = _origin
	
	for i=1, digging_robot_range, 1 do --8 directions around area (topleft,bottomright,bottomleft,topright,left,top,bottom,right), does a spiral from top to right to bottom to left to top
		local j = 0
		while j < i do --top of area starting from center going right
			_current = {x=_origin.x+j,y=_origin.y-i}
			if is_valid_for_digging(_surface, _current) then return _current end
			j=j+1
		end
		j=i
		while j >= 0 do --right of area starting from top going down
			_current = {x=_origin.x+i,y=_origin.y-j}
			if is_valid_for_digging(_surface, _current) then return _current end
			j=j-1
		end
		j=1
		while j < i do --right of area starting from center going down
			_current = {x=_origin.x+i,y=_origin.y+j}
			if is_valid_for_digging(_surface, _current) then return _current end
			j=j+1
		end
		j=i
		while j >= 0 do --bottom of area starting from right going left
			_current = {x=_origin.x+j,y=_origin.y+i}
			if is_valid_for_digging(_surface, _current) then return _current end
			j=j-1
		end
		j=1
		while j < i do --bottom of area starting from center going left
			_current = {x=_origin.x-j,y=_origin.y+i}
			if is_valid_for_digging(_surface, _current) then return _current end
			j=j+1
		end
		j=i
		while j >= 0 do --left of area starting from bottom going up
			_current = {x=_origin.x-i,y=_origin.y+j}
			if is_valid_for_digging(_surface, _current) then return _current end
			j=j-1
		end
		j=1
		while j < i do --left of area starting from center going up
			_current = {x=_origin.x-i,y=_origin.y-j}
			if is_valid_for_digging(_surface, _current) then return _current end
			j=j+1
		end
		j=i
		while j > 0 do --tio of area starting from left going right
			_current = {x=_origin.x-j,y=_origin.y-i}
			if is_valid_for_digging(_surface, _current) then return _current end
			j=j-1
		end
	end
	return false
end

function is_valid_for_digging(_surface, _position)
	if global.digging_pending[_surface.name][string.format("{%d,%d}", math.floor(_position.x), math.floor(_position.y))] and not global.digging_in_progress[_surface.name][string.format("{%d,%d}", math.floor(_position.x), math.floor(_position.y))] then
		return true
	else
		return false
	end
end
sonkhritis
Manual Inserter
Manual Inserter
Posts: 4
Joined: Sat Apr 30, 2016 10:44 am
Contact:

Re: [WIP][0.12.22+] Subsurfaces 0.0.4 : build beneath your base

Post by sonkhritis »

Logistic and Construction robots delving into subsurface and going back into surface would be nice.. but it would be a pain to code that i think.. Just a suggestion :)
Exasperation
Long Handed Inserter
Long Handed Inserter
Posts: 88
Joined: Fri Apr 22, 2016 9:55 pm
Contact:

Re: [WIP][0.12.22+] Subsurfaces 0.0.4 : build beneath your base

Post by Exasperation »

Simcra wrote:all ontick functions have been surrounded with the appropriate associative_table_count check similaraly to digging_robots_manager(event).
This is a bad idea. Rather than an optimization, this is an anti-optimization.

Code: Select all

if associative_table_count(t) ~= 0 then
    for k, v in pairs(t) do
        --do some stuff
    end
end
has strictly worse performance than just

Code: Select all

for k, v in pairs(t) do
    --do some stuff
end
this is because the associative_table_count version is equivalent to

Code: Select all

function waste_some_time (t)
    local time_to_waste = 0
    for k, v in pairs(t) do
        time_to_waste = time_to_waste + 1
    end
    return time_to_waste ~= 0
end

if waste_some_time(t) then
    for k, v in pairs(t) do
        --do some stuff
    end
end
Note how if the table is empty, you're doing the same loop setup and termination check in either case, but have added the overhead of a function call, a variable assignment, and a comparison. On the other hand, if the table isn't empty, you've added the overhead of a function call, a comparison, and an additional complete loop through the entire table (with variable assignments at each step). And by doing all this extra work, you've gained... absolutely nothing in return.

TL;DR: only use associative_table_count if you absolutely need to know how many things are in the table. If you just need to check if it's empty, replace

Code: Select all

if associative_table_count(t) ~= 0 then
with

Code: Select all

if next(t) then
or

Code: Select all

if associative_table_count(t) == 0 then
with

Code: Select all

if not next(t) then
or ask yourself if checking for emptiness is even necessary in this case (for the use case in question, it's probably better to just let the loop terminate because there are no elements to loop through than to throw in a separate emptiness check).
Post Reply

Return to “Mods”