Draw buildings under cars and players

Place to get help with not working mods / modding interface.
Post Reply
User avatar
Dr. Walrus
Long Handed Inserter
Long Handed Inserter
Posts: 96
Joined: Fri Nov 20, 2015 6:30 am
Contact:

Draw buildings under cars and players

Post by Dr. Walrus »

Hi, first time modder here!

I am adding a pressure plate entity that outputs a circuit signal if the player is standing on top of it. It is based off of the constant combinator entity. Since it is flat and rests on the floor I'd like for it to always be drawn under the player like a conveyor belt rather than being drawn like a regular building but I'm not sure how to go about that. I've changed it's collision mask which allowed me to walk through it which is nice but does not affect how it is drawn.
Problem Areas
Code
The mod itself.

Thanks guys! All help is appreciated :mrgreen:

memcallen
Inserter
Inserter
Posts: 34
Joined: Sat Mar 28, 2015 1:22 am
Contact:

Re: Draw buildings under cars and players

Post by memcallen »

I know for decoratives, you can do 'render_layer = "decorative" ', although I'm not sure if it would work with a constant combinator. Here's the link for the different types of render layers, https://forums.factorio.com/wiki/inde ... enderLayer

User avatar
Dr. Walrus
Long Handed Inserter
Long Handed Inserter
Posts: 96
Joined: Fri Nov 20, 2015 6:30 am
Contact:

Re: Draw buildings under cars and players

Post by Dr. Walrus »

Thanks for the suggestion
I tried render_layer = "decorative", render_layer = "floor", and render_layer = "lower-object" but nothing changed. I didn't get any errors but there was no change in the render layer. I guess the render layer is hardcoded for combinators, and probably for all building entities.

I might just change the entity the pressure plates are based on to transport belts. Or just ignore the ugliness.

memcallen
Inserter
Inserter
Posts: 34
Joined: Sat Mar 28, 2015 1:22 am
Contact:

Re: Draw buildings under cars and players

Post by memcallen »

Another, fairly hacky solution is creating a decorative entity with the image, and make the combinator have a clear sprite. Then spawn the decoration and destroy it depending on when your pressure plate is placed/broken (in the control.lua).

User avatar
Klonan
Factorio Staff
Factorio Staff
Posts: 5150
Joined: Sun Jan 11, 2015 2:09 pm
Contact:

Re: Draw buildings under cars and players

Post by Klonan »

memcallen wrote:Another, fairly hacky solution is creating a decorative entity with the image, and make the combinator have a clear sprite. Then spawn the decoration and destroy it depending on when your pressure plate is placed/broken (in the control.lua).
Although this has the side affect that when you try to place the entity, it will also be transparent, unless you have the decorative item the one placed by the player, and spawn the transparent pressure plate on top of that, the code for spawning the entities is fairly simple
Example from Concrete lamppost mod

User avatar
Blu3wolf
Fast Inserter
Fast Inserter
Posts: 202
Joined: Thu Apr 09, 2015 5:20 am
Contact:

Re: Draw buildings under cars and players

Post by Blu3wolf »

I think the way treefarm does it is by making the entire graphic only in one corner of the .png file, and using a shift parameter to offset the graphic such that the field on the graphic covers the field entity.

User avatar
Blu3wolf
Fast Inserter
Fast Inserter
Posts: 202
Joined: Thu Apr 09, 2015 5:20 am
Contact:

Re: Draw buildings under cars and players

Post by Blu3wolf »

Klonan wrote:
memcallen wrote:Another, fairly hacky solution is creating a decorative entity with the image, and make the combinator have a clear sprite. Then spawn the decoration and destroy it depending on when your pressure plate is placed/broken (in the control.lua).
Although this has the side affect that when you try to place the entity, it will also be transparent, unless you have the decorative item the one placed by the player, and spawn the transparent pressure plate on top of that, the code for spawning the entities is fairly simple
Example from Concrete lamppost mod
Does this mod work with current Factorio? I tried to use that script to place an entity, but on starting a new game I get an error 'attempt to index global defines that has a nil value'.

User avatar
Dr. Walrus
Long Handed Inserter
Long Handed Inserter
Posts: 96
Joined: Fri Nov 20, 2015 6:30 am
Contact:

Re: Draw buildings under cars and players

Post by Dr. Walrus »

Thanks for the help guys. I decided with memcallen's advice and give the combinator a transparent sprite and then create a decorative entity in the floor render layer over top of the invisible combinator on creation. This has the added benefit of allowing me to have 2 different decorative entities that change if the player stands on a pressure plate. I've got it working right now and it looks really nice, however this solution suffers from the invisible entity while placing problem.
Klonan wrote:
memcallen wrote:Another, fairly hacky solution is creating a decorative entity with the image, and make the combinator have a clear sprite. Then spawn the decoration and destroy it depending on when your pressure plate is placed/broken (in the control.lua).
Although this has the side affect that when you try to place the entity, it will also be transparent, unless you have the decorative item the one placed by the player, and spawn the transparent pressure plate on top of that, the code for spawning the entities is fairly simple
Klonan, when you make the decorative entity the one placed which then spawns the real invisible entity, what effect would this have on using the pressure plates with blueprints? Does the blueprint register the decorative entity and place a ghost of that, or does it register the invisible entity and place a ghost of that which can never be placed by your robots because you will have no items for the invisible entity? Either way it also seems like any wires connecting the pressure plates you had in the blueprint would get messed up.

