Autodrive

by Pi-C

Car equipment for train avoidance, logistic network integration, circuit network connectivity, fuel refill, ammo reload, vehicle repair, radio control, enemy targeting, and gate control.

Content
10 days ago
0.17 - 2.0
3.39K
Transportation Combat Logistic network Circuit network

b [Fixed?] Vehicles panicking despite having ammo for their guns

a month ago
(updated a month ago)

What the title says. Tested with vanilla tanks and cars and all vanilla ammo types. Factorio 2.0.60 (build 83512 expansion, linux64) with Space Age.
Tested on a playthrough with only base, elevated-rails, quality, space-age, Pi-C_lib, and autodrive enabled, as well as my main one with a bunch of mods, with the same result.

My version of the mod also includes the edit proposed in the thread https://mods.factorio.com/mod/autodrive/discussion/689fd0c17a3e0cd8190935e8 to fix a different bug. I tested this without the edit as well, the result is the same.

a month ago

Thanks for the report! Could you upload a saved game I can use for debugging this?

a month ago
(updated a month ago)

Thanks for the report! Could you upload a saved game I can use for debugging this?

Here's the save file with the unmodded (besides your lib and autodrive ofc) game: https://gofile.io/d/NVnPoz

There's a tank that's added into the autodrive gui, it has ammo for all its guns, and an enemy scanner in the equipment grid. There's also a small biter nest to the south.

Something that I haven't mentioned is that enemy targeting works fine when you're driving in manual, it does exactly what I expect, which is target and shoot at biters. It's when the vehicle is driven autonomously that the issue crops up.

a month ago

Thanks to your saved game, I've identified (and fixed) another problem: shooting speed bonuses from research would never be applied because Factorio 2.0 changed the way how to get the ammo_category of an ammo item.

Panicking is more difficult to reproduce. It worked with the tank, when it was using the flame thrower. Unless the other guns, flame throwers have a min_range in addition to max_range. If the nearest enemy was closer than min_range, the tank couldn't shoot at the enemy although it had ammo, and thus panicked. However, this shouldn't affect cars …

a month ago
(updated a month ago)

Interesting, there must be some relevant difference between our testing environments that we're not identifying here, but I can't think of anything right now. I've even tested this on a windows build and the tank still runs away without ever shooting its guns (not that I expected that the platform should matter, just didn't have any other ideas). The flamethrower behavior is something that I've seen happen in manual mode, so I assumed from the get go that it functions as intended, the issue there is with the main gun and the mg, as well as cars' mgs. I don't have any good ideas on how you could reproduce it on your end, sorry to say.

a month ago

Interesting, there must be some relevant difference between our testing environments that we're not identifying here, but I can't think of anything right now. I've even tested this on a windows build …

I'm on Linux myself. There is one difference: I don't have Space Age. But I don't see how that would be relevant.

a month ago

It seems I misunderstood this:

Something that I haven't mentioned is that enemy targeting works fine when you're driving in manual, it does exactly what I expect, which is target and shoot at biters. It's when the vehicle is driven autonomously that the issue crops up.

In order to always have the vehicle centered, I've entered the tank but selected a position it should drive to. This still worked as expected. however, with no players inside the tank, a dummy would be created as passenger (as expected) but not be set as shooter. Thus, there were enemies and the vehicle had loaded guns but couldn't shoot, so it panicked.

Please replace lines 452–470 in file scripts/driving.lua:

    -- Do nothing if vehicle already has a passenger (dummy or player/character)
    if (passenger and passenger.valid) or (dummy and dummy.valid) then
      AD.writeDebug("Already have %s passenger!",
                    {dummy and dummy.valid and "dummy" or "a"})
    -- Create dummy
    else
      AD.writeDebug("Creating dummy passenger!")
      dummy = vehicle.surface.create_entity({
        name = AD.dummy_passenger_name,
        position = vehicle.position,
        force = vehicle.force,
      })
      if dummy and dummy.valid then
        vehicle.set_passenger(dummy)

        state.occupants = state.occupants or {}
        state.occupants.dummy = dummy
      end
    end

with the following:

    -- Do nothing if vehicle already has a passenger (dummy or player/character)
    if (passenger and passenger.valid) then
      AD.writeDebug("Already have a passenger!")

    -- Use existing dummy as passenger
    elseif (dummy and dummy.valid) then
      AD.writeDebug("Using existing dummy as passenger!")
      passenger = dummy

    -- Create dummy
    else
      AD.writeDebug("Creating dummy passenger!")
      dummy = vehicle.surface.create_entity({
        name = AD.dummy_passenger_name,
        position = vehicle.position,
        force = vehicle.force,
      })
      if dummy and dummy.valid then
        vehicle.set_passenger(dummy)
        passenger = dummy

        state.occupants = state.occupants or {}
        state.occupants.dummy = dummy
      end
    end

