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
a month ago
0.17 - 2.0
3.27K
Transportation Combat Logistic network Circuit network

b [Pending] Vehicles panicking despite having ammo for their guns

5 days ago
(updated 5 days 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.

4 days ago

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

4 days ago
(updated 4 days 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.

3 days 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 …

3 days ago
(updated 3 days 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.

2 days 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 day 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 day 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.

14 hours 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.

New response