[Rseding91] [0.16.18] No way to eject a player from a vehicle sometimes
Posted: Wed Jan 24, 2018 12:47 pm
If a vehicle is surrounded by colliding entities for whatever reason, calling vehicle.set_driver(nil) does nothing. This makes sense in some situations where you don't want the player overlapping colliding entities, but if you need to destroy the vehicle that tick it's a game breaking problem because the player dies when you call .destroy().
The problem is made worse in that Vehicle_B.set_driver(Vehicle_A.get_driver()) also won't work if Vehicle_A's exit is blocked. Ideally if you're transferring a player between vehicles it would skip any player-can_place_entity style check and just put them in the other vehicle wherever that may be.
I tried moving the blocked vehicle to an open area before ejecting the player, but that only works if the eject command is on a tick after the Vehicle_A.teleport command. If they are called on the same tick then the passenger is still stuck (and killed if Vehicle_A is destroyed).
If there was a way to do something like: Vehicle_A.set_driver(nil, true) where the 2nd parameter is an override to skip placement checking then there would be a way out of the situation. Also if teleporting the vehicle before ejecting worked then that would be a workaround, it seems strange that doesn't.
Below is some code to recreate the problems:
v1.set_driver(nil) does not eject the player:
v2.set_driver(v1.get_driver()) does not transfer the player: (Note: v2 is in a clear unblocked position away from v1)
v1.set_driver(nil) does not eject the player even if the vehicle is moved to a clear position that tick:
The problem is made worse in that Vehicle_B.set_driver(Vehicle_A.get_driver()) also won't work if Vehicle_A's exit is blocked. Ideally if you're transferring a player between vehicles it would skip any player-can_place_entity style check and just put them in the other vehicle wherever that may be.
I tried moving the blocked vehicle to an open area before ejecting the player, but that only works if the eject command is on a tick after the Vehicle_A.teleport command. If they are called on the same tick then the passenger is still stuck (and killed if Vehicle_A is destroyed).
If there was a way to do something like: Vehicle_A.set_driver(nil, true) where the 2nd parameter is an override to skip placement checking then there would be a way out of the situation. Also if teleporting the vehicle before ejecting worked then that would be a workaround, it seems strange that doesn't.
Below is some code to recreate the problems:
v1.set_driver(nil) does not eject the player:
Code: Select all
/c p = game.player
s = p.surface
pos = {x = math.floor(game.player.position.x)+0.5, y = math.floor(game.player.position.y)+0.5}
s.create_entity{name="stone-wall", position={pos.x -1, pos.y-1}, force = p.force}
s.create_entity{name="stone-wall", position={pos.x, pos.y-1}, force = p.force}
s.create_entity{name="stone-wall", position={pos.x +1, pos.y-1}, force = p.force}
s.create_entity{name="stone-wall", position={pos.x -1, pos.y}, force = p.force}
s.create_entity{name="stone-wall", position={pos.x +1, pos.y}, force = p.force}
s.create_entity{name="stone-wall", position={pos.x -1, pos.y+1}, force = p.force}
s.create_entity{name="stone-wall", position={pos.x, pos.y+1}, force = p.force}
s.create_entity{name="stone-wall", position={pos.x +1, pos.y+1}, force = p.force}
v1 = s.create_entity{name="car", position=pos, force=p.force}
v1.set_driver(p)
v1.set_driver(nil)
Code: Select all
/c p = game.player
s = p.surface
pos = {x = math.floor(game.player.position.x)+0.5, y = math.floor(game.player.position.y)+0.5}
s.create_entity{name="stone-wall", position={pos.x -1, pos.y-1}, force = p.force}
s.create_entity{name="stone-wall", position={pos.x, pos.y-1}, force = p.force}
s.create_entity{name="stone-wall", position={pos.x +1, pos.y-1}, force = p.force}
s.create_entity{name="stone-wall", position={pos.x -1, pos.y}, force = p.force}
s.create_entity{name="stone-wall", position={pos.x +1, pos.y}, force = p.force}
s.create_entity{name="stone-wall", position={pos.x -1, pos.y+1}, force = p.force}
s.create_entity{name="stone-wall", position={pos.x, pos.y+1}, force = p.force}
s.create_entity{name="stone-wall", position={pos.x +1, pos.y+1}, force = p.force}
v1 = s.create_entity{name="car", position=pos, force=p.force}
v1.set_driver(p)
v2 = s.create_entity{name="car", position={pos.x + 4, pos.y}, force=p.force}
v2.set_driver(v1.get_driver())
Code: Select all
/c p = game.player
s = p.surface
pos = {x = math.floor(game.player.position.x)+0.5, y = math.floor(game.player.position.y)+0.5}
s.create_entity{name="stone-wall", position={pos.x -1, pos.y-1}, force = p.force}
s.create_entity{name="stone-wall", position={pos.x, pos.y-1}, force = p.force}
s.create_entity{name="stone-wall", position={pos.x +1, pos.y-1}, force = p.force}
s.create_entity{name="stone-wall", position={pos.x -1, pos.y}, force = p.force}
s.create_entity{name="stone-wall", position={pos.x +1, pos.y}, force = p.force}
s.create_entity{name="stone-wall", position={pos.x -1, pos.y+1}, force = p.force}
s.create_entity{name="stone-wall", position={pos.x, pos.y+1}, force = p.force}
s.create_entity{name="stone-wall", position={pos.x +1, pos.y+1}, force = p.force}
v1 = s.create_entity{name="car", position=pos, force=p.force}
v1.set_driver(p)
v1.teleport({pos.x + 4, pos.y})
v1.set_driver(nil)