520 lines
16 KiB
Lua
Raw Normal View History

2020-10-04 03:37:08 +02:00
-- autofly by cora
-- gui shit shamelessly stolen from advmarkers
-- https://git.minetest.land/luk3yx/advmarkers-csm
--[[
PATCHING MINETEST: (for autoaim)
in l_localplayer.h add:
static int l_set_yaw(lua_State *L);
static int l_set_pitch(lua_State *L);
in l_localplayer.cpp add:
int LuaLocalPlayer::l_set_yaw(lua_State *L)
{
LocalPlayer *player = getobject(L, 1);
f32 p = (float) luaL_checkinteger(L, 2);
player->setYaw(p);
g_game->cam_view.camera_yaw = p;
g_game->cam_view_target.camera_yaw = p;
player->setYaw(p);
return 0;
}
int LuaLocalPlayer::l_set_pitch(lua_State *L)
{
LocalPlayer *player = getobject(L, 1);
f32 p = (float) luaL_checkinteger(L, 2);
player->setPitch(p);
g_game->cam_view.camera_pitch = p;
g_game->cam_view_target.camera_pitch = p;
player->setPitch(p);
return 0;
}
in src/client/game.h, below class Game { public: add:
CameraOrientation cam_view = {0};
CameraOrientation cam_view_target = { 0 };
from src/client/game.cpp remove
CameraOrientation cam_view = {0};
CameraOrientation cam_view_target = { 0 };
--]]
-- Chat commands:
-- .wa x,y,z name - add waypoint with coords and name
-- .wah - quickadd this location (name will be time and date)
-- .wp - open the selection menu
-- .cls - remove hud
autofly = {}
wps={}
local landing_distance=100
local speed=0;
local ltime=0
local storage = minetest.get_mod_storage()
2020-10-25 11:15:08 +01:00
local oldpm=false
local lpos={x=0,y=0,z=0}
2020-10-04 03:37:08 +02:00
local info=minetest.get_server_info()
local stprefix="autofly-".. info['address'] .. '-'
autofly.flying=false
2020-10-04 03:37:08 +02:00
local modname = minetest.get_current_modname()
local modpath = minetest.get_modpath(modname)
dofile(modpath .. "/wpforms.lua")
local hud_wp
local hud_info
-- /COMMON
local function pos_to_string(pos)
if type(pos) == 'table' then
pos = minetest.pos_to_string(vector.round(pos))
end
if type(pos) == 'string' then
return pos
end
end
local function string_to_pos(pos)
if type(pos) == 'string' then
pos = minetest.string_to_pos(pos)
end
if type(pos) == 'table' then
return vector.round(pos)
end
end
function round2(num, numDecimalPlaces)
return tonumber(string.format("%." .. (numDecimalPlaces or 0) .. "f", num))
end
local last_sprint = false
2020-10-04 03:37:08 +02:00
minetest.register_globalstep(function()
autofly.checkfall()
2020-11-14 14:05:13 +01:00
autofly.axissnap()
if minetest.settings:get_bool("autosprint") or (minetest.settings:get_bool("continuous_forward") and minetest.settings:get_bool("autofsprint")) then
2020-10-23 02:19:12 +02:00
core.set_keypress("special1", true)
last_sprint = true
elseif last_sprint then
core.set_keypress("special1", false)
last_sprint = false
2020-10-23 02:19:12 +02:00
end
2020-10-04 03:37:08 +02:00
if not minetest.localplayer then return end
if not autofly.flying then autofly.set_hud_info("")
else
local pos = autofly.last_coords
2020-10-04 03:37:08 +02:00
if pos then
local dst = vector.distance(pos,minetest.localplayer:get_pos())
local etatime=-1
if not (speed == 0) then etatime = round2(dst / speed / 60,2) end
autofly.set_hud_info(autofly.last_name .. "\n" .. pos_to_string(pos) .. "\n" .. "ETA" .. etatime .. " mins")
2020-11-15 04:10:41 +01:00
if autofly.flying and dst < landing_distance then
2020-10-04 03:37:08 +02:00
autofly.arrived()
end
end
end
if not minetest.settings:get_bool("freecam") and autofly.flying and (minetest.settings:get_bool('afly_autoaim')) then
autofly.aim(autofly.last_coords)
--core.set_keypress("special1", true)
2020-10-04 03:37:08 +02:00
end
if ( os.time() < ltime + 1 ) then return end
ltime=os.time()
if lpos then
local dst=vector.distance(minetest.localplayer:get_pos(),lpos)
speed=round2(dst,1)
autofly.speed=speed
2020-10-04 03:37:08 +02:00
end
lpos=minetest.localplayer:get_pos()
end)
function autofly.getwps()
local wp={}
for name, _ in pairs(storage:to_table().fields) do
if name:sub(1, string.len(stprefix)) == stprefix then
table.insert(wp, name:sub(string.len(stprefix)+1))
end
end
table.sort(wp)
return wp
end
function autofly.set_hud_wp(pos, title)
if hud_wp then
minetest.localplayer:hud_remove(hud_wp)
end
pos = string_to_pos(pos)
hud_wp=nil
if not pos then return end
if not title then
title = pos.x .. ', ' .. pos.y .. ', ' .. pos.z
end
autofly.last_name=title
2020-10-04 03:37:08 +02:00
if hud_wp then
minetest.localplayer:hud_change(hud_wp, 'name', title)
minetest.localplayer:hud_change(hud_wp, 'world_pos', pos)
else
hud_wp = minetest.localplayer:hud_add({
hud_elem_type = 'waypoint',
name = title,
text = 'm',
number = 0x00ff00,
world_pos = pos
})
end
minetest.display_chat_message('Waypoint set to ' .. title)
-- minetest.colorize('#00ffff', title))
return true
end
local hud_info
function autofly.set_hud_info(text)
if not minetest.localplayer then return end
2020-11-14 14:05:13 +01:00
local vspeed=minetest.localplayer:get_velocity()
--local vspeed=vector.round(minetest.localplayer:get_velocity(),4)
2020-11-14 23:49:05 +01:00
local ttext=text.."\nSpeed: "..speed.."n/s\n"..round2(vspeed.x,2) ..','..round2(vspeed.y,2) ..','..round2(vspeed.z,2) .."\nYaw:"..round2(minetest.localplayer:get_yaw(),2).."° Pitch:" ..round2(minetest.localplayer:get_pitch(),2).."°"
2020-10-04 03:37:08 +02:00
if hud_info then
minetest.localplayer:hud_change(hud_info,'text',ttext)
else
hud_info = minetest.localplayer:hud_add({
hud_elem_type = 'text',
name = "Flight Info",
text = ttext,
number = 0x00ff00,
direction = 0,
2020-11-14 04:11:08 +01:00
position = {x=0,y=0.80},
2020-10-04 03:37:08 +02:00
alignment ={x=1,y=1},
offset = {x=0, y=0}
})
end
return true
end
function autofly.checkfall()
if(speed > 30) then
local nod=minetest.get_node_or_nil(vector.add(minetest.localplayer:get_pos(),{x=0,y=-100,z=0}))
if nod and not ( nod['name'] == "air" ) then
minetest.settings:set("free_move", "true")
minetest.settings:set("noclip", "false")
minetest.display_chat_message("fall detected")
end
end
end
function autofly.display_waypoint(name)
autofly.last_coords = autofly.get_waypoint(name)
autofly.last_name = name
autofly.set_hud_info(name)
autofly.aim(autofly.last_coords)
return autofly.set_hud_wp(autofly.get_waypoint(name), name)
end
function autofly.goto_waypoint(name)
2020-11-14 23:49:05 +01:00
autofly.goto(autofly.get_waypoint(name))
autofly.last_name=name
autofly.set_hud_wp(autofly.get_waypoint(name), name)
end
function autofly.goto(pos)
2020-10-25 11:15:08 +01:00
oldpm=minetest.settings:get_bool("pitch_move")
minetest.settings:set_bool("pitch_move",true)
minetest.settings:set_bool("continuous_forward",true)
minetest.settings:set_bool("autofsprint",true)
minetest.settings:set_bool("afly_autoaim",true)
minetest.settings:set_bool("autoeat_timed",true)
autofly.last_coords = pos
autofly.last_name = minetest.pos_to_string(pos)
2020-10-23 02:19:12 +02:00
--minetest.settings:set("movement_speed_walk", "5")
autofly.aim(autofly.last_coords)
autofly.flying=true
2020-10-04 03:37:08 +02:00
return autofly.set_hud_wp(autofly.get_waypoint(name), name)
end
function autofly.arrived()
minetest.settings:set("continuous_forward", "false")
minetest.settings:set_bool("autofsprint",false)
2020-10-25 11:15:08 +01:00
minetest.settings:set_bool("pitch_move",oldpm)
2020-11-01 16:21:54 +01:00
minetest.settings:set_bool("afly_autoaim",false)
minetest.settings:set_bool("autoeat_timed",false)
2020-10-04 03:37:08 +02:00
autofly.set_hud_info("Arrived at destination")
2020-11-15 17:09:45 +01:00
autofly.flying = false
minetest.localplayer:hud_change(hud_info,'text',autofly.last_name .. "\n" .. "Arrived at destination.")
minetest.sound_play({name = "default_dug_metal", gain = 1.0})
2020-10-04 03:37:08 +02:00
end
function autofly.checkfall()
if(speed > 30) then
local nod=minetest.get_node_or_nil(vector.add(minetest.localplayer:get_pos(),{x=0,y=-100,z=0}))
if nod and not ( nod['name'] == "air" ) then
2020-10-23 02:19:12 +02:00
-- minetest.display_chat_message("Autofly: Fall to ground detected!")
-- minetest.display_chat_message("Deactivating noclip.")
2020-10-04 03:37:08 +02:00
minetest.settings:set("noclip", "false")
if(minetest.settings:get_bool("afly_softlanding")) then
2020-10-23 02:19:12 +02:00
-- minetest.display_chat_message("Soft landing engaged.")
2020-10-04 03:37:08 +02:00
minetest.settings:set("free_move", "true")
else
2020-10-23 02:19:12 +02:00
-- minetest.display_chat_message("Lithobreak imminent maybe turn on soft landing next time")
2020-10-04 03:37:08 +02:00
end
end
end
end
function autofly.warp(name)
local pos=vector.add(autofly.get_waypoint(name),{x=0,y=150,z=0})
if pos then
minetest.localplayer:set_pos(pos)
return true, "Warped to " .. minetest.pos_to_string(pos)
end
end
function autofly.warpae(name)
local s, m = autofly.warp(name)
if s then
minetest.disconnect()
end
return s,m
end
function autofly.set_waypoint(pos, name)
pos = pos_to_string(pos)
if not pos then return end
storage:set_string(stprefix .. tostring(name), pos)
return true
end
-- Delete a waypoint
function autofly.delete_waypoint(name)
storage:set_string(stprefix .. tostring(name), '')
end
-- Get a waypoint
function autofly.get_waypoint(name)
return string_to_pos(storage:get_string(stprefix .. tostring(name)))
end
-- Rename a waypoint and re-interpret the position.
function autofly.rename_waypoint(oldname, newname)
oldname, newname = tostring(oldname), tostring(newname)
local pos = autofly.get_waypoint(oldname)
if not pos or not autofly.set_waypoint(pos, newname) then return end
if oldname ~= newname then
autofly.delete_waypoint(oldname)
end
return true
end
function autofly.get_chatcommand_pos(pos)
if pos == 'h' or pos == 'here' then
pos = minetest.localplayer:get_pos()
elseif pos == 't' or pos == 'there' then
if not autofly.last_coords then
return false, 'No-one has used ".coords" and you have not died!'
end
pos = autofly.last_coords
else
pos = string_to_pos(pos)
if not pos then
return false, 'Invalid position!'
end
end
return pos
end
local function register_chatcommand_alias(old, ...)
local def = assert(minetest.registered_chatcommands[old])
def.name = nil
for i = 1, select('#', ...) do
minetest.register_chatcommand(select(i, ...), table.copy(def))
end
end
minetest.register_chatcommand('waypoints', {
params = '',
description = 'Open the autofly GUI',
func = function(param)
if param == '' then
autofly.display_formspec()
else
local pos, err = autofly.get_chatcommand_pos(param)
if not pos then
return false, err
end
if not autofly.set_hud_wp(pos) then
return false, 'Error setting the waypoint!'
end
end
end
})
register_chatcommand_alias('waypoints','wp', 'wps', 'waypoint')
-- Add a waypoint
minetest.register_chatcommand('add_waypoint', {
params = '<pos / "here" / "there"> <name>',
description = 'Adds a waypoint.',
func = function(param)
local s, e = param:find(' ')
if not s or not e then
return false, 'Invalid syntax! See .help add_mrkr for more info.'
end
local pos = param:sub(1, s - 1)
local name = param:sub(e + 1)
-- Validate the position
local pos, err = autofly.get_chatcommand_pos(pos)
if not pos then
return false, err
end
-- Validate the name
if not name or #name < 1 then
return false, 'Invalid name!'
end
-- Set the waypoint
return autofly.set_waypoint(pos, name), 'Done!'
end
})
register_chatcommand_alias('add_waypoint','wa', 'add_wp')
minetest.register_chatcommand('add_waypoint_here', {
params = 'name',
description = 'marks the current position',
func = function(param)
local name = os.date("%Y-%m-%d %H:%M:%S")
local pos = minetest.localplayer:get_pos()
return autofly.set_waypoint(pos, name), 'Done!'
end
})
register_chatcommand_alias('add_waypoint_here', 'wah', 'add_wph')
minetest.register_chatcommand('clear_waypoint', {
params = '',
description = 'Hides the displayed waypoint.',
func = function(param)
if autofly.flying then autofly.flying=false end
2020-10-04 03:37:08 +02:00
if hud_wp then
minetest.localplayer:hud_remove(hud_wp)
hud_wp = nil
return true, 'Hidden the currently displayed waypoint.'
elseif not minetest.localplayer.hud_add then
minetest.run_server_chatcommand('clrmrkr')
return
elseif not hud_wp then
return false, 'No waypoint is currently being displayed!'
end
for k,v in wps do
minetest.localplayer:hud_remove(v)
table.remove(k)
end
end,
})
minetest.register_chatcommand('atp', {
params = 'position',
description = 'autotp',
func = function(param)
2020-11-11 21:33:12 +01:00
autofly.autotp(minetest.string_to_pos(param))
end
})
2020-10-04 03:37:08 +02:00
minetest.register_on_death(function()
if minetest.localplayer then
local name = 'Death waypoint'
local pos = minetest.localplayer:get_pos()
autofly.last_coords = pos
autofly.set_waypoint(pos, name)
minetest.display_chat_message('Added waypoint "' .. name .. '".')
end
end)
function autofly.aim(tpos)
local ppos=minetest.localplayer:get_pos()
--local dir=tpos
local dir=vector.direction(ppos,tpos)
local yyaw=0;
local pitch=0;
if dir.x < 0 then
yyaw = math.atan2(-dir.x, dir.z) + (math.pi * 2)
else
yyaw = math.atan2(-dir.x, dir.z)
end
yyaw = round2(math.deg(yyaw),0)
pitch = round2(math.deg(math.asin(-dir.y) * 1),0);
minetest.localplayer:set_yaw(yyaw)
minetest.localplayer:set_pitch(pitch)
end
2020-11-11 23:21:14 +01:00
function autofly.autotp(tpname)
if minetest.localplayer == nil then return end
2020-11-11 23:21:14 +01:00
local tpos=nil
if tpname == nil then
2020-11-11 21:33:12 +01:00
tpos = autofly.get_waypoint('AUTOTP')
2020-11-11 23:21:14 +01:00
else
tpos=autofly.get_waypoint(tpname)
end
2020-11-11 21:33:12 +01:00
if tpos == nil then return end
local lp=minetest.localplayer
2020-11-11 21:33:12 +01:00
local dst=vector.distance(lp:get_pos(),tpos)
if (dst < 500) then
2020-11-12 00:56:28 +01:00
minetest.sound_play({name = "default_dug_metal", gain = 1.0})
autofly.delete_waypoint('AUTOTP')
return
end
autofly.set_waypoint(tpos,'AUTOTP')
for k, v in ipairs(lp.get_nearby_objects(4)) do
2020-11-11 21:33:12 +01:00
local txt = v:get_item_textures()
if ( txt:find('mcl_boats_texture')) then
autofly.aim(vector.add(v:get_pos(),{x=0,y=-1.5,z=0}))
minetest.after("0.2",function()
minetest.interact(3) end)
2020-11-11 21:33:12 +01:00
minetest.after("2.5",function()
2020-11-11 21:35:41 +01:00
autofly.warpae('AUTOTP')
2020-11-11 21:33:12 +01:00
end)
return
end
end
2020-11-12 00:56:28 +01:00
minetest.sound_play({name = "default_dug_metal", gain = 1.0})
autofly.delete_waypoint('AUTOTP')
end
2020-11-14 14:05:13 +01:00
function autofly.axissnap()
if not minetest.settings:get_bool('afly_snap') then return end
2020-11-14 23:49:05 +01:00
local y=minetest.localplayer:get_yaw()
2020-11-14 14:05:13 +01:00
local yy=nil
if ( y < 45 or y > 315 ) then
yy=0
elseif (y < 135) then
yy=90
elseif (y < 225 ) then
yy=180
elseif ( y < 315 ) then
yy=270
end
if yy ~= nil then
minetest.localplayer:set_yaw(yy)
end
end
minetest.after("3.0",function()
2020-11-11 21:33:12 +01:00
if autofly.get_waypoint('AUTOTP') ~= nil then autofly.autotp(nil) end
end)
2020-10-04 03:37:08 +02:00
register_chatcommand_alias('clear_waypoint', 'cwp','cls')
if (_G["minetest"]["register_cheat"] == nil) then
minetest.settings:set_bool("afly_autoaim", false)
minetest.settings:set_bool("afly_softlanding", true)
else
minetest.register_cheat("Aim", "Autofly", "afly_autoaim")
2020-11-14 14:05:13 +01:00
minetest.register_cheat("AxisSnap", "Autofly", "afly_snap")
minetest.register_cheat("Softlanding", "Autofly", "afly_softlanding")
minetest.register_cheat("Waypoints", "Autofly", autofly.display_formspec)
2020-10-04 03:37:08 +02:00
end