Below is [another] flight script. It has some issues and some help would be appreciated.
The input keystrokes seem to be registered more than once per press. I have used a KeyPressed variable,
but I still get extra keystrokes.
Any other suggestion for optimization are also welcome.
Description:
The player can move an entity up, down, forward or backward and turn it left and right.
To see which keys are used how, see the function loadScancodeMap.
To use:
Set the entity properties for "Static Mode = No", "Always Active? = Yes"
and this script for "AI System => Main". Name this script and/or the init and main functions accordingly!
Features and Phenomena:
The player can "ride" the entity (TransportToIfUsed is called for this).
Unfortunately, the player cannot look up nor down so shooting while riding is an issue.
The player can "exit" the entity using the key defined (L to Land). The landing
can take a while for high values of y. One can go so high that the map is no longer visible.
Water landings are to be avoided due to drowning.
Physics must be off, and therefore the entity will plow through terrain, buildings and other entities.
The player was pulled through the buildings tested with; however, the player is pulled *over* terrain
and is not pulled under ground. The entity goes through the hill; the player goes over it.
An entity can be "flown" into water; the player will drown if riding along.
For simulating flight, a momentum variable is turned on, and the entity will continue moving
in the chosen direction, even when no keys are pressed. The player can disable this effect.
The player can fly the entity outside of the map boundaries. If the player is riding along and
leaves the entity while outside the map boundaries, then the player will drown in invisible water.
The Panel displays the initial speed before use, and it displays the current speed setting when hovering.
In other words, it shows "speed" when stationary. This could use some work...
The toggles donT work correctly. :-( It seems that the scan code is passed in more than once for each key pressed.
This applies to speed up and down too. The speed will increase/decrease more than the increment set.
--[[ my move entity script
The player can move an entity up, down, forward or backward and turn it left and right.
To see which keys are used how, see the function loadScancodeMap.
Set the entity properties for "Static Mode = No", "Always Active? = Yes"
and this script for "AI System => Main". Name this script and/or the init and main functions accordingly!
Features and Phenomena:
The player can "ride" the entity (TransportToIfUsed is called for this).
Unfortunately, the player cannot look up nor down so shooting while riding is an issue.
The player can "exit" the entity using the key defined (L to Land). The landing
can take a while for high values of y. One can go so high that the map is no longer visible.
Water landings are to be avoided due to drowning.
Physics must be off, and therefore the entity will plow through terrain, buildings and other entities.
The player was pulled through the buildings tested with; however, the player is pulled *over* terrain
and is not pulled under ground. The entity goes through the hill; the player goes over it.
An entity can be "flown" into water; the player will drown if riding along.
For simulating flight, a momentum variable is turned on, and the entity will continue moving
in the chosen direction, even when no keys are pressed. The player can disable this effect.
The player can fly the entity outside of the map boundaries. If the player is riding along and
leaves the entity while outside the map boundaries, then the player will drown in invisible water.
The Panel displays the initial speed before use, and it displays the current speed setting when hovering.
In other words, it shows "speed" when stationary. This could use some work...
The toggles donT work correctly. :-( It seems that the scan code is passed in more than once for each key pressed.
This applies to speed up and down too. The speed will increase/decrease more than the increment set.
]]
local activated = {}
local horizontal_vector = {} -- forward or backward
local vertical_vector = {} -- up or down
local yaw_angle = {} -- a.k.a. turn angle
local Speed = {}
local Speed_change = {} -- amount for speeding up or slowing down
local PlayerRides = {} -- boolean for when player is riding the entity
local MomentumToggle = {} -- if momentum is on, the entity will continue moving without player input.
local ScancodeMapToFunction = {} -- function table for each key we use
local PanelToggle = {} -- Toggle display of x,y,z, speed, distance.
function move_e_init(e)
-- physics need to be off:
GravityOff(e)
CollisionOff(e)
activated = 0
horizontal_vector = "stationary"
vertical_vector = "stationary"
yaw_angle = 40 -- a.k.a. turn angle
Speed = 200
Speed_change = 100
PlayerRides = 0
KeyPressed = 0
PanelToggle = 1 -- display of x,y,z, speed, distance.
MomentumToggle = 1 -- turn momentum off (set = 0) for finer control (or use M key).
loadScancodeMap(e) -- map keys to functions
end -- init
function move_e_main(e)
local KeyInput = {}
local KeyPressed = {}
if GetPlayerDistance(e) < 400 and activated == 0 then
-- you might want to change how this script gets activated...
activated = 1
PromptDuration("Press PageUp for lift off or press g to Go, etc....", 5)
end
if activated == 1 then
KeyInput = 0
KeyPressed = 0
KeyInput = GetScancode() -- get user input, if any
if KeyInput > 0 then
KeyPressed = 1
end
if ScancodeMapToFunction[KeyInput] ~= nil and KeyPressed == 1 then
ScancodeMapToFunction[KeyInput](e) -- call this matching function from our table
end
if MomentumToggle == 1 then -- if momentum is on, then continue moving even if no key is pressed
moveThis(e)
end
if PlayerRides == 1 then -- if player is riding this entity
TransportToIfUsed(e) -- then drag the player along...
end
if PanelToggle == 1 then -- display speed, location and distance:
displayPanel(e)
end
end -- end if activated
end -- main
function loadScancodeMap(e)
--[[ Map some keys to their functions.
ScancodeMapToFunction is a table of scancodes and matching functions.
Use this table like: "ScancodeMapToFunction[KeyInput](e)" where KeyInput = GetScancode()
and the appropriate function will execute. Also: "ScancodeMapToFunction[GetScancode()](e)".
Encapsulate the call inside an "if ScancodeMapToFunction[KeyInput] ~= nil" to avoid an error.
(If no function is defined for a key, a runtime error will otherwise be generated.)
Example:
KeyInput = GetScancode()
if ScancodeMapToFunction[KeyInput] ~= nil then
ScancodeMapToFunction[KeyInput](e)
end
]]
ScancodeMapToFunction[23] = function (e) -- i, player rides this entity.
TransportToIfUsed(e)
PlayerRides = 1
end
ScancodeMapToFunction[24] = function (e) -- o, turn off, deactivate this script.
activated = 0
horizontal_vector = "stationary"
vertical_vector = "stationary"
end
ScancodeMapToFunction[25] = function (e) -- p, toggle Panel Display on/off of x,y,z, speed, distance
if PanelToggle == 1 then
PanelToggle = 0
else
PanelToggle = 1
end
end
ScancodeMapToFunction[34] = function (e) -- g, go forward
MoveForward(e, Speed)
horizontal_vector = "forward"
end
ScancodeMapToFunction[35] = function () -- h, hover
horizontal_vector = "stationary"
vertical_vector = "stationary"
end
ScancodeMapToFunction[38] = function () -- l, if player is riding the entity, land the player
PlayerRides = 0 -- player dismounts
end
ScancodeMapToFunction[44] = function (e) -- z, turn left
RotateY(e, -yaw_angle)
end
ScancodeMapToFunction[45] = function (e) -- x, turn right
RotateY(e, yaw_angle)
end
ScancodeMapToFunction[48] = function (e) -- b, go backward
MoveBackward(e, Speed)
horizontal_vector = "backward"
end
ScancodeMapToFunction[50] = function () -- m, toggle momentum
if MomentumToggle == 1 then
MomentumToggle = 0
PromptDuration("Momentum: off", 3)
else
MomentumToggle = 1
PromptDuration("Momentum: on", 3)
end
-- turn off any vectors:
horizontal_vector = "stationary"
vertical_vector = "stationary"
end
ScancodeMapToFunction[74] = function () -- minus, slow down
Speed = Speed - Speed_change
if Speed < 0 then
Speed = 0
end
end
ScancodeMapToFunction[78] = function () -- +, speed up
Speed = Speed + Speed_change
-- might want to set a max-speed limit here...
end
ScancodeMapToFunction[201] = function (e) -- PageUp, move entity up.
if vertical_vector == "down" then
vertical_vector = "level off"
else
MoveUp(e, Speed)
vertical_vector = "up"
end
end
ScancodeMapToFunction[209] = function (e) -- PageDown, move entity down
if vertical_vector == "up" then
vertical_vector = "level off"
else
vertical_vector = "down"
myMoveDown(e, Speed)
end
end
end -- function loadScancodeMap
function moveThis(e)
-- this function should only be called when momentum is on.
if MomentumToggle == 0 then
return
end
if horizontal_vector == "forward" then
MoveForward(e, Speed)
elseif horizontal_vector == "backward" then
MoveBackward(e, Speed)
end
if vertical_vector == "up" then
MoveUp(e, Speed)
elseif vertical_vector == "down" and g_Entity[e]['y'] > 0 then -- donT drop below 0
if g_Entity[e]['y'] > Speed then
myMoveDown(e, Speed)
else -- getting deep
if g_Entity[e]['y'] > 0 then
myMoveDown(e, g_Entity[e]['y'])
if g_Entity[e]['y'] < 0 then -- settle down at y = 0 in case we missed it.
SetPosition(e, g_Entity[e]['x'], 0, g_Entity[e]['z'])
ResetPosition(e, g_Entity[e]['x'], 0, g_Entity[e]['z'])
vertical_vector = "level off"
end
end
end
end
end -- end function moveThis
function displayPanel(e) -- display speed, location and distance:
if PanelToggle ~= 1 then
return -- this function should only be called when the display is desired.
end
local Distance = {}
Distance = math.floor(GetPlayerDistance(e)+0.5)
if Distance < 40 then
Distance = 0 -- setting to 0 flickers less.
end
Panel(3,90,80,98)
Text(5,94,1, "Speed: " .. math.floor(Speed+0.5))
TextCenterOnX(40,94,1, "Location[X][Y][Z]: ["
.. math.floor(g_Entity[e]['x']+0.5) .. "] [" .. math.floor(g_Entity[e]['y']+0.5)
.. "] [" .. math.floor(g_Entity[e]['z']+0.5) .. "]")
Text(65,94,1, "Distance: " .. Distance)
end
function myMoveDown(e,v)
MoveUp(e, -v)
end