Blu3wolf, you need to put

Code: Select all

require "defines"
at the top of the code for it to work because it calls functions from the defines library.

Anyways thank yall for the help. Other than the problem with the pressure plates being invisible when you place them, these bad boys are working beautifully. I'll post a gif in the morning to show them off.

User avatar
Klonan
Factorio Staff
Factorio Staff
Posts: 5150
Joined: Sun Jan 11, 2015 2:09 pm
Contact:

Re: Draw buildings under cars and players

Post by Klonan »

Dr. Walrus wrote: Klonan, when you make the decorative entity the one placed which then spawns the real invisible entity, what effect would this have on using the pressure plates with blueprints? Does the blueprint register the decorative entity and place a ghost of that, or does it register the invisible entity and place a ghost of that which can never be placed by your robots because you will have no items for the invisible entity? Either way it also seems like any wires connecting the pressure plates you had in the blueprint would get messed up.

Yea so with blueprints its a bit tricky. I use a workaround that is making the placed entity part of the 'neutral' force, such that a blueprint wont pick up on it, and all will be ok. If it isn't on the neutral force, then when you blueprint it, it will grab both the entities, of which one cannot be placed, leading to undesireable issues

User avatar
Blu3wolf
Fast Inserter
Fast Inserter
Posts: 202
Joined: Thu Apr 09, 2015 5:20 am
Contact:

Re: Draw buildings under cars and players

Post by Blu3wolf »

Klonan wrote:
Dr. Walrus wrote: Klonan, when you make the decorative entity the one placed which then spawns the real invisible entity, what effect would this have on using the pressure plates with blueprints? Does the blueprint register the decorative entity and place a ghost of that, or does it register the invisible entity and place a ghost of that which can never be placed by your robots because you will have no items for the invisible entity? Either way it also seems like any wires connecting the pressure plates you had in the blueprint would get messed up.

Yea so with blueprints its a bit tricky. I use a workaround that is making the placed entity part of the 'neutral' force, such that a blueprint wont pick up on it, and all will be ok. If it isn't on the neutral force, then when you blueprint it, it will grab both the entities, of which one cannot be placed, leading to undesireable issues
hmm. I dont know if that workaround would work for me, as Im trying to place an assembly building. Which if I understand correctly, if its on a different force to the player, they wont be able to use it to craft things.

Although I guess thats a low priority issue, because its such a low level assembly building that by the time you get blueprints, you have no need or interest in blueprinting it, so theres that.

User avatar
Dr. Walrus
Long Handed Inserter
Long Handed Inserter
Posts: 96
Joined: Fri Nov 20, 2015 6:30 am
Contact:

Re: Draw buildings under cars and players

Post by Dr. Walrus »

Here's my finished control.lua code for using the decorative sprite workaround and a poorly made gif of it in action (it doesn't lag like that in game, my video recording software just sucks).

Code: Select all

-- "basic-pressure-plate" is invisible, type = "constant-combinator"
-- "decorative-basic-plate-inactive" is visble, type = "decorative", render_layer = "floor"
-- "decorative-basic-plate-active" is visble, type = "decorative", render_layer = "floor"

require "defines"

if global.basic_pp_list == nil then
	global.basic_pp_list = {}
end

--script events
script.on_event(defines.events.on_built_entity, function(event)
	if (event.created_entity.name == "basic-pressure-plate") then
		create_basic_pp(event.created_entity)
	end
end)

script.on_event(defines.events.on_robot_built_entity, function(event)
	if (event.created_entity.name == "basic-pressure-plate") then
		create_basic_pp(event.created_entity)
	end
end)

script.on_event(defines.events.on_preplayer_mined_item, function(event)
	if (event.entity.name == "basic-pressure-plate") then
		remove_basic_pp(event.entity)
	end
end)

script.on_event(defines.events.on_robot_pre_mined, function(event)
	if (event.entity.name == "basic-pressure-plate") then
		remove_basic_pp(event.entity)
	end
end)

script.on_event(defines.events.on_entity_died, function(event)
	if (event.entity.name == "basic-pressure-plate") then
		remove_basic_pp(event.entity)
	end
end)

script.on_event(defines.events.on_tick, function(event)
	for pp_xykey, pp_state in pairs(global.basic_pp_list) do
		set_basic_pp(pp_xykey, pp_state)
	end
end)

