Page 1 of 1

How to replace an elevated rail with a custom elevated rail

Posted: Mon Apr 28, 2025 3:37 pm
by theblackswitch
Hi,

I'm making a mod to hide elevated rails using a keybind so you can see behind them. Everything worked very well until I tried to replace a normal elevated-curved-rail-a with my new hidden-elevated-rail-curve-a which is just a deep copy of the elevated-curved-rail-a with different textures. It seems like the elevated rails do get replaced but only when the original rail isn't connected to any other rails. So the replace code works but when the newly created rail connects to any other rail, it cannot be replaced. Weird... Does someone know why this happens?

Here is my code:

Prototype

Code: Select all

require ("__hide-elevated-rail-keybind__.prototypes.hidden-rail-pictures")

local hidden_rail = table.deepcopy(data.raw["elevated-curved-rail-a"]["elevated-curved-rail-a"])

hidden_rail.name = "hidden-elevated-rail-curve-a"

hidden_rail.selection_priority = 1
hidden_rail.pictures = elevated_rail_pictures("curved-a")
hidden_rail.fence_pictures = elevated_rail_fences_pictures("curved-a")


data:extend({hidden_rail})
Control.lua

Code: Select all

function replace_elevated_rails (original, replace, player)
    local entities = game.surfaces[player.surface_index].find_entities_filtered{position = player.position, radius = 100, name = original}
    for i, entity in ipairs(entities) do
        local new = entity
        game.print(player.surface.create_entity{name})
        entity.destroy()
    end
end

script.on_event("on_tick",
    function(event)
        local players = game.players
        for i, local_player in pairs(players) do
            local original = "elevated-curved-rail-a"
            local replacement = "hidden-elevated-rail-curve-a"
            local s = local_player.surface
            for chunk in s.get_chunks() do
                local entities = s.find_entities_filtered{name=original, area={{chunk.x*32, chunk.y*32}, {(chunk.x+1)*32, (chunk.y+1)*32}}}
                for _, entity in pairs(entities) do
                    s.create_entity{name=replacement, position=entity.position}
                    entity.destroy()
                end
            end
        end
    end
)

Re: How to replace an elevated rail with a custom elevated rail

Posted: Mon Apr 28, 2025 4:53 pm
by robot256
Have you looked at how https://mods.factorio.com/mod/transpare ... ated-rails does it? They do the same thing, but with a selection tool so it only affects a small area at a time.

Just looking at your code, my first suspicion is how you destroy the old rail after attempting to create the new rail in the same spot. That may not fail completely, but it will potentially mess with the rail connection logic.

Typically when I replace an entity in the world, I save the necessary attributes of the old entity into variables, destroy it, then create the new entity.
You also will need to copy more than just position. Orientation (or possibly direction), force (default force is actually "enemy"), last_user, health, and maybe others.

Re: How to replace an elevated rail with a custom elevated rail

Posted: Tue Apr 29, 2025 4:08 pm
by theblackswitch
Thanks! I'll try to look into it :)

Re: How to replace an elevated rail with a custom elevated rail

Posted: Tue Apr 29, 2025 4:50 pm
by robot256
Actually, for your mod, I believe it would not be hard to use the ine I linked as a dependency, and then on keypress simulate the dragging of the mod's selection tool on the 100-tile area or something. Or offer a pull request to that mod to add a hotkey command. Then you can avoid duplicating mods on the portal.