Script - Zoom: Difference between revisions
m A bit of cleanup. |
New Config options and FRED interface |
||
| Line 1: | Line 1: | ||
This script enables you to zoom your view so precise aiming is easier. | This script enables you to zoom your view so precise aiming is easier. | ||
It includes a config file that specifies the values the script will use. It also features a FRED SEXP interface so A FREDer can force a zoom-in (or -out) as needed. | |||
For more documentation check out [http://www.hard-light.net/forums/index.php?topic=70411.0 this thread]. | |||
== Table Entry == | == Table Entry == | ||
* To use create an file called '''zoom-sct.tbm''' in your date/tables directory and paste the following code into it: | * To use create an file called '''zoom-sct.tbm''' in your ''date/tables'' directory and paste the following code into it: | ||
<pre> | <pre> | ||
#Conditional Hooks | #Conditional Hooks | ||
$Application: FS2_Open | $Application: FS2_Open | ||
$On | $On Game Init: | ||
[ | [ | ||
-- | ------------------------------------------------------------- | ||
-------- utility functions -------- | |||
------------------------------------------------------------- | |||
function trim(s) | |||
transitionTime = | return (s:gsub("^%s*(.-)%s*$", "%1")) | ||
end | |||
function isAllIdent(check) | |||
check = check:lower() | |||
if check == "**all**" then | |||
return true | |||
else | |||
return false | |||
end | |||
end | |||
function indexOf(t,val) | |||
for k,v in ipairs(t) do | |||
if v == val then | |||
return k | |||
end | |||
end | |||
end | |||
------------------------------------------------------------- | |||
---- defining functions used for parsing the config file ---- | |||
------------------------------------------------------------- | |||
-- gets the next line out of the file | |||
local function getNextLine(file) | |||
if file:isValid() then | |||
local line = file:read("*l") | |||
return line | |||
else | |||
ba.warning("Invalid file handle pased to readLine function") | |||
return nil | |||
end | |||
end | |||
-- looks up the set function which is connected to the specified keyword | |||
local function getSetFunc(keyword) | |||
keyword = keyword:lower() | |||
for i,v in pairs(setTable) do | |||
index = i:lower() | |||
if index == keyword then | |||
return v | |||
end | |||
end | |||
return nil | |||
end | |||
local function addAllowedShipClass(value) | |||
if isAllIdent(value) then | |||
allowedShips = {} | |||
allowedShips[1] = value | |||
return false | |||
end | |||
if allowedShips[1] == nil or not isAllIdent(allowedShips[1]) then | |||
if indexOf(allowedShips,value) ~= nil then | |||
ba.warning("Ship " .. value .. " was specified more than once. Skipping...") | |||
return false | |||
end | |||
local ship = tb.ShipClasses[value] | |||
if ship ~= nil and ship:isValid() then | |||
table.insert(allowedShips, value) | |||
return true | |||
else | |||
ba.warning("Specified ship class '" .. value .. "' does not exist.") | |||
return false | |||
end | |||
end | |||
end | |||
local function addRestrictedShipClass(value) | |||
if isAllIdent(value) then | |||
restrictedShips = {} | |||
restrictedShips[1] = value | |||
return | |||
end | |||
if restrictedShips[1] == nil or not isAllIdent(restrictedShips[1]) then | |||
if indexOf(restrictedShips,value) ~= nil then | |||
ba.warning("Ship " .. value .. " was specified more than once. Skipping...") | |||
return false | |||
end | |||
local ship = tb.ShipClasses[value] | |||
if ship ~= nil and ship:isValid() then | |||
table.insert(restrictedShips, value) | |||
return true | |||
else | |||
ba.warning("Specified ship class '" .. value .. "' does not exist.") | |||
return false | |||
end | |||
end | |||
end | |||
local function addAllowedWeaponClass(value) | |||
if isAllIdent(value) then | |||
allowedWeapons = {} | |||
allowedWeapons[1] = value | |||
return false | |||
end | |||
if allowedWeapons[1] == nil or not isAllIdent(allowedWeapons[1]) then | |||
if indexOf(allowedWeapons,value) ~= nil then | |||
ba.warning("Weapon " .. value .. " was specified more than once. Skipping...") | |||
return false | |||
end | |||
local weapon = tb.WeaponClasses[value] | |||
if weapon ~= nil and weapon:isValid() then | |||
table.insert(allowedWeapons, value) | |||
return true | |||
else | |||
ba.warning("Specified weapon class '" .. value .. "' does not exist.") | |||
return false | |||
end | |||
end | |||
end | |||
local function addRestrictedWeaponClass(value) | |||
if isAllIdent(value) then | |||
restrictedWeapons = {} | |||
restrictedWeapons[1] = value | |||
return false | |||
end | |||
if restrictedWeapons[1] == nil or not isAllIdent(restrictedWeapons[1]) then | |||
if indexOf(restrictedWeapons,value) ~= nil then | |||
ba.warning("Weapon " .. value .. " was specified more than once. Skipping...") | |||
return false | |||
end | |||
local weapon = tb.WeaponClasses[value] | |||
if weapon ~= nil and weapon:isValid() then | |||
table.insert(restrictedWeapons, value) | |||
return true | |||
else | |||
ba.warning("Specified weapon class '" .. value .. "' does not exist.") | |||
return false | |||
end | |||
end | |||
end | |||
local function parseLine(line) | |||
if line == nil or line == "" then -- Check if this line needs to be parsed | |||
return | |||
end | |||
local comm_s, comm_e = line:find("--",1,true) | |||
if comm_s ~= nil then | |||
line = line:sub(1,(comm_s - 1)) | |||
end | |||
if line == "" then -- was the line fully commented away? | |||
return -- Nothing to be done... | |||
end | |||
local key_s, key_e = line:find(":",1,true) | |||
local val_s, val_e = line:find("%a",key_e) | |||
if key_s == nil then -- malformatted line | |||
ba.warning("Malformatted line: " .. line .. "\nSkipping...") | |||
return | |||
end | |||
local keyword = line:sub(1,(key_e - 1)) | |||
if val_s == nil then -- Maybe we_ve got a digit value | |||
val_s, val_e = line:find("%d",key_e) -- search for them | |||
if val_s == nil then | |||
-- We have no value | |||
ba.warning("Keyword '" .. keyword .. "' hasn't specified a value. Skipping...") | |||
return | |||
end | |||
end | |||
keyword = keyword:lower() -- make the keyword lowercase | |||
local val = line:sub(val_s, line:len()) | |||
if val ~= nil then | |||
val = trim(val) | |||
local setFunc = getSetFunc(keyword) | |||
if setFunc == nil then | |||
ba.warning("Unknown keyword: " .. keyword) | |||
return | |||
end | |||
setFunc(val) | |||
else | |||
return | |||
end | |||
end | |||
local function initSetTable() | |||
setTable = {} | |||
setTable["Zoom Factor"]= | |||
function(value) | |||
local val = tonumber(value) | |||
if val == nil then | |||
return | |||
ba.warning("Non numeric value given to 'Zoom Factor'. Skipping...") | |||
end | |||
zoomValue = val | |||
end | |||
setTable["Transition Time"]= | |||
function(value) | |||
local val = tonumber(value) | |||
if val == nil then | |||
ba.warning("Non numeric value given to 'Transition Time'. Skipping...") | |||
return | |||
end | |||
transitionTime = val | |||
end | |||
setTable["Sensitivity"]= | |||
function(value) | |||
local val = tonumber(value) | |||
if val == nil then | |||
ba.warning("Non numeric value given to 'Sensitivity'. Skipping...") | |||
return | |||
end | |||
sensitivity = val | |||
end | |||
setTable["Allowed Ship Class"]=addAllowedShipClass | |||
setTable["Restricted Ship Class"]=addRestrictedShipClass | |||
setTable["Allowed Weapon Class"]=addWeaponClass | |||
setTable["Restricted Weapon Class"]=addRestrictedWeaponClass | |||
setTable["Linked Zoom"]= | |||
function(value) | |||
local yesKey = "yes" | |||
value = value:lower() | |||
if value == yesKey then | |||
linkedZoom = true | |||
else | |||
linkedZoom = false | |||
end | |||
end | |||
setTable["Key"]= | |||
function(key) | |||
if key == nil then | |||
ba.warning("Invalid value given for 'Key'. Skipping...") | |||
return | |||
end | |||
zoomKey=key | |||
end | |||
setTable["Zoom Lock Key"]= | |||
function(key) | |||
if key == nil then | |||
ba.warning("Invalid value given for 'Zoom Lock Key'. Skipping...") | |||
return | |||
end | |||
zoomLockKey=key | |||
end | |||
end | |||
-- | local function readConfig() | ||
if cf.fileExists(configFile) then | |||
local config = cf.openFile(configFile) | |||
if config:isValid() then | |||
initSetTable() | |||
local parse = true | |||
while parse do | |||
local line = getNextLine(config) | |||
if line == nil then | |||
parse = false | |||
break | |||
end | |||
parseLine(line) -- parse the found line | |||
end | |||
else | |||
ba.warning("Handle to config file is invalid. Is the file readable?") | |||
end | |||
else | |||
ba.warning("No config file found. Returning to default") | |||
end | |||
end | |||
------------------------------------------------------------- | |||
------these functions will be use for the FRED interface----- | |||
------------------------------------------------------------- | |||
-- | function zoom_zoomIn() | ||
if defaultZoomSet and cam:isValid() then | |||
cam:setFOV(normalFOV) -- Resetting the FOV in case we have not zoomed out completely | |||
end | |||
fredOverride = true | |||
zoomIn() | |||
end | |||
function zoom_zoomOut() | |||
fredOverride = false | |||
zoomOut() | |||
end | |||
function zoom_alS(ship) | |||
if addAllowedShipClass(ship) then | |||
table.insert(tempAllowedShip, ship) | |||
end | |||
end | |||
function zoom_alW(weapon) | |||
if addAllowedWeaponClass(weapon) then | |||
table.insert(tempAllowedWeapon, weapon) | |||
end | |||
end | |||
-- | function zoom_reS(ship) | ||
if addRestrictedShipClass(ship) then | |||
table.insert(tempRestrictedShip, ship) | |||
end | |||
end | |||
function zoom_reW(weapon) | |||
if addRestrictedWeaponClass(weapon) then | |||
table.insert(tempRestrictedWeapon, weapon) | |||
end | |||
end | |||
------------------------------------------------------------- | |||
------ defining functions used in the script ------ | |||
------------------------------------------------------------- | |||
function removeTemps() | |||
for i,v in ipairs(tempAllowedShip) do | |||
index = indexOf(allowedShips,v) | |||
if index ~= nil then | |||
allowedShips[index]=nil | |||
end | |||
end | |||
for i,v in ipairs(tempRestrictedShip) do | |||
index = indexOf(restrictedShips,v) | |||
if index ~= nil then | |||
restrictedShips[index]=nil | |||
end | |||
end | |||
for i,v in ipairs(tempAllowedWeapon) do | |||
index = indexOf(allowedWeapons,v) | |||
if index ~= nil then | |||
allowedWeapons[index]=nil | |||
end | |||
end | |||
for i,v in ipairs(tempRestrictedWeapon) do | |||
index = indexOf(restrictedWeapons,v) | |||
if index ~= nil then | |||
restrictedWeapons[index]=nil | |||
end | |||
end | |||
end | |||
local function checkTables(allTbl,restrTbl, checkHandle) | |||
if checkHandle == nil then | |||
return false | |||
end | |||
if allTbl ~= nil and restrTbl ~= nil then | |||
if #allTbl > 0 then | |||
if isAllIdent(allTbl[1]) then | |||
if #restrTbl > 0 then | |||
if isAllIdent(restrTbl[1]) then | |||
return true | |||
end | |||
end | |||
for i,v in ipairs(restrTbl) do | |||
if checkHandle.Name == v then | |||
return false | |||
end | |||
end | |||
return true | |||
elseif isAllIdent(restrTbl[1]) then | |||
if #allTbl > 0 then | |||
if isAllIdent(allTbl[1]) then | |||
return true | |||
end | |||
end | |||
for i,v in ipairs(allTbl) do | |||
if checkHandle.Name == v then | |||
return true | |||
end | |||
end | |||
return false | |||
else | |||
local allowed = false | |||
for i,v in ipairs(allTbl) do | |||
if checkHandle.Name == v then | |||
allowed = true | |||
break | |||
end | |||
end | |||
for i,v in ipairs(restrTbl) do | |||
if checkHandle.Name == v then | |||
allowed = false | |||
break | |||
end | |||
end | |||
return allowed | |||
end | |||
end | |||
end | |||
return true | |||
end | |||
function isAllowedShip(shipClass) | |||
return checkTables(allowedShips,restrictedShips,shipClass) | |||
end | |||
function isAllowedWeapon(weaponClass) | |||
return checkTables(allowedWeapons,restrictedWeapons,weaponClass) | |||
end | |||
function getProgressString() | function getProgressString() | ||
| Line 59: | Line 450: | ||
function handleControls() | function handleControls() | ||
if zoomingIn or zoomedIn then | if zoomingIn or zoomedIn then | ||
local ci = ba.getControlInfo() | if currentProgr > 0 then | ||
local tempSensValue = sensitivity * 100 / currentProgr | |||
if tempSensValue <= 1 then | |||
local ci = ba.getControlInfo() | |||
ci.Pitch = ci.Pitch * tempSensValue | |||
ci.Heading = ci.Heading * tempSensValue | |||
ci.Bank = ci.Bank * tempSensValue | |||
end | |||
end | |||
end | |||
end | |||
function isAllowedToZoom() | |||
local allowedShip = isAllowedShip(hv.Player.Class) | |||
local allowedWeapon = true | |||
local primWeaponBank = hv.Player.PrimaryBanks | |||
if not linkedZoom and primWeaponBank.Linked then | |||
allowedWeapon = false | |||
else | |||
for i=0, #primWeaponBank do | |||
local v = primWeaponBank[i] | |||
if v.Armed then | |||
if isAllowedWeapon(tb.WeaponClasses[v.WeaponClass.Name]) then | |||
allowedWeapon = true | |||
break | |||
else | |||
allowedWeapon = false | |||
end | |||
end | |||
end | |||
if allowedWeapon then | |||
local secWeaponBank = hv.Player.SecondaryBanks | |||
for i=0, #secWeaponBank do | |||
local v = secWeaponBank[i] | |||
if v.Armed then | |||
if isAllowedWeapon(tb.WeaponClasses[v.WeaponClass.Name]) then | |||
allowedWeapon = true | |||
break | |||
else | |||
allowedWeapon = false | |||
end | |||
end | |||
end | |||
end | |||
end | |||
return allowedShip and allowedWeapon | |||
end | |||
function zoomIn() | |||
if not cameraSet then | |||
if #gr.Cameras > 0 then | |||
cam = gr.Cameras[1] | |||
end | |||
end | |||
if not zooming then | |||
if hv.Player:isValid() then | |||
if cam:isValid() then | |||
if isAllowedToZoom() then | |||
if currentProgr > 0 and currentProgr < 100 then | |||
stepWidth = width / currentProgr -- Setting the stepWidth in case the zoom may not have been completed | |||
end | |||
zoomEndProgress = 100 | |||
zooming = true | |||
zoomingIn = true | |||
zoomedIn = false | |||
zoomedOut = false | |||
zoomingOut = false | |||
if not defaultZoomSet then | |||
normalFOV = cam.FOV | |||
defaultZoomSet = true | |||
end | |||
zoom = normalFOV * zoomValue | |||
ba.setControlMode(LUA_FULL_CONTROLS) | |||
cam:setFOV(zoom,transitionTime,transitionTime / 2,transitionTime / 4) | |||
end | |||
end | |||
end | |||
end | |||
end | |||
function zoomOut() | |||
if zooming and not zoomOutOverride then | |||
if hv.Player:isValid() then | |||
if cam:isValid() then | |||
stepWidth = width / 100 | |||
zoomingIn = false | |||
zoomingOut = true | |||
zoomedIn = false | |||
zoomedOut = false | |||
if currentProgr > 0 then | |||
zoomEndProgress = currentProgr -- Save the progress we made as we begin to zoom back | |||
end | |||
cam:setFOV(normalFOV,transitionTime,transitionTime / 2,transitionTime / 4) | |||
ba.setControlMode(NORMAL_CONTROLS) | |||
fredOverride = false | |||
end | |||
end | |||
end | end | ||
end | end | ||
| Line 77: | Line 576: | ||
local progressLineOffset_x = realOffset_x + stepWidth * currentProgr | local progressLineOffset_x = realOffset_x + stepWidth * currentProgr | ||
gr.drawLine(progressLineOffset_x, offset_y, progressLineOffset_x, offset_y + heigth) | gr.drawLine(progressLineOffset_x, offset_y, progressLineOffset_x, offset_y + heigth) | ||
if not isAllowedToZoom() and not zoomOutOverride then | |||
if zoomingIn or zoomedIn then | |||
zoomOut() | |||
zoomOutOverride = true | |||
end | |||
end | |||
local thisFrameProg = (frameTime / transitionTime) * zoomEndProgress | local thisFrameProg = (frameTime / transitionTime) * zoomEndProgress | ||
| Line 83: | Line 589: | ||
if currentProgr >= 100 then | if currentProgr >= 100 then | ||
currentProgr = 100 | currentProgr = 100 | ||
zoomingIn = false | |||
zoomedIn = true | |||
end | end | ||
elseif zoomingOut then | elseif zoomingOut then | ||
| Line 90: | Line 596: | ||
if currentProgr <= 0 then | if currentProgr <= 0 then | ||
currentProgr = 0 | currentProgr = 0 | ||
zoomOutOverride = false | |||
zoomedOut = true | zoomedOut = true | ||
zoomingOut = false | zoomingOut = false | ||
| Line 95: | Line 602: | ||
end | end | ||
end | end | ||
end | |||
local function init() | |||
if useConfig then | |||
readConfig() -- read the config file if exists | |||
end | |||
end | |||
local function initVars() | |||
-- Some things to tell the script to do something and some default values | |||
runZoomScript = false | |||
useConfig = true | |||
zoomValue = 0.1 | |||
normalFOV = 0.75 | |||
transitionTime = 2 | |||
zooming = false | |||
defaultZoomSet = false | |||
cameraSet = false | |||
configFile = "data/config/zoom_config.cfg" | |||
zoomOutOverride = false | |||
linkedZoom = true | |||
zoomKey = "d" | |||
zoomLockKey = nil | |||
fredOverride=false | |||
lockedZoom = false | |||
-- Setting the values to be used in the $On Frame: hook | |||
currentProgr = 0 | |||
zoomEndProgress = 100 | |||
zoomingIn = false | |||
zoomedIn = false | |||
zoomingOut = false | |||
zoomedOut = true | |||
-- Constants for drawing the progress | |||
offset_x = 30 | |||
offset_y = 70 | |||
heigth = 8 | |||
width = 80 | |||
stepWidth = width / 100 | |||
-- Settings for the sensitivity | |||
sensitivity = 0.25 | |||
-- The camera which is used for zooming (is initialized in the first $Key Pressed: hook) | |||
cam = nil | |||
-- Tables that hold the allowe/restricted informations | |||
-- Ships | |||
allowedShips = {"**all**"} | |||
tempAllowedShip = {} | |||
restrictedShips = {} | |||
tempRestrictedShip = {} | |||
-- Weapons | |||
allowedWeapons = {"**all**"} | |||
tempAllowedWeapon = {} | |||
restrictedWeapons = {} | |||
tempRestrictedWeapon = {} | |||
end | |||
-- Initialize the global variables | |||
initVars() | |||
-- Initialize the rest | |||
init() | |||
] | |||
$Application: FS2_Open | |||
$On Mission Start: | |||
[ | |||
if not runZoomScript then | |||
runZoomScript = true | |||
end | end | ||
] | ] | ||
| Line 102: | Line 690: | ||
if runZoomScript then | if runZoomScript then | ||
runZoomScript = false | runZoomScript = false | ||
if defaultZoomSet then | if defaultZoomSet and cam:isValid() then | ||
cam:setFOV(normalFOV) -- Resetting the FOV in case we have not zoomed out completely | cam:setFOV(normalFOV) -- Resetting the FOV in case we have not zoomed out completely | ||
end | end | ||
removeTemps() | |||
end | end | ||
] | ] | ||
| Line 119: | Line 708: | ||
] | ] | ||
$ | $On Key Pressed: [[zoom_KeyDn.lua]] | ||
$On Key Released: [[zoom_KeyUp.lua]] | |||
$On Key | |||
[ | |||
#End | |||
</pre> | |||
Then create the file '''zoom_KeyDn.lua''' and '''zoom_KeyUp.lua''' in your ''data/scripts'' directory and paste the following into then: | |||
'''zoom_KeyDn.lua:''' | |||
<pre> | |||
if runZoomScript and not fredOverride then | |||
if hv.Key:lower() == zoomLockKey:lower() then | |||
if lockedZoom then | |||
lockedZoom = false | |||
zoomOut() | |||
else | |||
lockedZoom = true | |||
zoomIn() | |||
end | end | ||
elseif hv.Key:lower() == zoomKey:lower() then | |||
zoomIn() | |||
end | end | ||
end | end | ||
</pre> | |||
'''zoom_KeyUp.lua:''' | |||
<pre> | |||
if runZoomScript then | if runZoomScript and not fredOverride then | ||
if | if not lockedZoom then | ||
if hv.Key:lower() == zoomKey:lower() then | |||
zoomOut() | |||
end | end | ||
end | end | ||
end | end | ||
</pre> | |||
After this create a file named '''zoom_config.cfg''' in your ''data/config'' directory and paste the following text into it: | |||
<pre> | |||
-- Setting standart values | |||
Zoom Factor: 0.1 | |||
Transition Time: 2 | |||
Sensitivity: 0.25 | |||
Linked Zoom: YES | |||
Key: d | |||
Zoom Lock Key: Alt-d | |||
-- Setting ship class options | |||
Allowed Ship Class: **all** | |||
-- Setting weapon class options | |||
Allowed Weapon Class: **all** | |||
</pre> | </pre> | ||
[[Category:Scripting Examples|Zoom]] | [[Category:Scripting Examples|Zoom]] | ||
Revision as of 13:46, 12 September 2010
This script enables you to zoom your view so precise aiming is easier. It includes a config file that specifies the values the script will use. It also features a FRED SEXP interface so A FREDer can force a zoom-in (or -out) as needed. For more documentation check out this thread.
Table Entry
- To use create an file called zoom-sct.tbm in your date/tables directory and paste the following code into it:
#Conditional Hooks
$Application: FS2_Open
$On Game Init:
[
-------------------------------------------------------------
-------- utility functions --------
-------------------------------------------------------------
function trim(s)
return (s:gsub("^%s*(.-)%s*$", "%1"))
end
function isAllIdent(check)
check = check:lower()
if check == "**all**" then
return true
else
return false
end
end
function indexOf(t,val)
for k,v in ipairs(t) do
if v == val then
return k
end
end
end
-------------------------------------------------------------
---- defining functions used for parsing the config file ----
-------------------------------------------------------------
-- gets the next line out of the file
local function getNextLine(file)
if file:isValid() then
local line = file:read("*l")
return line
else
ba.warning("Invalid file handle pased to readLine function")
return nil
end
end
-- looks up the set function which is connected to the specified keyword
local function getSetFunc(keyword)
keyword = keyword:lower()
for i,v in pairs(setTable) do
index = i:lower()
if index == keyword then
return v
end
end
return nil
end
local function addAllowedShipClass(value)
if isAllIdent(value) then
allowedShips = {}
allowedShips[1] = value
return false
end
if allowedShips[1] == nil or not isAllIdent(allowedShips[1]) then
if indexOf(allowedShips,value) ~= nil then
ba.warning("Ship " .. value .. " was specified more than once. Skipping...")
return false
end
local ship = tb.ShipClasses[value]
if ship ~= nil and ship:isValid() then
table.insert(allowedShips, value)
return true
else
ba.warning("Specified ship class '" .. value .. "' does not exist.")
return false
end
end
end
local function addRestrictedShipClass(value)
if isAllIdent(value) then
restrictedShips = {}
restrictedShips[1] = value
return
end
if restrictedShips[1] == nil or not isAllIdent(restrictedShips[1]) then
if indexOf(restrictedShips,value) ~= nil then
ba.warning("Ship " .. value .. " was specified more than once. Skipping...")
return false
end
local ship = tb.ShipClasses[value]
if ship ~= nil and ship:isValid() then
table.insert(restrictedShips, value)
return true
else
ba.warning("Specified ship class '" .. value .. "' does not exist.")
return false
end
end
end
local function addAllowedWeaponClass(value)
if isAllIdent(value) then
allowedWeapons = {}
allowedWeapons[1] = value
return false
end
if allowedWeapons[1] == nil or not isAllIdent(allowedWeapons[1]) then
if indexOf(allowedWeapons,value) ~= nil then
ba.warning("Weapon " .. value .. " was specified more than once. Skipping...")
return false
end
local weapon = tb.WeaponClasses[value]
if weapon ~= nil and weapon:isValid() then
table.insert(allowedWeapons, value)
return true
else
ba.warning("Specified weapon class '" .. value .. "' does not exist.")
return false
end
end
end
local function addRestrictedWeaponClass(value)
if isAllIdent(value) then
restrictedWeapons = {}
restrictedWeapons[1] = value
return false
end
if restrictedWeapons[1] == nil or not isAllIdent(restrictedWeapons[1]) then
if indexOf(restrictedWeapons,value) ~= nil then
ba.warning("Weapon " .. value .. " was specified more than once. Skipping...")
return false
end
local weapon = tb.WeaponClasses[value]
if weapon ~= nil and weapon:isValid() then
table.insert(restrictedWeapons, value)
return true
else
ba.warning("Specified weapon class '" .. value .. "' does not exist.")
return false
end
end
end
local function parseLine(line)
if line == nil or line == "" then -- Check if this line needs to be parsed
return
end
local comm_s, comm_e = line:find("--",1,true)
if comm_s ~= nil then
line = line:sub(1,(comm_s - 1))
end
if line == "" then -- was the line fully commented away?
return -- Nothing to be done...
end
local key_s, key_e = line:find(":",1,true)
local val_s, val_e = line:find("%a",key_e)
if key_s == nil then -- malformatted line
ba.warning("Malformatted line: " .. line .. "\nSkipping...")
return
end
local keyword = line:sub(1,(key_e - 1))
if val_s == nil then -- Maybe we_ve got a digit value
val_s, val_e = line:find("%d",key_e) -- search for them
if val_s == nil then
-- We have no value
ba.warning("Keyword '" .. keyword .. "' hasn't specified a value. Skipping...")
return
end
end
keyword = keyword:lower() -- make the keyword lowercase
local val = line:sub(val_s, line:len())
if val ~= nil then
val = trim(val)
local setFunc = getSetFunc(keyword)
if setFunc == nil then
ba.warning("Unknown keyword: " .. keyword)
return
end
setFunc(val)
else
return
end
end
local function initSetTable()
setTable = {}
setTable["Zoom Factor"]=
function(value)
local val = tonumber(value)
if val == nil then
return
ba.warning("Non numeric value given to 'Zoom Factor'. Skipping...")
end
zoomValue = val
end
setTable["Transition Time"]=
function(value)
local val = tonumber(value)
if val == nil then
ba.warning("Non numeric value given to 'Transition Time'. Skipping...")
return
end
transitionTime = val
end
setTable["Sensitivity"]=
function(value)
local val = tonumber(value)
if val == nil then
ba.warning("Non numeric value given to 'Sensitivity'. Skipping...")
return
end
sensitivity = val
end
setTable["Allowed Ship Class"]=addAllowedShipClass
setTable["Restricted Ship Class"]=addRestrictedShipClass
setTable["Allowed Weapon Class"]=addWeaponClass
setTable["Restricted Weapon Class"]=addRestrictedWeaponClass
setTable["Linked Zoom"]=
function(value)
local yesKey = "yes"
value = value:lower()
if value == yesKey then
linkedZoom = true
else
linkedZoom = false
end
end
setTable["Key"]=
function(key)
if key == nil then
ba.warning("Invalid value given for 'Key'. Skipping...")
return
end
zoomKey=key
end
setTable["Zoom Lock Key"]=
function(key)
if key == nil then
ba.warning("Invalid value given for 'Zoom Lock Key'. Skipping...")
return
end
zoomLockKey=key
end
end
local function readConfig()
if cf.fileExists(configFile) then
local config = cf.openFile(configFile)
if config:isValid() then
initSetTable()
local parse = true
while parse do
local line = getNextLine(config)
if line == nil then
parse = false
break
end
parseLine(line) -- parse the found line
end
else
ba.warning("Handle to config file is invalid. Is the file readable?")
end
else
ba.warning("No config file found. Returning to default")
end
end
-------------------------------------------------------------
------these functions will be use for the FRED interface-----
-------------------------------------------------------------
function zoom_zoomIn()
if defaultZoomSet and cam:isValid() then
cam:setFOV(normalFOV) -- Resetting the FOV in case we have not zoomed out completely
end
fredOverride = true
zoomIn()
end
function zoom_zoomOut()
fredOverride = false
zoomOut()
end
function zoom_alS(ship)
if addAllowedShipClass(ship) then
table.insert(tempAllowedShip, ship)
end
end
function zoom_alW(weapon)
if addAllowedWeaponClass(weapon) then
table.insert(tempAllowedWeapon, weapon)
end
end
function zoom_reS(ship)
if addRestrictedShipClass(ship) then
table.insert(tempRestrictedShip, ship)
end
end
function zoom_reW(weapon)
if addRestrictedWeaponClass(weapon) then
table.insert(tempRestrictedWeapon, weapon)
end
end
-------------------------------------------------------------
------ defining functions used in the script ------
-------------------------------------------------------------
function removeTemps()
for i,v in ipairs(tempAllowedShip) do
index = indexOf(allowedShips,v)
if index ~= nil then
allowedShips[index]=nil
end
end
for i,v in ipairs(tempRestrictedShip) do
index = indexOf(restrictedShips,v)
if index ~= nil then
restrictedShips[index]=nil
end
end
for i,v in ipairs(tempAllowedWeapon) do
index = indexOf(allowedWeapons,v)
if index ~= nil then
allowedWeapons[index]=nil
end
end
for i,v in ipairs(tempRestrictedWeapon) do
index = indexOf(restrictedWeapons,v)
if index ~= nil then
restrictedWeapons[index]=nil
end
end
end
local function checkTables(allTbl,restrTbl, checkHandle)
if checkHandle == nil then
return false
end
if allTbl ~= nil and restrTbl ~= nil then
if #allTbl > 0 then
if isAllIdent(allTbl[1]) then
if #restrTbl > 0 then
if isAllIdent(restrTbl[1]) then
return true
end
end
for i,v in ipairs(restrTbl) do
if checkHandle.Name == v then
return false
end
end
return true
elseif isAllIdent(restrTbl[1]) then
if #allTbl > 0 then
if isAllIdent(allTbl[1]) then
return true
end
end
for i,v in ipairs(allTbl) do
if checkHandle.Name == v then
return true
end
end
return false
else
local allowed = false
for i,v in ipairs(allTbl) do
if checkHandle.Name == v then
allowed = true
break
end
end
for i,v in ipairs(restrTbl) do
if checkHandle.Name == v then
allowed = false
break
end
end
return allowed
end
end
end
return true
end
function isAllowedShip(shipClass)
return checkTables(allowedShips,restrictedShips,shipClass)
end
function isAllowedWeapon(weaponClass)
return checkTables(allowedWeapons,restrictedWeapons,weaponClass)
end
function getProgressString()
local progressString = "Zooming"
if zoomingIn then
progressString = progressString .. " in:"
elseif zoomingOut then
progressString = progressString .. " out:"
elseif zoomedIn then
progressString = "Zoomed in:"
elseif zoomedOut then
progressString = "Zoomed out:"
else
progressString = "Zoomed:"
end
return progressString
end
function handleControls()
if zoomingIn or zoomedIn then
if currentProgr > 0 then
local tempSensValue = sensitivity * 100 / currentProgr
if tempSensValue <= 1 then
local ci = ba.getControlInfo()
ci.Pitch = ci.Pitch * tempSensValue
ci.Heading = ci.Heading * tempSensValue
ci.Bank = ci.Bank * tempSensValue
end
end
end
end
function isAllowedToZoom()
local allowedShip = isAllowedShip(hv.Player.Class)
local allowedWeapon = true
local primWeaponBank = hv.Player.PrimaryBanks
if not linkedZoom and primWeaponBank.Linked then
allowedWeapon = false
else
for i=0, #primWeaponBank do
local v = primWeaponBank[i]
if v.Armed then
if isAllowedWeapon(tb.WeaponClasses[v.WeaponClass.Name]) then
allowedWeapon = true
break
else
allowedWeapon = false
end
end
end
if allowedWeapon then
local secWeaponBank = hv.Player.SecondaryBanks
for i=0, #secWeaponBank do
local v = secWeaponBank[i]
if v.Armed then
if isAllowedWeapon(tb.WeaponClasses[v.WeaponClass.Name]) then
allowedWeapon = true
break
else
allowedWeapon = false
end
end
end
end
end
return allowedShip and allowedWeapon
end
function zoomIn()
if not cameraSet then
if #gr.Cameras > 0 then
cam = gr.Cameras[1]
end
end
if not zooming then
if hv.Player:isValid() then
if cam:isValid() then
if isAllowedToZoom() then
if currentProgr > 0 and currentProgr < 100 then
stepWidth = width / currentProgr -- Setting the stepWidth in case the zoom may not have been completed
end
zoomEndProgress = 100
zooming = true
zoomingIn = true
zoomedIn = false
zoomedOut = false
zoomingOut = false
if not defaultZoomSet then
normalFOV = cam.FOV
defaultZoomSet = true
end
zoom = normalFOV * zoomValue
ba.setControlMode(LUA_FULL_CONTROLS)
cam:setFOV(zoom,transitionTime,transitionTime / 2,transitionTime / 4)
end
end
end
end
end
function zoomOut()
if zooming and not zoomOutOverride then
if hv.Player:isValid() then
if cam:isValid() then
stepWidth = width / 100
zoomingIn = false
zoomingOut = true
zoomedIn = false
zoomedOut = false
if currentProgr > 0 then
zoomEndProgress = currentProgr -- Save the progress we made as we begin to zoom back
end
cam:setFOV(normalFOV,transitionTime,transitionTime / 2,transitionTime / 4)
ba.setControlMode(NORMAL_CONTROLS)
fredOverride = false
end
end
end
end
function drawProgress()
progressString = getProgressString()
local stringWidth = gr.getStringWidth(progressString);
gr.drawString(progressString,30,70)
local realOffset_x = offset_x + stringWidth + 10
gr.drawRectangle(realOffset_x, offset_y,realOffset_x + width, offset_y + heigth, zoomedIn)
local frameTime = ba.getFrametime()
local progressLineOffset_x = realOffset_x + stepWidth * currentProgr
gr.drawLine(progressLineOffset_x, offset_y, progressLineOffset_x, offset_y + heigth)
if not isAllowedToZoom() and not zoomOutOverride then
if zoomingIn or zoomedIn then
zoomOut()
zoomOutOverride = true
end
end
local thisFrameProg = (frameTime / transitionTime) * zoomEndProgress
if zoomingIn then
currentProgr = currentProgr + thisFrameProg
if currentProgr >= 100 then
currentProgr = 100
zoomingIn = false
zoomedIn = true
end
elseif zoomingOut then
currentProgr = currentProgr - thisFrameProg
if currentProgr <= 0 then
currentProgr = 0
zoomOutOverride = false
zoomedOut = true
zoomingOut = false
zooming = false
end
end
end
local function init()
if useConfig then
readConfig() -- read the config file if exists
end
end
local function initVars()
-- Some things to tell the script to do something and some default values
runZoomScript = false
useConfig = true
zoomValue = 0.1
normalFOV = 0.75
transitionTime = 2
zooming = false
defaultZoomSet = false
cameraSet = false
configFile = "data/config/zoom_config.cfg"
zoomOutOverride = false
linkedZoom = true
zoomKey = "d"
zoomLockKey = nil
fredOverride=false
lockedZoom = false
-- Setting the values to be used in the $On Frame: hook
currentProgr = 0
zoomEndProgress = 100
zoomingIn = false
zoomedIn = false
zoomingOut = false
zoomedOut = true
-- Constants for drawing the progress
offset_x = 30
offset_y = 70
heigth = 8
width = 80
stepWidth = width / 100
-- Settings for the sensitivity
sensitivity = 0.25
-- The camera which is used for zooming (is initialized in the first $Key Pressed: hook)
cam = nil
-- Tables that hold the allowe/restricted informations
-- Ships
allowedShips = {"**all**"}
tempAllowedShip = {}
restrictedShips = {}
tempRestrictedShip = {}
-- Weapons
allowedWeapons = {"**all**"}
tempAllowedWeapon = {}
restrictedWeapons = {}
tempRestrictedWeapon = {}
end
-- Initialize the global variables
initVars()
-- Initialize the rest
init()
]
$Application: FS2_Open
$On Mission Start:
[
if not runZoomScript then
runZoomScript = true
end
]
$On Mission End:
[
if runZoomScript then
runZoomScript = false
if defaultZoomSet and cam:isValid() then
cam:setFOV(normalFOV) -- Resetting the FOV in case we have not zoomed out completely
end
removeTemps()
end
]
$On Frame:
[
if runZoomScript then
if zooming then
handleControls()
drawProgress()
end
end
]
$On Key Pressed: [[zoom_KeyDn.lua]]
$On Key Released: [[zoom_KeyUp.lua]]
#End
Then create the file zoom_KeyDn.lua and zoom_KeyUp.lua in your data/scripts directory and paste the following into then:
zoom_KeyDn.lua:
if runZoomScript and not fredOverride then if hv.Key:lower() == zoomLockKey:lower() then if lockedZoom then lockedZoom = false zoomOut() else lockedZoom = true zoomIn() end elseif hv.Key:lower() == zoomKey:lower() then zoomIn() end end
zoom_KeyUp.lua:
if runZoomScript and not fredOverride then if not lockedZoom then if hv.Key:lower() == zoomKey:lower() then zoomOut() end end end
After this create a file named zoom_config.cfg in your data/config directory and paste the following text into it:
-- Setting standart values Zoom Factor: 0.1 Transition Time: 2 Sensitivity: 0.25 Linked Zoom: YES Key: d Zoom Lock Key: Alt-d -- Setting ship class options Allowed Ship Class: **all** -- Setting weapon class options Allowed Weapon Class: **all**