Array of vehicle spawners not consistently assinging drivers

I built a device to take in an array of ufo vehicle spawners and when a player activates a conditional button they get assigned to one of the spawners and it gets marked in use using a map. Once the vehicle is destroyed, it gets marked back to not in use. I only have 3 spawners for testing but I will scale to 16 for all players on the map s at any given point any players can spawn a ufo without knocking another player out of theirs.

Everything works fine at first, however the issue is that once a driver gets assigned to a vehicle and that vehicle gets destroyed, after they respawn and try to spawn another vehicle, the code shows the last one they were in is available and says they are assigned as a driver but the vehicle spawns without them inside. Therefore the vehicle never gets destroyed and the button has to be hit again which then spawns them in the next available vehicle in the array.Which again works just fine, until THAT vehicle is destroyed and they move to the next one and so on and so forth eventually exhausting the array and making no more vehicles available. I’ve been trying all sorts of combinations and the problem persists.

Is there some flag I don’t know about that prevents them from respawning into a vehicle they previously occupied?

Also is this going to work with multiple players? It’s my first time doing something of this nature in Verse. Thanks!

    @editable ConditionalButton : conditional_button_device = conditional_button_device{}
    @editable VehicleSpawners : []vehicle_spawner_ufo_device = array{}
   
    var tempSpawner : vehicle_spawner_ufo_device = vehicle_spawner_ufo_device{}
    var vehicle_index : int = 0
    var tempIndex : int = 0

    #Map value of 0 indicates not in use, 1 indicates in use
    var VehicleInUse : [int]int = map{
                                            0=> 0
                                            1=> 0
                                            2=> 0}


    OnBegin<override>():void=
        # Subscribes to the InteractedEvent of the ConditionalButton.
        ConditionalButton.ActivatedEvent.Subscribe(HandleButtonInteraction)
        # Print("{VehicleInUse.Length}")


    # Function to handle the button interaction.
    HandleButtonInteraction(Agent : agent):void=
        SpawnPlayerInAvailableVehicle(Agent)

    # Function to find an available vehicle spawner and spawn the player.
    SpawnPlayerInAvailableVehicle(Agent : agent):void=
        # Iterate through the vehicle spawners to find an available one.
        Print("About to enter the loop")
        #Show current use state of all vehicles
        for (Key->Value : VehicleInUse):
            Print("{Value} value in VehicleInUse at key {Key}")
        #Set vhicle index counter back to start of array
        set vehicle_index = 0
        #Loop through the vehicle spawners to find an available one
        for (VehicleSpawner : VehicleSpawners):
            Print("Checking index. {vehicle_index}")
            if (VehicleInUse[vehicle_index] = 0):
                VehicleSpawner.Enable()
                VehicleSpawner.AssignDriver(Agent)
                Print("Assigned driver to vehicle spawner {vehicle_index}")
                #Mark the vehicle as in use.
                if (set VehicleInUse[vehicle_index] = 1):
                #Spawn function to listen for vehicle destroyed event    
                    spawn:
                        IfVehicleDestroyed(VehicleSpawner, vehicle_index)
                return
            else:
                if (VehicleInUse[vehicle_index] = 1):
                set vehicle_index += 1

    # Subscribe to the Vehicle DestroyedEvent
    IfVehicleDestroyed(Spawner : vehicle_spawner_ufo_device, Index : int)<suspends>:void=
        Print("Waiting for destroyed event for index, {Index}")
        Spawner.DestroyedEvent.Subscribe(HandleVehicleDestroyed)
        set tempIndex = Index
        set tempSpawner = Spawner
    
    #Mark the vehicle as not in use
    HandleVehicleDestroyed():void=
        Print("Setting back to false for index {tempIndex}")
        if (set VehicleInUse[tempIndex] = 0):
        tempSpawner.Disable()

Hey, I can kind of see what you’re trying to do.

The problem with the vehicle spawning without the player assigned to them might be caused by enabling it just before assigning the driver, you can try adding a delay:

VehicleSpawner.Enable()
Sleep(0.2)
VehicleSpawner.AssignDriver(Agent)

Still, to answer your question, it’s not going to work with multiple players. Specially with how you handle marking a vehicle as not in use (after being destroyed) by using tempIndex and tempSpawner:

  1. Player A gets assigned a vehicle, then tempIndex is 0.
  2. Player B gets assigned a vehicle, then tempIndex is 1.
  3. Player A’s vehicle is destroyed so HandleVehicleDestroyed() is called.
  4. Because tempIndex is now 1, then the vehicle that is set as “not in use” is the one from Player B instead, which is incorrect.

It’s been 10 days since your post so I’m not sure if you’ve got this all fixed. In case you still need help, please say so and I can try to help! :slight_smile:

I recently did a vehicle based map and encountered similar problems, what I did to get around it was have functions like TryAssignDriver where we keep trying every .1 seconds to assign them and then check if they are in vehicle, if so then break and if not try again. (.inVehicle is from customPlayer class I made where I just subscribe to the player’s enter and exit vehicle event) if you race this loop against Sleep(10.0) it will fail after 10 seconds. Looks like this:

    TryAssignDriver(A : agent, V : vehicle_spawner_device, C: CustomPlayer, FC : fort_character)<suspends>: void =
        
        var i : int = 0
        race:
            loop:
                Print("try assign {i}")
                if:
                    C.inVehicle = true
                then:
                    Print("Success")
                    break
                else:
                    V.AssignDriver(A)

                set i += 1
                Sleep(0.1)
            block:
                Sleep(10.0)
                Print("Assign Failed")

As far as keeping track of player’s vehicles, I use an AssetPool script where I check out the vehicle spawner assets per player:

PlayerAssets := class<concrete>:
    var checkedOut : logic = false
    @editable Follower : creative_prop = creative_prop{}#used for fps cam blocker, lights (?), particle FX
    @editable Teleporter : creative_prop = creative_prop{} #used for teleporting spawners
    @editable Bike : vehicle_spawner_sportbike_device = vehicle_spawner_sportbike_device{}
    @editable SUV : vehicle_spawner_valet_suv_device = vehicle_spawner_valet_suv_device{}
    @editable Sedan : vehicle_spawner_sedan_device = vehicle_spawner_sedan_device{}


    

Asset_Pool := class(creative_device):
    @editable AssetPool<public> : []PlayerAssets = array{}

    CheckOut<public>(id : int): void =
        if:
            AssetPool[id].checkedOut = false
            set AssetPool[id].checkedOut = true
        then:
            Print("checked out {id}")
        else :
            Print("already checked out!")
        
        #set checkedOut = true
    Return<public>(id : int): void =
        if:
            AssetPool[id].checkedOut = true
            set AssetPool[id].checkedOut = false
        then:
            Print("returned {id}")
        else:
            Print("not checked out!")