Does that fix it for you?

a month ago

@Pi-C It sort of does, the tank shoots the biters. And once it shoots the last biter, it keeps shooting in the direction of the last (now dead) biter. This can be interrupted by issuing a drive command. It will keep shooting on the way to the new waypoint, and stop once there.

a month ago

Look for this in scripts.driving.lua:

  -- We don't need a dummy!
  elseif driver or passenger then
    AD.writeDebug("Don't need a passenger. Check %s for dummies!",
                  {AD.argprint(vehicle)})
    -- Remove dummy passenger
    if dummy and dummy.valid then
      AD.writeDebug("Removing dummy passenger %s!", {AD.argprint(dummy)})
      dummy.destroy()
    end
    -- -- Make sure no dummy has sneaked in as driver!
    -- if driver and driver.valid and driver.name == AD.dummy_passenger_name then
      -- AD.writeDebug("Removing illegal dummy driver %s!", {AD.argprint(driver)})
      -- driver.destroy()
    -- end

and replace it with the following:

  -- We don't need a dummy!
  elseif dummy and dummy.valid then
    AD.writeDebug("Don't need a passenger. Removing dummy %s from %s!",
                  {AD.argprint(dummy), AD.argprint(vehicle)})
    dummy.destroy()

   -- Make sure no dummy has sneaked in as driver!
  elseif driver and driver.valid and driver.name == AD.dummy_passenger_name then
    AD.writeDebug("Removing illegal dummy driver %s!", {AD.argprint(driver)})
    -- This makes driver invalid, but it still exists, so we must delete the variable
    driver.destroy()
    driver = nil

If the vehicle doesn't need a passenger (no enemies to shoot at and no gates to open), this will remove the dummy. As shooting is not done by the vehicle itself, but by the driver (if vehicle.driver_is_gunner is true) or passenger (if it is false), this should fix the non-stop shooting.

a month ago

This stops the shooting, but it makes the tank go through "Attacking enemies!" thing every time a targeted enemy is killed, i.e. instead of immediately targeting the next enemy in range, it stops shooting, goes on standby ("forgets" that there are still enemies in range), then restarts the targeting ("Attacking enemies!") until it shoots and kills an enemy again. This means that the fire rate is extremely low.

Sorry for the time it took me to respond.

a month ago
(updated a month ago)

I think I've got that already covered! If vehicle.surface.find_nearest_enemy() succeeds but the distance between enemy and vehicle is less than min_range, I now call vehicle.surface.find_entities_filtered(), with force set to all enemy forces of the vehicle's force, and is_military_target set to true. If this returns more than one vehicle, enemy will be set to the first entity found within min_range.

However, that includes more code for storing/updating the enemy forces of each force stored in storage.force_data, so you'll have to wait for the next update. :-)

a month ago

Oh yeah, no problem, honestly I just wanted to get to the bottom of this at this point, in my current playthrough I don't really need to think about the biters anymore anyway. Looking forward for these issues and the Editor Extensions compatibility to be resolved in the next update, thank you for your time and effort, this is a really good mod.

30 days ago

Thanks for the compliment, glad you like the mod! I just released the update (version 2.0.5). Can you confirm that it fixes everything discussed in this thread?

30 days ago

There's now a new bug that causes a crash as soon as you add any vehicle with a remote:
The mod Autodrive (2.0.5) caused a non-recoverable error.
Please report this error to the mod author.

Error while running event autodrive::on_tick (ID 0)
autodrive/scripts/driving.lua:102: attempt to compare nil with number
stack traceback:
autodrive/scripts/driving.lua:102: in function 'check_crons'
autodrive/scripts/driving.lua:994: in function 'tick_vehicle'
autodrive/scripts/event_handlers.lua:1438: in function <autodrive/scripts/event_handlers.lua:1392>

29 days ago

Changing line 102 in scripts/driving.lua from

                        (state.shooting_until_tick <= game.tick)

to

                        (state.shooting_until_tick and
                          state.shooting_until_tick <= game.tick)

should fix this.

29 days ago

I think that did the trick, the slow fire rate issue went away as well.

13 days ago

Please try version 2.0.6!

New response