Page 1 of 1

[SOLVED] Help - Detecting ghosts being destroyed

Posted: Sun Dec 22, 2019 6:30 pm
by wodzu93
Is is possible to detect ghosts getting killed by an entity being placed in competing space?

My use case is, entity of one force gets placed on the spot where ghost of another force is present. This operation will remove the ghost.
Is is possible to detect that removed ghost this with an event?

I'm trying to do this:

Code: Select all

script.on_event(defines.events.on_entity_died, function(event)
	if event.entity.force == game.forces.enemy and event.entity.type == "turret" then
		for i, worm in pairs(global.surface_worms) do
			if worm == event.entity then
				table.remove(global.surface_worms, i)
				break
			end
		end
	elseif event.entity.type == "ghost" then
		game.players[1].print("Ghost of " .. event.entity.name .. " destroyed ")
	end
end, {{filter = "turret"}, {filter = "ghost"}})
Detecting dead worms works fine, but that print on killed ghost isn't working for my intended case.

Re: Help - Detecting ghosts being destroyed

Posted: Mon Dec 23, 2019 8:42 pm
by Honktown
wodzu93 wrote: Sun Dec 22, 2019 6:30 pm Is is possible to detect ghosts getting killed by an entity being placed in competing space?

My use case is, entity of one force gets placed on the spot where ghost of another force is present. This operation will remove the ghost.
Is is possible to detect that removed ghost this with an event?

I'm trying to do this:

Code: Select all

script.on_event(defines.events.on_entity_died, function(event)
	if event.entity.force == game.forces.enemy and event.entity.type == "turret" then
		for i, worm in pairs(global.surface_worms) do
			if worm == event.entity then
				table.remove(global.surface_worms, i)
				break
			end
		end
	elseif event.entity.type == "ghost" then
		game.players[1].print("Ghost of " .. event.entity.name .. " destroyed ")
	end
end, {{filter = "turret"}, {filter = "ghost"}})
Detecting dead worms works fine, but that print on killed ghost isn't working for my intended case.
1) a ghost is named "entity-ghost". raw.txt suggest the ghost type is "entity-ghost" as well (I've never checked it):

Code: Select all

  ["entity-ghost"] = {
    ["entity-ghost"] = {
      flags = {
        "not-on-map"
      },
      minable = {
        mining_time = 0,
        results = {}
      },
      name = "entity-ghost",
      type = "entity-ghost"
    }
  },
2) I don't know if ghosts being removed count as "dying": they're not taking damage. There's defines.events.script_raised_destroy, but the name implies the base game doesn't raise it. Edit: disregard the rest of my post the entity_died filter says it has ghost :P

3) One way to check collide-able entities is when on_put_item fires, which is called before on_built_entity:
https://lua-api.factorio.com/latest/eve ... n_put_item

You filter for entities in the area of the to-be-placed entity by passing the bounding box of the entity as the area. There were some issues I was having with cliff collision detection, but those have orientations (angles) and other weirdness. Absolutely no idea how it behaves with square entities/non-cliffs. I used on_marked_for_deconstruction, because I was going from a marked cliff to possible ghost(s) (the api page is wrong for that event, actually, since it is raised when a normal blueprint or shift-ghosting is used).

In your case, you may want to save an area that's slightly larger than the original. If only the center positions must lie within the area of the filter, then something could be exactly on the edge which is a little worrisome (I hadn't tried that, but there were at least two things going on in my case).

I used (past tense) this line:

Code: Select all

table.insert(clear_ghosts_info, {area = event.entity.bounding_box, surface = game.players[player].surface})
and next tick:

Code: Select all

        ghosts = surface.find_entities_filtered({
                  area = ginfo.area,
                  name = "entity-ghost"
                  })

        if ghosts ~= nil and #ghosts > 0 then
          --log("found ghost(s) to clear")
          for _, g in pairs(ghosts) do
            g.destroy()
          end
          --game.print("destroyed " .. count .. " ghosts")
          table.insert(ghosts_cleared, gkey)
        end
I didn't trust that the ghost would have existed when a cliff was marked for deconstruction. Deconstruction marking happens before the ghost exists, in my mind, so I stored the possible ghost(s) and cleared them next tick. In your case, the ghost definitely exists before the turret is placed. You still want to store/act on the data for whatever reason, so storing the area to check (unless you want it now) and surface (you have to search from a surface table) is relevant.

P.s. I saw your post when looking for how to use the darn event filters. Thanks for the code in your post (no examples on api or wiki)

Edit: if you have to check collision manually, the area would probably have to be increased a lot. The center of a rocket silo is far from the bound_box, for example. On the other hand, you can just make it a big area and say "noo to close go away this isn't your space"

Re: Help - Detecting ghosts being destroyed

Posted: Mon Dec 23, 2019 10:05 pm
by Honktown
Oh er, I got through my post and forgot why you wanted this. It won't help you next tick, but the ideas will right? :?

Re: [SOLVED] Help - Detecting ghosts being destroyed

Posted: Fri Dec 27, 2019 5:56 pm
by wodzu93
Thanks for the clues, I managed to get it working!