--functions
function create_basic_pp(entity)
	entity.operable = false
	pp_mask = game.get_surface(1).create_entity{name = "decorative-basic-plate-inactive", position = {entity.position.x, entity.position.y}, force = game.forces.neutral}
	global.basic_pp_list[entity.position.x .. "," .. entity.position.y] = {basic_pp_entity = entity, mask_entity = pp_mask, x = entity.position.x, y = entity.position.y, active = false}
end

function remove_basic_pp(entity)
	global.basic_pp_list[entity.position.x .. "," .. entity.position.y].mask_entity.destroy()
	global.basic_pp_list[entity.position.x .. "," .. entity.position.y] = nil
	
end

function set_basic_pp(key, value)
	if game.player.position.x > (value.x - 0.5) and game.player.position.x < (value.x + 0.5) and game.player.position.y > (value.y - 0.5) and game.player.position.y < (value.y + 0.5) then
		if global.basic_pp_list[key].active == false then
			global.basic_pp_list[key].active = true
			value.basic_pp_entity.set_circuit_condition(1, {parameters = {{count=1, index=1, signal={name="basic-pressure-plate", type="item"}}}})
			
			global.basic_pp_list[key].mask_entity.destroy()
			pp_mask = game.get_surface(1).create_entity{name = "decorative-basic-plate-active", position = {value.x, value.y}, force = game.forces.neutral}
			global.basic_pp_list[key].mask_entity = pp_mask
		end
	else
		if global.basic_pp_list[key].active == true then
			global.basic_pp_list[key].active = false
			value.basic_pp_entity.set_circuit_condition(1, {parameters = {{count=0, index=1, signal={name="basic-pressure-plate", type="item"}}}})
			
			global.basic_pp_list[key].mask_entity.destroy()
			pp_mask = game.get_surface(1).create_entity{name = "decorative-basic-plate-inactive", position = {value.x, value.y}, force = game.forces.neutral}
			global.basic_pp_list[key].mask_entity = pp_mask
		end
	end
end
There is a loop and quite a few lines of code in the on_tick event but I don't think there is too much going on because entities and variables for the pressure plates are only changed if the player steps off of or on to a pressure plate. I've played a game with 200 pressure plates on the ground and I haven't seen FPS or UPS drop under 60 so I think I'm ok performance wise.

Image

You can see the pressure plates under the player and car at all times, and how a light illuminates on the pressure plate that the player is standing on.
Last edited by Dr. Walrus on Sun Jan 17, 2016 5:40 am, edited 1 time in total.

User avatar
prg
Filter Inserter
Filter Inserter
Posts: 947
Joined: Mon Jan 19, 2015 12:39 am
Contact:

Re: Draw buildings under cars and players

Post by prg »

Don't hardcode things like game.get_surface(1) or you guarantee your mod will break when people use multiple surfaces. Entities contain the surface they're on so you can get at the right surface with event.created_entity.surface.
Automatic Belt (and pipe) Planner—Automate yet another aspect of constructing your factory!

User avatar
Dr. Walrus
Long Handed Inserter
Long Handed Inserter
Posts: 96
Joined: Fri Nov 20, 2015 6:30 am
Contact:

Re: Draw buildings under cars and players

Post by Dr. Walrus »

prg wrote:Don't hardcode things like game.get_surface(1) or you guarantee your mod will break when people use multiple surfaces. Entities contain the surface they're on so you can get at the right surface with event.created_entity.surface.
Thanks mate! Nice catch! I changed it to this. I'm not getting any errors so I assume that its working.

Code: Select all

pp_mask = value.basic_pp_entity.surface.create_entity{name = "decorative-basic-plate-active", position = {value.x, value.y}, force = game.forces.neutral}
Can you recommend any mods you know of that involve multiple surfaces so that I may test it out?

Supercheese
Filter Inserter
Filter Inserter
Posts: 841
Joined: Mon Sep 14, 2015 7:40 am
Contact:

Re: Draw buildings under cars and players

Post by Supercheese »

Dr. Walrus wrote:
prg wrote:Don't hardcode things like game.get_surface(1) or you guarantee your mod will break when people use multiple surfaces. Entities contain the surface they're on so you can get at the right surface with event.created_entity.surface.
Thanks mate! Nice catch! I changed it to this. I'm not getting any errors so I assume that its working.

Code: Select all

pp_mask = value.basic_pp_entity.surface.create_entity{name = "decorative-basic-plate-active", position = {value.x, value.y}, force = game.forces.neutral}
Can you recommend any mods you know of that involve multiple surfaces so that I may test it out?
NEST or The Underground.

User avatar
prg
Filter Inserter
Filter Inserter
Posts: 947
Joined: Mon Jan 19, 2015 12:39 am
Contact:

Re: Draw buildings under cars and players

Post by prg »

Code: Select all

/c game.player.teleport({0,0}, game.create_surface("bla"))
No need for a mod.
Automatic Belt (and pipe) Planner—Automate yet another aspect of constructing your factory!

Post Reply

Return to “Modding help”