ReikaKalseki / Reika_FactorioMods_Issues

The issue tracker for all of my Factorio mods - EndgameCombat, NauvisDay, Geothermal, Oreverhaul, and the rest.
5 stars 1 forks source link

Suggestion for Belt Rotation Actuator #395

Open afewvowels opened 1 year ago

afewvowels commented 1 year ago

Hello again! I'm using the Belt Rotation Actuator in your Factor I/O mod and I had to do some digging around in the repo to figure out to send the "N", "S", "E", and "W" virtual signals via another combinator to get the belts to rotate.

And then I started messing with some code and instead of figuring out how to rotate underground belts and miniloaders (uh, type "inserter" not type "loader-1x1"???) I realized using tgt[1].rotate{by_player=game.get_player(1)} on the transport belt would trigger the auto-orient-direction functionality on adjacent underground belts and miniloaders!

Also I clunked around a bit and butchered your code and made a modified version that can take a numerical signal in as well direction to flip multiple belts in a row. I use a lot of big warehouses and spaceships so having the ability now to flip belts and load and unload on both sides of a spaceship landing pad is going to be super helpful.

Here's all the modified code in the call.lua file that I made lol.

I had to modify getFacingEntity() with an optional distance parameter to search at a specified distance from the combinator:

local function getFacingEntity(entity, types, distance)
    local box = getBox(entity)
    local searchDistance = distance or 1
    box = moveBoxDirection(box, entity.direction, searchDistance)
    local seek = {area = box, force = entity.force, limit = 1}
    if types then seek.type = types end
    return entity.surface.find_entities_filtered(seek)
end

I changed getDesiredBeltDirection() to getDesiredBeltDirectionandDistance() to search for a N/S/E/W and a 1/2/3/4/5/6 virtual signal pair and return a table with both those values (or default distance of 1):

local function getDesiredBeltDirectionAndDistance(entity)
    local network = entity.get_circuit_network(defines.wire_type.red)
    if not network then network = entity.get_circuit_network(defines.wire_type.green) end
    if network then
        local signals = network.signals
        if signals and #signals > 0 then
        local directionAndCount = {}
        local direction = nil
        local count = 1
        for _,signal in pairs(signals) do
            if signal.count > 0 and signal.signal.type == "virtual" then
            if signal.signal.name == "signal-N" then direction = defines.direction.north end
            if signal.signal.name == "signal-S" then direction = defines.direction.south end
            if signal.signal.name == "signal-E" then direction = defines.direction.east end
            if signal.signal.name == "signal-W" then direction = defines.direction.west end
                    if signal.signal.name == "signal-1" then count = 1 end
                    if signal.signal.name == "signal-2" then count = 2 end
                    if signal.signal.name == "signal-3" then count = 3 end
                    if signal.signal.name == "signal-4" then count = 4 end
                    if signal.signal.name == "signal-5" then count = 5 end
                    if signal.signal.name == "signal-6" then count = 6 end
        end
            end
            table.insert(directionAndCount, direction)
            table.insert(directionAndCount, count)
            return directionAndCount
    end
    end
    return nil
end

...and I changed setBeltDirection() to use .rotate() instead of .direction to trigger the underground belt/miniloader orientation change as well as to iterate if the returned distance was > 1

function setBeltDirection(entity, data, connection)
    local tgt = getFacingEntity(entity, "transport-belt")
    if tgt and table_size(tgt) > 0 and tgt[1].valid then
        local directionAndCount = getDesiredBeltDirectionAndDistance(entity)
        if directionAndCount and directionAndCount[1] ~= nil then
                while tgt[1].direction ~= directionAndCount[1] do
                    tgt[1].rotate{by_player = game.get_player(1)}
                end
            if directionAndCount[2] > 1 then
                for i = 1, directionAndCount[2] do
                    tgt = getFacingEntity(entity, "transport-belt", i)
                    while tgt[1].direction ~= directionAndCount[1] do
                        tgt[1].rotate{by_player = game.get_player(1)}
                    end
                end
              end
            end
    end
    return 0
end

Anyways thanks for making all these cool mods! 🎉