182 lines
6.2 KiB
Lua
182 lines
6.2 KiB
Lua
-- Snap amount is the amount of different angles car aims to drive,
|
|
-- (360 / vehiclesnap_amount) is the difference between each direction.
|
|
-- Car will slowly turn towards such angle.
|
|
-- Default amount is 16, recommended to try with other multiples of 4.
|
|
-- You can change snapping amount and keybinds in ingame-menus.
|
|
|
|
local function OnOffText(value)
|
|
if value then return {"description.VehicleSnap_enable"}
|
|
else return {"description.VehicleSnap_disable"} end
|
|
end
|
|
|
|
local function PlayerToggle(event)
|
|
local player = game.players[event.player_index]
|
|
global.players[event.player_index].snap = not global.players[event.player_index].snap
|
|
CheckDrivingState(player)
|
|
-- Create floating text at car position (auto-disappears after a couple of seconds)
|
|
player.surface.create_entity{ name = "flying-text", position = player.position,
|
|
text = OnOffText(global.players[event.player_index].snap) }
|
|
player.set_shortcut_toggled("VehicleSnap-shortcut", global.players[event.player_index].snap)
|
|
end
|
|
|
|
script.on_event("VehicleSnap-toggle", PlayerToggle)
|
|
|
|
-- This is ran everytime the game is changed (adding mods upgrading etc) and installed.
|
|
local function run_install()
|
|
global.players = global.players or {}
|
|
for i, player in (pairs(game.players)) do
|
|
--game.players[i].print("VehicleSnap installed") -- Debug
|
|
global.players[i] = global.players[i] or {
|
|
snap = true,
|
|
player_ticks = 0,
|
|
last_orientation = 0,
|
|
-- driving is only true if snapping is true and player is in a valid vehicle
|
|
driving = false,
|
|
moves = 0,
|
|
eff_moves = 0, -- Effective tile moves from last time period
|
|
snap_amount = 16
|
|
}
|
|
local snap = settings.get_player_settings(player)["VehicleSnap_amount"].value
|
|
if snap ~= nil then
|
|
global.players[i].snap_amount = snap
|
|
end
|
|
|
|
CheckDrivingState(player)
|
|
player.set_shortcut_toggled("VehicleSnap-shortcut", global.players[i].snap)
|
|
end
|
|
ToggleEvents(true)
|
|
end
|
|
|
|
-- Any time a new player is created run this.
|
|
script.on_event(defines.events.on_player_created, function(event)
|
|
global.players[event.player_index] = {
|
|
snap = true,
|
|
player_ticks = 0,
|
|
last_orientation = 0,
|
|
driving = false,
|
|
moves = 0,
|
|
eff_moves = 0,
|
|
snap_amount = 16
|
|
}
|
|
local snap = settings.get_player_settings(game.players[event.player_index])["VehicleSnap_amount"].value
|
|
if snap ~= nil then
|
|
global.players[event.player_index].snap_amount = snap
|
|
end
|
|
end)
|
|
|
|
script.on_event(defines.events.on_runtime_mod_setting_changed, function(event)
|
|
if event.setting == "VehicleSnap_amount" then
|
|
local snap = settings.get_player_settings(game.players[event.player_index])["VehicleSnap_amount"].value
|
|
if snap ~= nil then
|
|
global.players[event.player_index].snap_amount = snap
|
|
end
|
|
end
|
|
end)
|
|
|
|
function CheckDrivingState(player)
|
|
local pdata = global.players[player.index]
|
|
local driving = false
|
|
if player.vehicle and pdata.snap then -- and player.connected
|
|
driving = (player.vehicle.type == "car")
|
|
pdata.moves = 0
|
|
pdata.eff_moves = 0
|
|
pdata.snap_amount = pdata.snap_amount or 16
|
|
end
|
|
pdata.driving = driving
|
|
ToggleEvents(true)
|
|
end
|
|
|
|
script.on_event(defines.events.on_player_driving_changed_state, function(event)
|
|
CheckDrivingState(game.players[event.player_index])
|
|
end)
|
|
|
|
script.on_event(defines.events.on_player_died, function(event)
|
|
CheckDrivingState(game.players[event.player_index])
|
|
end)
|
|
|
|
local function onPlayerChangedPosition(event)
|
|
local pdata = global.players[event.player_index]
|
|
if pdata and pdata.driving then
|
|
pdata.moves = pdata.moves + 1
|
|
|
|
-- Debug player speed values
|
|
--local player = game.players[event.player_index]
|
|
--if player.vehicle then
|
|
-- player.surface.create_entity{ name = "flying-text", position = player.position, text = player.vehicle.speed }
|
|
--end
|
|
end
|
|
end
|
|
|
|
local function onTick()
|
|
if game.tick % 2 == 0 then
|
|
local drivers = false
|
|
moveReset = (game.tick % 40 == 0)
|
|
for _, player in pairs(game.connected_players) do
|
|
local pdata = global.players[player.index]
|
|
if pdata.driving and pdata.snap then
|
|
if not player.vehicle then
|
|
if player.controller_type == defines.controllers.character then
|
|
-- Use of Space Exploration navigation satellite changes controller to godmode,
|
|
-- after which it returns to car.
|
|
pdata.driving = false
|
|
else
|
|
drivers = true
|
|
end
|
|
else
|
|
drivers = true
|
|
if (pdata.eff_moves > 1) and (math.abs(player.vehicle.speed) > 0.03) then
|
|
local o = player.vehicle.orientation -- float value, the direction vehicle is facing
|
|
-- Has player turned vehicle? Don't push against,
|
|
-- so delay snapping a little with player_ticks
|
|
if math.abs(o - pdata.last_orientation) < 0.001 then
|
|
if pdata.player_ticks > 1 then
|
|
local snap_o = math.floor(o * pdata.snap_amount + 0.5) / pdata.snap_amount
|
|
-- Interpolate with 80% current and 20% target orientation
|
|
o = (o * 4.0 + snap_o) * 0.2
|
|
player.vehicle.orientation = o
|
|
else
|
|
pdata.player_ticks = pdata.player_ticks + 1
|
|
end
|
|
else
|
|
pdata.player_ticks = 0
|
|
end
|
|
pdata.last_orientation = o
|
|
end
|
|
if moveReset then -- Counting tile changes, reset every 40 ticks
|
|
pdata.eff_moves = pdata.moves
|
|
pdata.moves = 0
|
|
end
|
|
end
|
|
end
|
|
end
|
|
if not drivers then
|
|
ToggleEvents(false)
|
|
end
|
|
end
|
|
end
|
|
|
|
function ToggleEvents(enable)
|
|
global.RegisterEvents = enable
|
|
if enable then
|
|
script.on_event(defines.events.on_tick, onTick)
|
|
script.on_event(defines.events.on_player_changed_position, onPlayerChangedPosition)
|
|
else
|
|
script.on_event(defines.events.on_tick, nil)
|
|
script.on_event(defines.events.on_player_changed_position, nil)
|
|
end
|
|
end
|
|
|
|
script.on_init(run_install)
|
|
script.on_configuration_changed(run_install)
|
|
|
|
script.on_load(function()
|
|
if global.RegisterEvents then
|
|
ToggleEvents(true)
|
|
end
|
|
end)
|
|
|
|
script.on_event(defines.events.on_lua_shortcut, function(event)
|
|
if event.prototype_name == "VehicleSnap-shortcut" then
|
|
PlayerToggle(event)
|
|
end
|
|
end) |