Hard Light Productions Forums

FreeSpace Releases => Scripting Releases => Topic started by: Nuke on January 13, 2007, 02:26:01 pm

Title: hate how the mouse works? have i got the script for you!
Post by: Nuke on January 13, 2007, 02:26:01 pm
ok youl need WMCoolmon's Pre-Commit build (http://www.hard-light.net/forums/index.php/topic,44021.0.html)

and this in a scripting.tbl

Code: [Select]
#Global Hooks

$GameInit:

[

--all this stuff is for multires support, for getting true width and height, and for generating factors to scale coords by

w = gr.getScreenWidth()
h = gr.getScreenHeight()

if w >= 1024 then
wf = w / 1024
else
wf = w / 640
end

if h >= 768 then
hf = h / 768
else
hf = h / 480
end

dead = 15
--mousejoy function, returns a value from -100 to 100 depending on the mouse's position

mousejoy = function(deadzone)
local X = ((io.getX() * wf) - (w/2)) * (200/w)
local Y = ((io.getY() * hf) - (h/2)) * (200/h)

if X < deadzone and X > -deadzone then X=0 end
if Y < deadzone and Y > -deadzone then Y=0 end

return X, Y
end

--generic crosshair function

crosshair = function(x,y)
gr.setColor(0,255,0,200)
gr.drawGradientLine(x+20,y+20,x+10,y+10)
gr.drawGradientLine(x-20,y+20,x-10,y+10)
gr.drawGradientLine(x+20,y-20,x+10,y-10)
gr.drawGradientLine(x-20,y-20,x-10,y-10)
end
]

$HUD:
[

mX, mY = mousejoy(dead)

gr.setColor(0,255,0,255)
gr.drawCircle(5,mX+200,mY+200)
gr.setColor(100,100,255,100)
gr.drawRectangle(100,100,300,300)
gr.setColor(128,128,0,200)
gr.drawRectangle(200-dead,200-dead,200+dead,200+dead)

mX = mX / 100
mY = -mY / 100
mZ = 0

cornholio = mn.Ships["Alpha 1"]

if cornholio:isValid() then
desrot = cornholio.Physics.RotationalVelocityMax
desrot['1'] = desrot['1'] * mY
desrot['2'] = desrot['2'] * mX
desrot['3'] = desrot['3'] * mZ
cornholio.Physics.RotationalVelocity = desrot
end

]
#End




enjoy! :D

*edit*

be sure to leave the mouse off in the game settings
Title: Re: hate how the mouse works? have i got the script for you!
Post by: Taristin on January 13, 2007, 05:11:33 pm
cornholio o.'.o
Title: Re: hate how the mouse works? have i got the script for you!
Post by: Nuke on January 13, 2007, 06:17:27 pm
i see you like my var for alpha 1's ship object :D i still got to do a few things, like come up with some better indicaters, roll control on button 2+mousex, and the big one is to throw in some damp calculation, cause right now it ignores it. anyway when its done hopefully it will serve as a good interim solution till they implement it in c. it makes flying with a mouse a hella lot easyer.
Title: Re: hate how the mouse works? have i got the script for you!
Post by: DaBrain on January 13, 2007, 07:54:24 pm
Wow... thanks man.

I told myself to be patient and wait for taylor's new control stuff, but now I don't have to use the crappy mouse control till then. I'll test it and give you some feedback. ;)
Title: Re: hate how the mouse works? have i got the script for you!
Post by: Nuke on January 13, 2007, 08:13:42 pm
mint you thats the wow it worked i cant believe it quick post it version :D il have an updated version later tonight, just got the deadzone feature in, im gonna make a better looking gauge next.
Title: Re: hate how the mouse works? have i got the script for you!
Post by: Huggybaby on January 13, 2007, 09:59:39 pm
Nuke, this is fantastic!

For those curious, what this does is eliminate the need to keep moving the mouse to keep turning the ship, a problem which has caused a long thread elsewhere. Now the mouse works like a joystick! Move it a few inches and stop, and the ship keeps turning. It's no longer necessary to keep picking up the mouse and repositioning it! Awesome.

Umm, is the gauge even necessary? And if you use button 2 to roll (an idea I like), does that mean you can't fire missiles with it anymore?
Title: Re: hate how the mouse works? have i got the script for you!
Post by: Nuke on January 14, 2007, 02:04:37 am
new version

Code: [Select]
#Global Hooks

$GameInit:

[

--all this stuff is for multires support, for getting true width and height, and for generating factors to scale coords by

w = gr.getScreenWidth()
h = gr.getScreenHeight()

if w >= 1024 then
wf = w / 1024
else
wf = w / 640
end

if h >= 768 then
hf = h / 768
else
hf = h / 480
end

--mousejoy function, returns a value from -1 to 1 depending on the mouse's position

dead = 0.05 --factor of how much range of motion is dead, 1 is max 0 is min
mX=0
mY=0
mZ=0
rolltoggle = false

mousejoy = function(deadzone)
local X = io.getX()
local Y = io.getY()

if w >= 1024 then
X = (X / 511.5) - 1
Y = (Y / 383.5) - 1
else
X = (X / 319.5) - 1
Y = (Y / 239.5) - 1
end

local tweak = 1 / (1 - deadzone)

if X < deadzone and X > -deadzone then
X=0
else
if X > 0 then
X = (X - deadzone) * tweak
elseif X < 0 then
X = (X + deadzone) * tweak
end
end

if Y < deadzone and Y > -deadzone then
Y=0
else
if Y > 0 then
Y = (Y - deadzone) * tweak
elseif Y < 0 then
Y = (Y + deadzone) * tweak
end
end

return X, Y
end

--mouse hud

mousegauge = function(eks,why,zee) --just a bunch of loops to draw the various hashes for the gauges
local cx = w/2
local cy = h/2
local rgx = cx+60
local rgy = cy+60

gr.setColor(150,255,150,200) --big hashes

for i=cx-67.5, cx+67.5, 15 do
gr.drawLine(i,cy - 140,i,cy - 125)
end
for i=cy-67.5, cy+67.5, 15 do
gr.drawLine(cx - 140,i,cx - 125,i)
end

for i=0, 90, 10 do --radial roll gauge
local x = math.sin(i*math.pi/180)
local y = math.cos(i*math.pi/180)
gr.drawLine(rgx+x*65,rgy+y*65,rgx+x*80,rgy+y*80)
end

gr.setColor(50,255,50,150) --small hashes

for i=cx-60, cx+60, 15 do
gr.drawLine(i,cy - 140,i,cy - 132)
end
for i=cy-60, cy+60, 15 do
gr.drawLine(cx - 140,i,cx - 132,i)
end

for i=5, 85, 10 do --radial roll gauge
local x = math.sin(i*math.pi/180)
local y = math.cos(i*math.pi/180)
gr.drawLine(rgx+x*70,rgy+y*70,rgx+x*80,rgy+y*80)
end

gr.setColor(200,200,255,255) --indicators
gr.drawCircle(8,cx+(eks*67.5),cy-135)
gr.drawCircle(8,cx-135,cy+(why*67.5))
zee = (-zee * 45) + 45
gr.drawCircle(8,rgx + (math.sin(zee*math.pi/180) * 75),rgy + (math.cos(zee*math.pi/180) * 75 ))
end
]

$HUD:
[
rolltoggle = io.isButtonDown(MOUSE_MIDDLE_BUTTON)

if rolltoggle then
mZ, mY = mousejoy(dead)
mX = 0
else
mX, mY = mousejoy(dead)
mZ = 0
end

cornholio = mn.Ships["Alpha 1"]

if cornholio:isValid() then
desrot = cornholio.Physics.RotationalVelocityMax
desrot['1'] = desrot['1'] * -mY
desrot['2'] = desrot['2'] * mX
desrot['3'] = desrot['3'] * -mZ
cornholio.Physics.RotationalVelocity = desrot
end

mousegauge(mX,mY,mZ)

]
#End



ive added some more astheticly pleasing gauges. ive also added deadzone support for the mouse, you may tweak the dead variable to your liking. bigger number means more deadzone,  1 is the full range of motion 0.5 is half. i find a low value like 0.05 works well, to give you a small snap to indicate you reached center. bigger deadzones can be harder to deal with, and if you have a steady hand you can just set it to zero to get a fluid range. no matter what setting you use it will always run a full smooth 0-1 gradient from the edge of the dead zone to the edge of the range max. to change the deadzone just change the number on this line to whatever you want:
dead = 0.05   --factor of how much range of motion is dead, 1 is max 0 is min

ive also added a roll mode, enabled by the middle button, if you dont have a middle button you can use your right (or left for that matter) my changing this line:
rolltoggle = io.isButtonDown(MOUSE_MIDDLE_BUTTON)
to
rolltoggle = io.isButtonDown(MOUSE_RIGHT_BUTTON)
i used middle so i could use my right for missiles.

now i still havent plugged in scale factors for different screen resolutions yet. it might be a little large cause i designed it for 1280*1024, but i intent to make it uniform, at any resolution. i also havent plugged damping values yet. not sure how yet, i might need to ask wmc about that. but theyre on my to do list.
Title: Re: hate how the mouse works? have i got the script for you!
Post by: Wanderer on January 14, 2007, 02:22:12 am
if you are using the new scripting system why aren't you using sv.Player - or whatever was the new 'direct' handle to player's ship - instead of mn.Ships["Alpha 1"]
Title: Re: hate how the mouse works? have i got the script for you!
Post by: Nuke on January 14, 2007, 02:36:30 am
im just finally getting the hang of the new system. that wasnt in the scripting.html, but il make note for future reference.

*edit*
just tried it and it doesnt work :D

commented out this line
cornholio = mn.Ships["Alpha 1"]
and changed all other cornholio references to sv.Player.
crashes straight to desktop at mission commit, no error.
Title: Re: hate how the mouse works? have i got the script for you!
Post by: Wanderer on January 14, 2007, 02:52:58 am
well... WMC's pre-commit build fails to run on my cpu (that is when trying without any mods or any kind of scripts)

EDIT: Hmmm... fs2_open_C12172006-P4 caused an Illegal Instruction in module fs2_open_C12172006-P4.exe at 001b:005ef547.

Your problems sounds awfully lot like the older 'plr' handle issue that dropped game immediately when encountered if the actual exe file was of certain type. That is it worked with debugs and IIRC also on some redmenace builds but failed on all 369RCs for example
Title: Re: hate how the mouse works? have i got the script for you!
Post by: Nuke on January 14, 2007, 03:16:51 am
i found another strange bug. if theres a line of code on the line preceding the ]  at the end of a hook, the game will refuse to run. i hope wmc reads this thread.

somone should hilight this, mousies might want :D
Title: Re: hate how the mouse works? have i got the script for you!
Post by: WMCoolmon on January 14, 2007, 06:13:12 am
Yeah, I did, both that and the +override bug should be fixed in this build (http://fs2source.warpcore.org/exes/latest/C01142007.zip), although I couldn't reproduce the ] bug so I have no way for telling if it's been fixed for sure.

I also fixed some code that just looked completely wrong relating to the script-eval SEXP. I haven't tested that, but it's in the build + CVS anyway so it doesn't get forgotten.

EDIT: Oh, and this thread should really be moved to the proper forum (http://www.hard-light.net/forums/index.php/board,145.0.html). :D
Title: Re: hate how the mouse works? have i got the script for you!
Post by: Nuke on January 14, 2007, 12:09:49 pm
hell yea, i was wondering when the scripting forum would come to be.
Title: Re: hate how the mouse works? have i got the script for you!
Post by: Nuke on January 14, 2007, 01:43:46 pm
new version. ive added support for multiple resolutions (all have been tested of course) in the gauge function. only thing left to do is factor in damp:

Code: [Select]
#Global Hooks

$GameInit:

[

--all this stuff is for multires support, for getting true width and height, and for generating factors to scale coords by

w = gr.getScreenWidth()
h = gr.getScreenHeight()

if w >= 1024 then
wf = w / 1024
else
wf = w / 640
end

if h >= 768 then
hf = h / 768
else
hf = h / 480
end

--mousejoy function, returns a value from -1 to 1 depending on the mouse's position

dead = 0.0 --factor of how much range of motion is dead, 1 is max 0 is min
mX=0
mY=0
mZ=0
rolltoggle = false

mousejoy = function(deadzone)
local X = io.getX()
local Y = io.getY()

if w >= 1024 then
X = (X / 511.5) - 1
Y = (Y / 383.5) - 1
else
X = (X / 319.5) - 1
Y = (Y / 239.5) - 1
end

local tweak = 1 / (1 - deadzone)

if X < deadzone and X > -deadzone then
X=0
else
if X > 0 then
X = (X - deadzone) * tweak
elseif X < 0 then
X = (X + deadzone) * tweak
end
end

if Y < deadzone and Y > -deadzone then
Y=0
else
if Y > 0 then
Y = (Y - deadzone) * tweak
elseif Y < 0 then
Y = (Y + deadzone) * tweak
end
end

return X, Y
end

--mouse hud

mousegauge = function(eks,why,zee) --just a bunch of loops to draw the various hashes for the gauges
local cx = w/2
local cy = h/2
local awh = (wf + hf) / 2

if w < 1024 then
awh = awh * 0.625
end

local rgx = cx + (48 * awh)
local rgy = cy + (48 * awh)

gr.setColor(150,255,150,200) --big hashes

for i=cx-(54*awh), cx+(54*awh), 12*awh do
gr.drawLine(i,cy - (108*awh),i,cy - (96*awh))
end
for i=cy-(54*awh), cy+(54*awh), 12*awh do
gr.drawLine(cx - (108*awh),i,cx - (96*awh),i)
end

for i=0, 90, 10 do --radial roll gauge
local x = math.sin(i*math.pi/180)
local y = math.cos(i*math.pi/180)
gr.drawLine(rgx+x*50*awh,rgy+y*50*awh,rgx+x*62*awh,rgy+y*62*awh)
end

gr.setColor(50,255,50,150) --small hashes

for i=cx-(48*awh), cx+(48*awh), 12*awh do
gr.drawLine(i,cy - (108*awh),i,cy - (100*awh))
end
for i=cy-(48*awh), cy+(48*awh), 12*awh do
gr.drawLine(cx - (108*awh),i,cx - (100*awh),i)
end

for i=5, 85, 10 do --radial roll gauge
local x = math.sin(i*math.pi/180)
local y = math.cos(i*math.pi/180)
gr.drawLine(rgx+x*54*awh,rgy+y*54*awh,rgx+x*62*awh,rgy+y*62*awh)
end

gr.setColor(200,200,255,255) --indicators
gr.drawCircle(7.5*awh,cx+(eks*54*awh),cy-(104*awh))
gr.drawCircle(7.5*awh,cx-(104*awh),cy+(why*54*awh))
zee = (-zee * 45) + 45
gr.drawCircle(7.5*awh,rgx + (math.sin(zee*math.pi/180) * 58 * awh),rgy + (math.cos(zee*math.pi/180) * 58 * awh))
end

]

$HUD:
[
rolltoggle = io.isButtonDown(MOUSE_MIDDLE_BUTTON)

if rolltoggle then
mZ, mY = mousejoy(dead)
mX = 0
else
mX, mY = mousejoy(dead)
mZ = 0
end

cornholio = mn.Ships["Alpha 1"]

if cornholio:isValid() then
desrot = cornholio.Physics.RotationalVelocityMax
desrot['1'] = desrot['1'] * -mY
desrot['2'] = desrot['2'] * mX
desrot['3'] = desrot['3'] * -mZ
cornholio.Physics.RotationalVelocity = desrot
end

mousegauge(mX,mY,mZ)

]
#End



Title: Re: hate how the mouse works? have i got the script for you!
Post by: Huggybaby on January 14, 2007, 02:09:11 pm
Can this be included in the new build, maybe as an option in the launcher?
Title: Re: hate how the mouse works? have i got the script for you!
Post by: Nuke on January 14, 2007, 03:02:39 pm
no, id advise agaisnt that for a few reasons. first being it breaks the other control modes. you notice while running the script you can no longer turn with the keypad, and id assume the joystick wouldnt work either. secondly it breaks the way the ships manuver, ignoring rotdamp (for now). it should respect the maximum turn rates for your ship though. while i may be able script in some fixes to theese problems. however sence theyr gonna do the same thing in c later on down the line, its better just to think of this as an interim solution for mousers. i really just did it to play with physics handles and the mouse interface.
Title: Re: hate how the mouse works? have i got the script for you!
Post by: Huggybaby on January 14, 2007, 07:10:36 pm
OK, thanks. I'll think of it as a great proof of concept then.
Title: Re: hate how the mouse works? have i got the script for you!
Post by: Nuke on January 14, 2007, 11:27:07 pm
im currently coding in some new features. the first being a config menu to allow you to configure things like deadzone and which button to use for roll. i think il mess with the file stuff and try to get it to save a config, which it will check for on load.
Title: Re: hate how the mouse works? have i got the script for you!
Post by: Wanderer on January 15, 2007, 12:21:30 am
I got WMC's new builds to run... it seems that there is some issues with it currently...

Code: [Select]
#Global Hooks

$Global:
[

gr.setColor(255,255,0)
gr.drawString(#sv.Globals,100,80)
for h=1,#sv.Globals do
    gr.drawString(sv.Globals[h],100,20*h+80)
end

]
#End

This shows the number of sv.Glovals to be -1.. continously. So no wonder the sv.Player didnt function as AFAIK it doesnt even exists at the moment.
Title: Re: hate how the mouse works? have i got the script for you!
Post by: WMCoolmon on January 15, 2007, 03:25:52 am
Well I've made a change in CVS that should allow the Globals array to work properly. Pain in the ass to implement though.

ScriptingVariables is also now moving to HookVariables(hv) for another possible future feature, and clarity of purpose.

Code: [Select]
#Global Hooks

$Global: [
gr.setColor(255,255,0)
gr.drawString(#hv.Globals,100,80)
for h=1,#hv.Globals do
    gr.drawString(hv.Globals[h],100,20*h+80)
end
]
#End
Title: Re: hate how the mouse works? have i got the script for you!
Post by: Nuke on January 15, 2007, 03:38:50 am
remember that ] bug, i dont think it had anything to do with the brackets. i think it has more to do with unused tabs floating around. if you got a bunch of tabs on a line and nothing else, it wont even run. this is bad cause i have a habbit of tabbing out to the current level of scope regaurdless if i use the line or not. of course i cant duplicate it. sometimes il get stummped adn cant figure out whats wrong, clean up the formatting (while not changing the actual code), and it will end up working. im still trying to figure out exactly whats causing it. maybe a combination of things.

*edit*

it seems i fixed a few problems and ive implemented a working menu. im not sure if i fixed the damping, but i think i may have. i still have 3 more features to finish up before i call this script done. one of which it the ability to save preferances. right now the menu comes on at start up. i want to make it so that if it sees a prefs file it will not load the menu but rather load the prefs instead. the player will set the options the first time they come up, the file will be saved and autoloaded on game start next time they play, and the menu will remain hidden. the player is presented with a countdown on game start, during this period he may hit left and right buttons to pull up the menu, should changes need to be made.i got too many loose ends open to put up a new version now. i should finish it by tomorrow.
Title: Re: hate how the mouse works? have i got the script for you!
Post by: neoterran on January 15, 2007, 09:13:43 pm
Umm, can someone explain to me how to get this to work ? I can't run P4 builds and I get a bunch of LUA errors with the january ones...

edit.. i have problems with the middle mouse button, causes LUA crashes on my system, and the script doesn't seem to work for me when my mouse is off.
Title: Re: hate how the mouse works? have i got the script for you!
Post by: WMCoolmon on January 16, 2007, 02:17:56 am
http://www.hard-light.net/forums/index.php/topic,44659.0.html

Note the "non-p4 builds" :D
Title: Re: hate how the mouse works? have i got the script for you!
Post by: Nuke on January 16, 2007, 06:39:25 am
this script is becomming bloat, but hey, its a good demo. it also uses physics, io, string manipulation and control interfaces. good for a learning tool at least. new feature is the menu which is presented on script load. the vertical axis selects the option while horizontal will change options. some things like save and exit require a click, click on the slider to set its default position. your settings will be saved and you wont have to look at my ugly menu when next time you load your game. you are however presented with an option to open the menu, by holding left and right buttons simultaniously.

UseMouse needs to be on for the script to do anything usefull. its pretty much for multi, so people with joysticks dont get screwed.  DrawHud enables and disables the hud gauges. DeadZone is obvous, clicking sets default. CoordP/B allows you to both pitch and yaw on the x axis, center is no coordination right is full positive coord and right is full negative, set center to use buttons for roll. FallOff is the ramping rate for button based roll right means faster. 1337Mode swaps yaw and roll, sorta like in elite. RollCtrl lets you pick which button to use for roll toggle, mid and right are toggles, set both for mid left roll and right right roll, just be sure you have coord set to mid or they probly wont work. InvPitch is obvious, flipps your y. save and exit saves your settings in a file called nukemouse.cfg. you can edit it in edit, notepad or wordpad corrupt it. the loader is pretty good at not crashing on a bad file. if the file is corrupt it will just ovver ride it with defaults.

*edit* fixed to work with newest builds

Code: [Select]
#Global Hooks ;;nukemouse version 4
$GameInit:
[

--all this stuff is for multires support, for getting true width and height, centers, and for generating factors to scale coords by
--it just needs to run once so heres the place to do it, 8 vars in all

w = gr.getScreenWidth()
h = gr.getScreenHeight()
cx = w/2
cy = h/2

if w >= 1024 then
wf = w / 1024
hf = h / 768
awh = (wf + hf) / 2
hires = true
else
wf = w / 640
hf = h / 480
awh = ((wf + hf) / 2) * 0.625
hires = false
end

--couple functions for loading and saving config files

menusave = function(vars)
local config = cf.openFile("nukemouse.cfg","w+")
local b1 = 0
local b2 = 0
local b6 = 0
local b7 = 0
local b8 = 0
if vars[1] then b1 = 1 end --convert non-neumeric values to neumerics
if vars[2] then b2 = 1 end
if vars[6] then b6 = 1 end
if vars[7] == "Right" then
b7 = 0
elseif vars[7] == "Mid" then
b7 = 1
elseif vars[7] == "Both" then
b7 = 2
end
if vars[8] then b8 = 1 end
config:write(b1,"\r\n",b2,"\r\n",vars[3],"\r\n",vars[4],"\r\n",vars[5],"\r\n",b6,"\r\n",b7,"\r\n",b8)
config:close()
end

menuload = function(test)
local config = cf.openFile("nukemouse.cfg","r")
local V = {}
local error = false

if config:isValid() ~= true then
config:close()
error = true
return error
else
for i=1, 8 do
V[i] = config:read("*n")
end

config:close()
end

if test then
for i=1, 8 do --test mode to check if file is valid
if V[i] == nil then error = true end
end
return error
else
if V[1] == 1 then V[1] = true else V[1] = false end --convert imput back to the correct type
if V[2] == 1 then V[2] = true else V[2] = false end
if V[6] == 1 then V[6] = true else V[6] = false end

if V[7] == 0 then
V[7] = "Right"
elseif V[7] == 1 then
V[7] = "Mid"
else
V[7] = "Both"
end

if V[8] == 1 then V[8] = true else V[8] = false end

return V
end
end

--uservars, soon il set it up to check for a file to load

if menuload(true) == false then
showmenu = false
local settings = menuload(false)
usemouse = settings[1]
usehud = settings[2]
dead = settings[3]
coord = settings[4]
falloff = settings[5]
leetmode = settings[6]
rollmode = settings[7]
latvert = settings[8]

else
dead = 0.0 --factor of how much range of motion is dead, 1 is max 0 is min, this one is safe to change
coord = 0.0 --coordinates roll with yaw, factor from -1 to 1, negative nums anti-coordinate
falloff = 0.01 --how long it takes a setting such as roll to wear off after control mode was switched, also rampup for 2 button roll
leetmode = false --elite mode (swap roll and yaw)
usehud = true --draw the hud, if mouse is off will still display rotation forces being applied or latvert if its being used
usemouse = true --turn on mouse mode
latvert = false --use mouse for lateral and vertical thrusters, for saitek users with analog mouse sticks
showmenu = true --toggles menu
rollmode = "Right" --uses left button for roll
end

--some internal vars

mX=0
mY=0
mZ=0
Mx=0
My=0
countdown = 500

mousejoy = function(deadzone) --mousejoy function, returns a value from -1 to 1 depending on the mouse's position
local X = io.getMouseX()
local Y = io.getMouseY()

if hires then
X = (X / 511.5) - 1
Y = (Y / 383.5) - 1
else
X = (X / 319.5) - 1
Y = (Y / 239.5) - 1
end

Mx = X --theese are for the menu, -1 to 1 without deadzone applied
My = Y

local tweak = 1 / (1 - deadzone)

if X < deadzone and X > -deadzone then
X=0
else
if X > 0 then
X = (X - deadzone) * tweak
elseif X < 0 then
X = (X + deadzone) * tweak
end
end

if Y < deadzone and Y > -deadzone then
Y=0
else
if Y > 0 then
Y = (Y - deadzone) * tweak
elseif Y < 0 then
Y = (Y + deadzone) * tweak
end
end

return X, Y
end

--mouse hud

mousegauge = function(eks,why,zee) --just a bunch of loops to draw the various hashes for the gauges
local rgx = cx + (48 * awh)
local rgy = cy + (48 * awh)

gr.setColor(150,255,150,200) --big hashes

for i=cx-(54*awh), cx+(54*awh), 12*awh do
gr.drawLine(i,cy - (108*awh),i,cy - (96*awh))
end
for i=cy-(54*awh), cy+(54*awh), 12*awh do
gr.drawLine(cx - (108*awh),i,cx - (96*awh),i)
end

for i=0, 90, 10 do --radial roll gauge
local x = math.sin(i*math.pi/180)
local y = math.cos(i*math.pi/180)
gr.drawLine(rgx+x*50*awh,rgy+y*50*awh,rgx+x*62*awh,rgy+y*62*awh)
end

gr.setColor(50,255,50,150) --small hashes

for i=cx-(48*awh), cx+(48*awh), 12*awh do
gr.drawLine(i,cy - (108*awh),i,cy - (100*awh))
end
for i=cy-(48*awh), cy+(48*awh), 12*awh do
gr.drawLine(cx - (108*awh),i,cx - (100*awh),i)
end

for i=5, 85, 10 do --radial roll gauge
local x = math.sin(i*math.pi/180)
local y = math.cos(i*math.pi/180)
gr.drawLine(rgx+x*54*awh,rgy+y*54*awh,rgx+x*62*awh,rgy+y*62*awh)
end

gr.setColor(200,200,255,255) --indicators
gr.drawCircle(7.5*awh,cx+(eks*54*awh),cy-(104*awh))
gr.drawCircle(7.5*awh,cx-(104*awh),cy+(why*54*awh))
zee = (-zee * 45) + 45
gr.drawCircle(7.5*awh,rgx + (math.sin(zee*math.pi/180) * 58 * awh),rgy + (math.cos(zee*math.pi/180) * 58 * awh))
end

mousemenu = function(sel,val,button)
local mtext = {"UseMouse","DrawHud","DeadZone","CoordP/B","FallOff","1337Mode","RollCtrl","InvPitch","Save and Exit"}
local ops = 9
local snum = math.ceil((sel+1.25)*4)

for i=1,ops do --draw menu and set settings
if i == snum then
gr.setColor(192,255,255,255)
else
gr.setColor(64,192,128,200)
end

gr.drawString(mtext[i], cx-(85*awh), cy+(((i-1)-(ops/2))*(15*awh)))

if i == 1 or i == 2 or i == 6 or i == 8 then --draw radio butons
gr.drawCircle(8*awh, cx+(81*awh), (cy+(4*awh))+(((i-1)-(ops/2))*(15*awh)))

if i == 1 then
if usemouse then
gr.setColor(0,192,255,255)
else
gr.setColor(0,0,0,255)
end

if snum == 1 and val >= 0 then
usemouse = true
elseif snum == 1 and val < 0 then
usemouse = false
end

gr.drawCircle(6.5*awh, cx+(81*awh), (cy+(4*awh))+(((i-1)-(ops/2))*(15*awh)))
elseif i == 2 then
if usehud then
gr.setColor(0,192,255,255)
else
gr.setColor(0,0,0,255)
end

if snum == 2 and val >= 0 then
usehud = true
elseif snum == 2 and val < 0 then
usehud = false
end

gr.drawCircle(6.5*awh, cx+(81*awh), (cy+(4*awh))+(((i-1)-(ops/2))*(15*awh)))
elseif i == 6 then
if leetmode then
gr.setColor(0,192,255,255)
else
gr.setColor(0,0,0,255)
end

if snum == 6 and val >= 0 then
leetmode = true
elseif snum == 6 and val < 0 then
leetmode = false
end

gr.drawCircle(6.5*awh, cx+(81*awh), (cy+(4*awh))+(((i-1)-(ops/2))*(15*awh)))
elseif i == 8 then
if latvert then
gr.setColor(0,192,255,255)
else
gr.setColor(0,0,0,255)
end

if snum == 8 and val >= 0 then
latvert = true
elseif snum == 8 and val < 0 then
latvert = false
end

gr.drawCircle(6.5*awh, cx+(81*awh), (cy+(4*awh))+(((i-1)-(ops/2))*(15*awh)))
end
elseif i == 3 or i == 4 or i == 5 then --draw sliders
for j = 0, 10 do
gr.drawLine( (cx-(j*5*awh))+(85*awh), cy+(((i-1)-(ops/2))*(15*awh)),(cx-(j*5*awh))+(85*awh), (cy+(6*awh))+(((i-1)-(ops/2))*(15*awh)) )
end

gr.setColor(192,255,255,255)

if i == 3 then
gr.drawCircle(7*awh, cx+(85*awh)-(50*awh)+(dead*100*awh), (cy+(4*awh))+(((i-1)-(ops/2))*(15*awh)))
if snum == 3 then
dead = (val+1)*0.25
if button then dead = 0 end
end
elseif i == 4 then
gr.drawCircle(7*awh, cx+(85*awh)-(25*awh)+(coord*25*awh), (cy+(4*awh))+(((i-1)-(ops/2))*(15*awh)))
if snum == 4 then
coord = val
if button then coord = 0 end
end
elseif i == 5 then
gr.drawCircle(7*awh, cx+(85*awh)-(50*awh)+(falloff*100*awh), (cy+(4*awh))+(((i-1)-(ops/2))*(15*awh)))
if snum == 5 then
falloff = (val+1)*0.25
if button then falloff = 0.2 end
end
end
elseif i == 7 then --draw string settings
if val <= -0.666 and snum == 7 then
rollmode = "Right"
elseif val <= 0.666 and snum == 7 then
rollmode = "Mid"
elseif val <=1 and snum == 7 then
rollmode = "Both"
end
gr.drawString(rollmode, (cx+(85 * awh)) - gr.getStringWidth(rollmode), cy+(((i-1)-(ops/2))*(15*awh)))
elseif i == 9 then --exit command
if snum == 9 and button then
savevars = {usemouse,usehud,dead,coord,falloff,leetmode,rollmode,latvert}
menusave(savevars)
showmenu = false
end
end
end
end

]
$Simulation:
[

if showmenu then
mousejoy(dead)
elseif usemouse then
if (rollmode == "Mid" and io.isMouseButtonDown(MOUSE_MIDDLE_BUTTON)) or (rollmode == "Right" and io.isMouseButtonDown(MOUSE_RIGHT_BUTTON)) then
mZ, mY = mousejoy(dead)

if mX < -falloff then
mX = mX + falloff
elseif mX > falloff then
mX = mX - falloff
else
mX = 0
end
elseif rollmode == "Mid" or rollmode == "Right" then
mX, mY = mousejoy(dead)

if mZ < -falloff then
mZ = mZ + falloff
elseif mZ > falloff then
mZ = mZ - falloff
else
mZ = 0
end
else
mX, mY = mousejoy(dead)

if io.isMouseButtonDown(MOUSE_MIDDLE_BUTTON) and io.isMouseButtonDown(MOUSE_RIGHT_BUTTON) then
mZ = 0
elseif io.isMouseButtonDown(MOUSE_RIGHT_BUTTON) then
if mZ < 1 - falloff then
mZ = mZ + falloff
else
mZ = 1
end
elseif io.isMouseButtonDown(MOUSE_MIDDLE_BUTTON) then
if mZ > -1 + falloff then
mZ = mZ - falloff
else
mZ = -1
end
else
if mZ < -falloff then
mZ = mZ + falloff
elseif mZ > falloff then
mZ = mZ - falloff
else
mZ = 0
end
end
end

cornholio = mn.Ships["Alpha 1"]

if coord ~= 0 then mZ = mX * coord end

if leetmode then
local temp = mX
mX = mZ
mZ = temp
end

if latvert then mY = -mY end

if cornholio:isValid() then
desrot = cornholio.Physics.RotationalVelocityMax
desrot['1'] = desrot['1'] * mY
desrot['2'] = desrot['2'] * mX
desrot['3'] = desrot['3'] * -mZ
cornholio.Physics.RotationalVelocity = desrot + cornholio.Physics.RotationalVelocityDamping * ba.getFrametime()
end
end

]
$HUD:
[

if usehud then
mousegauge(mX,mY,mZ)
end

if showmenu then
mousemenu(My,Mx,io.isMouseButtonDown(MOUSE_LEFT_BUTTON))
end

if countdown > 1 and showmenu == false then
countdown = countdown - 1
if io.isMouseButtonDown(MOUSE_RIGHT_BUTTON) and io.isMouseButtonDown(MOUSE_LEFT_BUTTON) then
showmenu = true
end
gr.setColor(192,255,255,255)

gr.drawString("press left and right mouse buttons to configure mouse", cx-(gr.getStringWidth("press left and right mouse buttons to configure mouse")/2), cy - (150*awh) )
end

]
#End
Title: Re: hate how the mouse works? have i got the script for you!
Post by: neoterran on January 16, 2007, 12:48:53 pm
Gosh I'd really like to get this to work, but i'm having all kinds of LUA issues. I have the mouse turned off, as requested in the top post. I have the january build. (b) and I have scripting.tbl in my data folder with this script in.

The best i can get is the stuff to show up on the hud, but i can't make any movements.

The worst is a bunch of LUA errors.
Title: Re: hate how the mouse works? have i got the script for you!
Post by: Nuke on January 16, 2007, 03:40:37 pm
i hope youre not running it on 3.6.9, you gotta use one of wmcs scripting builds.
Title: Re: hate how the mouse works? have i got the script for you!
Post by: neoterran on January 16, 2007, 04:10:32 pm
no, i'm using the january non-p4 wmc build.
Title: Re: hate how the mouse works? have i got the script for you!
Post by: Nuke on January 16, 2007, 04:26:16 pm
looks like wmc changed the mouse functions, yet again. il post a fix in abit.

*edit*
fixed, try it again
Title: Re: hate how the mouse works? have i got the script for you!
Post by: neoterran on January 16, 2007, 05:22:11 pm
cool ! works.

Wow, this is going to take some getting used to... thanks for the hard work tho !
Title: Re: hate how the mouse works? have i got the script for you!
Post by: WMCoolmon on January 16, 2007, 07:26:00 pm
looks like wmc changed the mouse functions, yet again. il post a fix in abit.

*edit*
fixed, try it again

Sorry. :) I realized that "GetX()" might be a bit vague if/when joystick support is added.
Title: Re: hate how the mouse works? have i got the script for you!
Post by: Nuke on January 17, 2007, 11:13:31 pm
not a big deal. anyway to hilight this? it might be hella usefull for anyone who flys with a mouse :D
Title: Re: hate how the mouse works? have i got the script for you!
Post by: WMCoolmon on January 18, 2007, 12:06:38 am
Ehm...possibly, I don't know if I have privs. I don't want to mess with it tonight though.
Title: Re: hate how the mouse works? have i got the script for you!
Post by: natty_dread78 on January 18, 2007, 12:06:39 pm
 Hi guys,
I'm a newb here, but 'd really like to use that new mouse behavior. So I have a couple of questions here:

* If I've understood correctly, I need the builds from wmc. Do I use C01142007 ? C01142007b ? c12172006 ? What exe inside the archive
  do I have to use ?
* I put the code that Nuke posted in scripting.tbl  Where do I put this file ?
* Nuke, u said that you changed your code for scripting.tbl when wmc changed the mouse functions. Where is the updated code ?
 
That's all for now! Thxs in advance guys!
N_D
Title: Re: hate how the mouse works? have i got the script for you!
Post by: Taristin on January 18, 2007, 03:57:18 pm
All tbl files go in the Tables folder.
The updated code should be what you see on the page.

And using the most recent dated build is almost always advisable (In this case the c01 14 2007 build.) Try either that one or the b variant and see which works better for you, I guess.
Title: Re: hate how the mouse works? have i got the script for you!
Post by: Nuke on January 18, 2007, 04:28:05 pm
just use the last build posted in  this thread (http://www.hard-light.net/forums/index.php/topic,44659.0.html) and use the last script i posted in  this post  (http://www.hard-light.net/forums/index.php/topic,44634.msg912322.html#msg912322).
Title: Re: hate how the mouse works? have i got the script for you!
Post by: natty_dread78 on January 19, 2007, 06:55:35 am
That's what I did. But it doesn't work. So I changed the function in your code: getMouseX => GetX , same for Y, and isMouseButtonDown => isButtonDown, then it works.  It even works like a charm! A few years ago, I was playing FS2 with the Trackpoint, the pointing device on IBM thinkpads, I was an ace with it! Then my laptop died. Then I played with the mouse, because I suck with a joystick, I don't know why. But the mouse also kinda sucks because you have to keep moving. So finally I played with both the keyboard and the mouse (using the keyboard while moving the mouse back), kinda sucks too.
 
================== >>   So I recommend Nuke's code for anyone that plays with a mouse or that sucks with a joystick! It rocks, thxs Nuke!


 The only drawback is that the roll function doesn't work (even with the middle mouse button), and it also doesn't work with the keyboard anymore (it works actually, but 100x times slower...). But it's really not a big issue, I hardly used the roll anyways...
 I found that a deadzone value of 0 works best for me, it's most responsive. What do u recommend for the CoordP/B value ?
   (thxs for your answer Taristin)
Title: Re: hate how the mouse works? have i got the script for you!
Post by: Nuke on January 19, 2007, 07:11:29 am
fixed some bugs. now all options should work together without conflict. you can now use coord with button toggles or both mode. changed the falloff math so that it compensates for framerate. changed the way 1337Mode and InvY are handled. fixed a bug that would coord your controls if you had elite mode on with a coord setting. also be sure to use one of theese builds (http://www.hard-light.net/forums/index.php/topic,44659.msg911505.html#msg911505), not the pre commit build as stated in my first post, in order to avoid trouble with the mouse functions.

Code: [Select]
#Global Hooks ;;nukemouse version 5
$GameInit:
[

--all this stuff is for multires support, for getting true width and height, centers, and for generating factors to scale coords by
--it just needs to run once so heres the place to do it, 8 vars in all

w = gr.getScreenWidth()
h = gr.getScreenHeight()
cx = w/2
cy = h/2

if w >= 1024 then
wf = w / 1024
hf = h / 768
awh = (wf + hf) / 2
hires = true
else
wf = w / 640
hf = h / 480
awh = ((wf + hf) / 2) * 0.625
hires = false
end

--couple functions for loading and saving config files

menusave = function(vars)
local config = cf.openFile("nukemouse.cfg","w+")
local b1 = 0
local b2 = 0
local b6 = 0
local b7 = 0
local b8 = 0
if vars[1] then b1 = 1 end --convert non-neumeric values to neumerics
if vars[2] then b2 = 1 end
if vars[6] then b6 = 1 end
if vars[7] == "Right" then
b7 = 0
elseif vars[7] == "Mid" then
b7 = 1
elseif vars[7] == "Both" then
b7 = 2
end
if vars[8] then b8 = 1 end
config:write(b1,"\r\n",b2,"\r\n",vars[3],"\r\n",vars[4],"\r\n",vars[5],"\r\n",b6,"\r\n",b7,"\r\n",b8)
config:close()
end

menuload = function(test)
local config = cf.openFile("nukemouse.cfg","r")
local V = {}
local error = false

if config:isValid() ~= true then
config:close()
error = true
return error
else
for i=1, 8 do
V[i] = config:read("*n")
end

config:close()
end

if test then
for i=1, 8 do --test mode to check if file is valid
if V[i] == nil then error = true end
end
return error
else
if V[1] == 1 then V[1] = true else V[1] = false end --convert imput back to the correct type
if V[2] == 1 then V[2] = true else V[2] = false end
if V[6] == 1 then V[6] = true else V[6] = false end

if V[7] == 0 then
V[7] = "Right"
elseif V[7] == 1 then
V[7] = "Mid"
else
V[7] = "Both"
end

if V[8] == 1 then V[8] = true else V[8] = false end

return V
end
end

--uservars, soon il set it up to check for a file to load

if menuload(true) == false then
showmenu = false
local settings = menuload(false)
usemouse = settings[1]
usehud = settings[2]
dead = settings[3]
coord = settings[4]
falloff = settings[5]
leetmode = settings[6]
rollmode = settings[7]
latvert = settings[8]

else
dead = 0.0 --factor of how much range of motion is dead, 1 is max 0 is min, this one is safe to change
coord = 0.0 --coordinates roll with yaw, factor from -1 to 1, negative nums anti-coordinate
falloff = 0.2 --how long it takes a setting such as roll to wear off after control mode was switched, also rampup for 2 button roll
leetmode = false --elite mode (swap roll and yaw)
usehud = true --draw the hud, if mouse is off will still display rotation forces being applied or latvert if its being used
usemouse = true --turn on mouse mode
latvert = false --flip z
showmenu = true --toggles menu
rollmode = "Right" --uses left button for roll
end

--some internal vars

mX=0
mY=0
mZ=0
Mx=0
My=0
countdown = 500

mousejoy = function(deadzone) --mousejoy function, returns a value from -1 to 1 depending on the mouse's position
local X = io.getMouseX()
local Y = io.getMouseY()

if hires then
X = (X / 511.5) - 1
Y = (Y / 383.5) - 1
else
X = (X / 319.5) - 1
Y = (Y / 239.5) - 1
end

Mx = X --theese are for the menu, -1 to 1 without deadzone applied
My = Y

local tweak = 1 / (1 - deadzone)

if X < deadzone and X > -deadzone then
X=0
else
if X > 0 then
X = (X - deadzone) * tweak
elseif X < 0 then
X = (X + deadzone) * tweak
end
end

if Y < deadzone and Y > -deadzone then
Y=0
else
if Y > 0 then
Y = (Y - deadzone) * tweak
elseif Y < 0 then
Y = (Y + deadzone) * tweak
end
end

return X, Y
end

--mouse hud

mousegauge = function(eks,why,zee) --just a bunch of loops to draw the various hashes for the gauges
local rgx = cx + (48 * awh)
local rgy = cy + (48 * awh)

gr.setColor(150,255,150,200) --big hashes

for i=cx-(54*awh), cx+(54*awh), 12*awh do
gr.drawLine(i,cy - (108*awh),i,cy - (96*awh))
end
for i=cy-(54*awh), cy+(54*awh), 12*awh do
gr.drawLine(cx - (108*awh),i,cx - (96*awh),i)
end

for i=0, 90, 10 do --radial roll gauge
local x = math.sin(i*math.pi/180)
local y = math.cos(i*math.pi/180)
gr.drawLine(rgx+x*50*awh,rgy+y*50*awh,rgx+x*62*awh,rgy+y*62*awh)
end

gr.setColor(50,255,50,150) --small hashes

for i=cx-(48*awh), cx+(48*awh), 12*awh do
gr.drawLine(i,cy - (108*awh),i,cy - (100*awh))
end
for i=cy-(48*awh), cy+(48*awh), 12*awh do
gr.drawLine(cx - (108*awh),i,cx - (100*awh),i)
end

for i=5, 85, 10 do --radial roll gauge
local x = math.sin(i*math.pi/180)
local y = math.cos(i*math.pi/180)
gr.drawLine(rgx+x*54*awh,rgy+y*54*awh,rgx+x*62*awh,rgy+y*62*awh)
end

gr.setColor(200,200,255,255) --indicators
gr.drawCircle(7.5*awh,cx+(eks*54*awh),cy-(104*awh))
gr.drawCircle(7.5*awh,cx-(104*awh),cy+(why*54*awh))
zee = (-zee * 45) + 45
gr.drawCircle(7.5*awh,rgx + (math.sin(zee*math.pi/180) * 58 * awh),rgy + (math.cos(zee*math.pi/180) * 58 * awh))
end

mousemenu = function(sel,val,button)
local mtext = {"UseMouse","DrawHud","DeadZone","CoordP/B","FallOff","1337Mode","RollCtrl","InvPitch","Save and Exit"}
local ops = 9
local snum = math.ceil((sel+1.25)*4)

for i=1,ops do --draw menu and set settings
if i == snum then
gr.setColor(192,255,255,255)
else
gr.setColor(64,192,128,200)
end

gr.drawString(mtext[i], cx-(85*awh), cy+(((i-1)-(ops/2))*(15*awh)))

if i == 1 or i == 2 or i == 6 or i == 8 then --draw radio butons
gr.drawCircle(8*awh, cx+(81*awh), (cy+(4*awh))+(((i-1)-(ops/2))*(15*awh)))

if i == 1 then
if usemouse then
gr.setColor(0,192,255,255)
else
gr.setColor(0,0,0,255)
end

if snum == 1 and val >= 0 then
usemouse = true
elseif snum == 1 and val < 0 then
usemouse = false
end

gr.drawCircle(6.5*awh, cx+(81*awh), (cy+(4*awh))+(((i-1)-(ops/2))*(15*awh)))
elseif i == 2 then
if usehud then
gr.setColor(0,192,255,255)
else
gr.setColor(0,0,0,255)
end

if snum == 2 and val >= 0 then
usehud = true
elseif snum == 2 and val < 0 then
usehud = false
end

gr.drawCircle(6.5*awh, cx+(81*awh), (cy+(4*awh))+(((i-1)-(ops/2))*(15*awh)))
elseif i == 6 then
if leetmode then
gr.setColor(0,192,255,255)
else
gr.setColor(0,0,0,255)
end

if snum == 6 and val >= 0 then
leetmode = true
elseif snum == 6 and val < 0 then
leetmode = false
end

gr.drawCircle(6.5*awh, cx+(81*awh), (cy+(4*awh))+(((i-1)-(ops/2))*(15*awh)))
elseif i == 8 then
if latvert then
gr.setColor(0,192,255,255)
else
gr.setColor(0,0,0,255)
end

if snum == 8 and val >= 0 then
latvert = true
elseif snum == 8 and val < 0 then
latvert = false
end

gr.drawCircle(6.5*awh, cx+(81*awh), (cy+(4*awh))+(((i-1)-(ops/2))*(15*awh)))
end
elseif i == 3 or i == 4 or i == 5 then --draw sliders
for j = 0, 10 do
gr.drawLine( (cx-(j*5*awh))+(85*awh), cy+(((i-1)-(ops/2))*(15*awh)),(cx-(j*5*awh))+(85*awh), (cy+(6*awh))+(((i-1)-(ops/2))*(15*awh)) )
end

gr.setColor(192,255,255,255)

if i == 3 then
gr.drawCircle(7*awh, cx+(85*awh)-(50*awh)+(dead*100*awh), (cy+(4*awh))+(((i-1)-(ops/2))*(15*awh)))
if snum == 3 then
dead = (val+1)*0.25
if button then dead = 0 end
end
elseif i == 4 then
gr.drawCircle(7*awh, cx+(85*awh)-(25*awh)+(coord*25*awh), (cy+(4*awh))+(((i-1)-(ops/2))*(15*awh)))
if snum == 4 then
coord = val
if button then coord = 0 end
end
elseif i == 5 then
gr.drawCircle(7*awh, cx+(85*awh)-(50*awh)+(falloff*100*awh), (cy+(4*awh))+(((i-1)-(ops/2))*(15*awh)))
if snum == 5 then
falloff = (val+1)*0.25
if button then falloff = 0.2 end
end
end
elseif i == 7 then --draw string settings
if val <= -0.666 and snum == 7 then
rollmode = "Right"
elseif val <= 0.666 and snum == 7 then
rollmode = "Mid"
elseif val <=1 and snum == 7 then
rollmode = "Both"
end
gr.drawString(rollmode, (cx+(85 * awh)) - gr.getStringWidth(rollmode), cy+(((i-1)-(ops/2))*(15*awh)))
elseif i == 9 then --exit command
if snum == 9 and button then
savevars = {usemouse,usehud,dead,coord,falloff,leetmode,rollmode,latvert}
menusave(savevars)
showmenu = false
end
end
end
end

]
$Simulation:
[

if showmenu then
mousejoy(dead)
elseif usemouse then
fo = (falloff + 0.01) * ba.getFrametime() * 45

if (rollmode == "Mid" and io.isMouseButtonDown(MOUSE_MIDDLE_BUTTON)) or (rollmode == "Right" and io.isMouseButtonDown(MOUSE_RIGHT_BUTTON)) then
mZ, mY = mousejoy(dead)
emmzee = mZ * coord

if mX < -fo + emmzee then
mX = mX + fo
elseif mX > fo + emmzee then
mX = mX - fo
else
mX = emmzee
end
elseif rollmode == "Mid" or rollmode == "Right" then
mX, mY = mousejoy(dead)
emmzee = mX * coord

if mZ < -fo + emmzee then
mZ = mZ + fo
elseif mZ > fo + emmzee then
mZ = mZ - fo
else
mZ = emmzee
end
else
mX, mY = mousejoy(dead)
emmzee = mX * coord

if io.isMouseButtonDown(MOUSE_MIDDLE_BUTTON) and io.isMouseButtonDown(MOUSE_RIGHT_BUTTON) then
mZ = 0
elseif io.isMouseButtonDown(MOUSE_RIGHT_BUTTON) then
if mZ < 1 - fo then
mZ = mZ + fo
else
mZ = 1
end
elseif io.isMouseButtonDown(MOUSE_MIDDLE_BUTTON) then
if mZ > -1 + fo then
mZ = mZ - fo
else
mZ = -1
end
else
if mZ < -fo + emmzee then
mZ = mZ + fo
elseif mZ > fo + emmzee then
mZ = mZ - fo
else
mZ = emmzee
end
end
end

cornholio = mn.Ships["Alpha 1"]

if cornholio:isValid() then
desrot = cornholio.Physics.RotationalVelocityMax

if latvert then
desrot['1'] = desrot['1'] * -mY
else
desrot['1'] = desrot['1'] * mY
end

if leetmode then
desrot['2'] = desrot['2'] * mZ
desrot['3'] = desrot['3'] * -mX
else
desrot['2'] = desrot['2'] * mX
desrot['3'] = desrot['3'] * -mZ
end

cornholio.Physics.RotationalVelocity = desrot + cornholio.Physics.RotationalVelocityDamping * ba.getFrametime()
end

end

]
$HUD:
[

if usehud then
if leetmode then
mousegauge(mZ,mY,mX)
else
mousegauge(mX,mY,mZ)
end
end

if showmenu then
mousemenu(My,Mx,io.isMouseButtonDown(MOUSE_LEFT_BUTTON))
end

if countdown > 1 and showmenu == false then
countdown = countdown - 1
if io.isMouseButtonDown(MOUSE_RIGHT_BUTTON) and io.isMouseButtonDown(MOUSE_LEFT_BUTTON) then
showmenu = true
end
gr.setColor(192,255,255,255)

gr.drawString("press left and right mouse buttons to configure mouse", cx-(gr.getStringWidth("press left and right mouse buttons to configure mouse")/2), cy - (150*awh) )
end

]
#End
Title: Re: hate how the mouse works? have i got the script for you!
Post by: natty_dread78 on January 23, 2007, 09:32:17 am
 Guys,
I'm having trouble using Nuke's code with WMC scripting build and the 3.6.8 beta media VPs. The grame crashes at some point, usually when a large ship comes in. I have errors such as: "Malloc failed" or some error related to an entry in a table that couldn't be found, I don't remember. I installed the media VPs correctly with the 710 patches.
  An important point is that everything works fine with the 3.6.7 media VPs. So I guess that WMC builds are incompatible with 3.6.8 ?
N_D
Title: Re: hate how the mouse works? have i got the script for you!
Post by: Nuke on January 23, 2007, 01:14:02 pm
this is experimental and needs the most recent scripting build to work. it doesnt use media vps at all cause all graphics are procedural.
Title: Re: hate how the mouse works? have i got the script for you!
Post by: jr2 on February 19, 2007, 08:00:44 am
...based on that, I'd say that the scripting build has a beef with the VPs?
Title: Re: hate how the mouse works? have i got the script for you!
Post by: natty_dread78 on February 21, 2007, 09:12:21 am
 Yeah I guess. But maybe it's more an incompatibility problem with the new VPs (3.6.8 zeta), since it works fine with the old ones (3.6.7). I've completed half the campaign and still not a single crash. For the scripting build to be compatible with the new VPs or to be included in a new release is just a matter of time I guess...
Title: Re: hate how the mouse works? have i got the script for you!
Post by: jr2 on February 21, 2007, 09:38:44 am
I think 3.7.0 will have scripting support, correct?
Title: Re: hate how the mouse works? have i got the script for you!
Post by: Wanderer on February 21, 2007, 11:27:32 am
All current cvs HEAD branch builds are AFAIK builds that more or less will in the future lead to 3.7 release. So... yes, 3.7 should have support for the current HEAD branch scripts
Title: Re: hate how the mouse works? have i got the script for you!
Post by: neoterran on February 21, 2007, 05:02:06 pm
yeah, but unfortunately, 3.7 is probably at least 6 months away
Title: Re: hate how the mouse works? have i got the script for you!
Post by: WMCoolmon on February 22, 2007, 01:16:53 am
As I understand it, 3.6.10 will be based on the 3.6.9 branch and so will not have most of the scripting stuff in it. However, I've been pretty good about committing all my changes to CVS, so the next HEAD build should have most of the stuff that I've mentioned that I've done.

Which to use is entirely up to you. As far as I'm concerned, the period where the "new" scripting system is not in official use has the benefit of giving me a bit more leeway in case I want to change some infrequently-used parts of the system to work more closely with convention or just plain better. This is the first time I've basically written a programming language*, so I'm constantly finding new things that I want to tweak or change.

*(Technically, I only defined all the functions, object types, libraries, and implemented the appropriate code for parsing the Lua sequences and integrating that with the aforementioned elements. It still feels like starting from a clean slate, though.)
Title: Re: hate how the mouse works? have i got the script for you!
Post by: jr2 on February 22, 2007, 08:23:34 am
...This is the first time I've basically written a programming language*, so I'm constantly finding new things that I want to tweak or change.

*(Technically, I only defined all the functions, object types, libraries, and implemented the appropriate code for parsing the Lua sequences and integrating that with the aforementioned elements. It still feels like starting from a clean slate, though.)
So, why not just go for broke and create whatever's left to make it a programming language?  :D 
Of course, I have absolutely no clue what I'm talking about...  XD
Title: Re: hate how the mouse works? have i got the script for you!
Post by: WMCoolmon on February 23, 2007, 01:24:41 am
It'd be a lot of work, and it wouldn't provide any real benefit unless I came up with some clever thing to make it more appealing than the scripting languages already out there. I don't want to throw away my time - which I can't ever get back - to reinvent the wheel, while at the same time devaluing the Lua guys' work by not using it, and providing a competing scripting system that would do the same thing.
Title: Re: hate how the mouse works? have i got the script for you!
Post by: jr2 on February 23, 2007, 01:52:29 am
Aiee!  I was only half-joking...  :D
So, I take it there'd be quite a lot of work left to make that happen... it just sounded to me (stupid me!) that you had almost made a whole programming language, but not quite.
Title: Re: hate how the mouse works? have i got the script for you!
Post by: takashi on March 26, 2007, 07:48:31 pm
NUUUUUUUUKE!!!!!!!!!! i took odd nukemouse and when i play regular freespace, gameplay images and manuvering are both gone! explain!

(angry, but you corrupted my game!)
Title: Re: hate how the mouse works? have i got the script for you!
Post by: jr2 on March 26, 2007, 08:10:48 pm
Eh, say what??
To undo, can't you just use the old (3.6.9) engine?
Title: Re: hate how the mouse works? have i got the script for you!
Post by: Nuke on March 26, 2007, 10:31:18 pm
iirc nukemouse only works in head builds. using head builds requires at least minor understanding of the engine. if it messes the game up just remove the scripting table and everything should work. i tested this thouroughly and i never encountered this problem which means youre either tampering with the script or running multiple scripts at once.
Title: Re: hate how the mouse works? have i got the script for you!
Post by: takashi on March 29, 2007, 01:27:03 pm
seems its a pilot-file corruption. odd, since there was no warning.

ps: more than just a corruption. i had to re-install to get the joystick to work again.
Title: Re: hate how the mouse works? have i got the script for you!
Post by: Nuke on March 29, 2007, 08:31:10 pm
youre like a toddler with matches. youd think after burning yourself a dozen times you would learn.
Title: Re: hate how the mouse works? have i got the script for you!
Post by: WMCoolmon on March 29, 2007, 10:59:11 pm
NUUUUUUUUKE!!!!!!!!!! i took odd nukemouse and when i play regular freespace, gameplay images and manuvering are both gone! explain!

(angry, but you corrupted my game!)

"Please" would have been nice. Also, yelling and screaming and blaming them for breaking freespace does not make people want to help you.

I should probably note that all the code samples in this forum should be considered "try-at-your-own-risk" just like any executable would be. I've tried to make scripting as safe as possible but there's always the chance that someone will find a way to corrupt things or will accidentally corrupt things, especially in the case of writing files.

I really don't want to have to write up a "Read this first!" thread for this forum, they're so cliche'd...
Title: Re: hate how the mouse works? have i got the script for you!
Post by: Nuke on March 31, 2007, 12:26:13 am
i dont even know what build hes using, and really i dont think he does either. now this script will only work in head builds, he obviously missed the part about turning OFF the mouse in the game options, that explains the lack of control he reported. the missing images, which im assuming he means the hud, is probibly cause he stuck an +override in there. il test the script with the latest head build when i find it just to make sure theres not a problem elsewhere.

*edit*
tested it and it still works fine in the latest head build
Title: Re: hate how the mouse works? have i got the script for you!
Post by: Eorohi on April 02, 2007, 06:04:49 am
Hi, I'm a complete n00blet when it comes to scripting.  Anyhow I'm wondering would it be possible to get this to work on Btrl demo?  When you try to use the script this is the error that pops up.

LUA ERROR: [string "GameInit"]:22: attempt to call field `getX' (a nil value)

LUA Debug:
------------------------------------------------------------------
Name:      getX
Name of:   field
Function type:   C
Defined on:   -1
Upvalues:   0

Source:      =[C]
Short source:   [C]
Current line:   -1
------------------------------------------------------------------

LUA Stack:
------------------------------------------------------------------

------------------------------------------------------------------

lol knowing me i probably put it in the wrong place  :lol:
Title: Re: hate how the mouse works? have i got the script for you!
Post by: Wanderer on April 02, 2007, 06:11:26 am
BTRL demo uses builds based on 369 builds so it wont function without some editing (or rather reverting to older functions).
Title: Re: hate how the mouse works? have i got the script for you!
Post by: Eorohi on April 02, 2007, 06:24:26 am
ahh ok, thank you for the fast reply.  Just anoying when the mouse doesn't work like it really should for a flight/space sim  :mad:
Title: Re: hate how the mouse works? have i got the script for you!
Post by: Nuke on April 05, 2007, 05:10:40 am
you could try running btrl with a head build (http://www.hard-light.net/forums/index.php/topic,44659.msg943378.html#msg943378). no gaurantees though. stick it in the btrl folder and point to it with the launcher. then you could possibly use my script. but that wouldnt be offitially supported by the btrl team. i doubt theyd let you play multi with such tweaks :D

i dont think reverting the funcs would work either. i used alot of stuff exclusive to head, cfile for example, used to save config files and such.
Title: Re: hate how the mouse works? have i got the script for you!
Post by: jr2 on April 05, 2007, 07:49:51 am
If you do as he suggests above, make sure to create a new pilot file for use with the new build, in case the builds are incompatible.
Title: Re: hate how the mouse works? have i got the script for you!
Post by: Nuke on April 05, 2007, 08:11:53 pm
thats a good pointer, i think they did change something somewhere.
Title: Re: hate how the mouse works? have i got the script for you!
Post by: WMCoolmon on April 05, 2007, 10:34:40 pm
Yeah, taylor said something about the pilot files being broken/getting corrupted in HEAD. I'm rather unhappy with that, considering I've been going to the effort of testing my changes before they get in, and now somebody has decided to **** all over the only branch I'm allowed to commit to.
Title: Re: hate how the mouse works? have i got the script for you!
Post by: Unknown Target on April 05, 2007, 11:21:18 pm
Doesn't this break the BtRL flight model? That's what I've always heard.
Title: Re: hate how the mouse works? have i got the script for you!
Post by: Nuke on April 05, 2007, 11:24:06 pm
only thing it might break is perhaps moi. i accounted for rotdamp, but i dont think anyones checked my math.

ive never had a pilot file get corrupted and i pretty much run head builds exclusively.
Title: Re: hate how the mouse works? have i got the script for you!
Post by: Wanderer on April 06, 2007, 12:49:11 am
It was the earlier (or earliest) versions that broke it.. Though the use of the scripting.tbl & multi is not a good idea.

And pilot files get broken, but AFAIK this appears only in certain situations, like red alert missions etc.
Title: Re: hate how the mouse works? have i got the script for you!
Post by: Fury on March 01, 2009, 01:45:00 am
I was told this Nuke's script allows freelancerish mouse control. :) I tried it and got the oddball menu in the HUD, I got settings saved but once that's done the game crashes. :p Tried again and crashed again.

I mentioned this yesterday on IRC and it would seem like Wanderer reworked parts of the script, I have yet to see his work though. I'd love to get this script working because I hate the standard mouse control and joystick doesn't sit comfortably on my table.

I wonder if this script can still cause pilot file corruption? What of multiplayer? I assume I would get complains of unvalidated tables. :nervous:
Title: Re: hate how the mouse works? have i got the script for you!
Post by: Wanderer on March 01, 2009, 05:53:20 am
Well... I have recently added option to the scripting that should (might, possibly could... - cant give 100% on this yet as there might be some unforeseen probs in the code/script) enable player controls to be read directly into lua which is a lot less hackish way of using mouse control than the one used in this script (granted at the time this script was written it was the only way). Though that option is still only in wanderer branch.

This script also utilizes control over (read/write) other files and i haven't recently checked how those work.

Script such as the one above should not cause pilot file corruption in any case. But in multiplayer it might (probably will) complain of unvalidated tables. Then again only result of that complain is that the stats wont be saved so its not really that major loss.

I'm gonna take closer look at the lua/c code as soon as i get enough time to get around to it. Before that i can write menuless script that should enable different mouse control if you need it.
Title: Re: hate how the mouse works? have i got the script for you!
Post by: Fury on March 01, 2009, 06:37:57 am
I'd be happy with any script that would allow me actually play FS2 with some comfort. :D Thank you very much. :)
Title: Re: hate how the mouse works? have i got the script for you!
Post by: JGZinv on March 01, 2009, 08:14:35 am
Well let me ask this then since it is at least related to the topic....

I've got a trackball (ball on top) mouse which is set fairly high in terms of cursor speed.
Any time FS2 is loaded, the program slows the travel of the mouse considerably. Enough
so that it at least gives my thumb a work out by comparison.

The mouse sensitivity is all the way up, general options and launcher settings just don't seem
to take into account that the mouse is naturally slowed while within the game window.

Would this script fix this issue, or is something else entirely needed?
Title: Re: hate how the mouse works? have i got the script for you!
Post by: Nuke on March 04, 2009, 11:21:38 pm
i think they chaged cfile since last i updated this thing. the script stores its settings in a file called nukemouse.cfg. once the file is stored the menu wont come up again unless you hold down both mouse buttons, or delete the file. for some reason editing the file manually doesnt seem to work. probibly because i used linux style escape sequences. probibly why youre getting the crash.

when i wrote this scripting was fairly new and we didnt have much to work with. for example my menu sucks bad. now its probibly possible to add a button to the options screen with conditional hooks. also most of the physis bugs could probibly be avoided now. frankly the script was kinda poorly written from the getgo. i stopped working on it, aside from minor bug fixes  (all the major bugs go unfixed :D )  for a few reasons, first nobody seemed to be using it, second, i was under the assumption that input was about to get a major rewrite, third, any remaining problems with physics, i didnt have the skill to solve at the time, also the code was a mess and ttempts to rewrite it usually ended in me working on something entirely different.

yep its most definately a cfile thing. when it tries to save the file it gives an assert

Assert: dir_type != CF_TYPE_ANY
File: cfile.cpp
Line: 1019

problem is cfile isnt documented at all so i havet a clue how its supposed to work, just that what i coded before worked. since then ive learned a thing or two about file parsing. i bet i could make the cfg look like a freespace table if i wanted to. looks like it didnt like the path i gave it (which i probibly didnt).

i could probibly hack together something that would use default values, because this file handling is haphazard at best.
Title: Re: hate how the mouse works? have i got the script for you!
Post by: Wanderer on March 05, 2009, 12:00:25 am
Well... i have been working on something which still requires some fine adjustments and couple of additional controls to be added...

Here is something that can be tested... archive (http://koti.mbnet.fi/vekkup/FS2/script_mouse.7z).

From my local codebase with a set of additional scripting functions which are not yet in either trunk nor in any of the branches in SVN. Archive consists of a mod and a build. It is strongly recommended that you run the script in question only as a mod within its own directory (when using multi mod - mod.ini - feature then preferably the first one in the 'stack').

The cfg file has several options...
Sensitivity: defines the length of the response area measured from the end of the deadzone (oddly enough in screen pixels... minimum is 100)
Sensitivity Curve: defines the exponent applied to the response (setting it to 1 essentially disables this setting)
Control Mode: planned support for other modes.. as for now only '1' will work
Deadzone: defines the size of the deadzone from the centerpoint (again in pixels)
Mouse Invert: defines if the mouse invert is use or not (1 = inverted mouse in use, 0 = not in use)

Keeping center mouse button pressed for > 0.2 s resets the controls. Script can be used when normal FS2 mouse is in use but it might be is better to turn the default mouse off. When playing in windowed mode it is very easy to get the mouse cursor of the edge. This generally causes both the game to pause as well as when continued if any of the weapons were firing.. then they will keep firing. This firing can be stopped by shooting once with the weapons in question.

EDIT... still uploading... DONE
Title: Re: hate how the mouse works? have i got the script for you!
Post by: Nuke on March 05, 2009, 01:12:05 am
looks like you beat me to it. i was about to post a dirty hack. i commented out the file load code and just hard coded the variables. but your system seems to work better. my script is a total mess, i really didnt want to waste an evening debugging it :D

looks like you added some stuff to lua that ive been asking for for a long time.
Title: Re: hate how the mouse works? have i got the script for you!
Post by: theGleep on March 05, 2009, 03:28:45 pm
Help for a total Open Source FS noob?  Please?

I play on my laptop in front of the TV...so mouse (a'la freelancer) is the best option for me.

I've read through this thread...and there's a lot I don't understand.

Could someone post an "Idiot's guide to Freelancer-style mouse control"?

Please?

TIA!

Earl
Title: Re: hate how the mouse works? have i got the script for you!
Post by: Wanderer on March 06, 2009, 02:04:42 am
Well... This is still something that is tested and it relies on a special build

Download the archive linked couple posts before this one. Extract the build (the exe file) to your main freespace directory. Extract the mod directory also to the same place. Start the launcher, make sure to select the newly extracted build, select MOD tab and choose the new directory as a mod. Start the game. Go to options screen and set mouse off. Return to mainhall and test it out (or start playing).

If the default settings weren't good enough those can be changed in the .cfg file (in the new mods data directory, open with text editor like notepad).
Title: Re: hate how the mouse works? have i got the script for you!
Post by: theGleep on March 06, 2009, 07:21:07 am
Really?  It's that easy?

Thanks!
Title: Re: hate how the mouse works? have i got the script for you!
Post by: Wanderer on March 06, 2009, 02:47:51 pm
Had to revise the script a bit... Same link but now there is additional (small) bitmap in the set. And the cfg file has couple more options. Also the sct.tbm file now has some comments to make it easier to understand what it is doing. Basically uses the same build as the current wanderer branch so OS X and Linux users can compile their own builds and try it out if they want to (though i have no idea how well the script will run on those). Now it should not matter if you have the normal fs mouse flight control on or off.

Boundary Limit:   Limit from the edge of the screen/window (towards the center) on how far the mouse cursor is allowed to go before it is reset.
Indicator Color:   Four numbers for example comma separated, red, green, blue, alpha

Title: Re: hate how the mouse works? have i got the script for you!
Post by: theGleep on March 07, 2009, 10:01:51 pm
FAN-Tastic!  How long before it's rolled into the main build, do you think?
Title: Re: hate how the mouse works? have i got the script for you!
Post by: Wanderer on June 08, 2009, 04:57:04 am
The script is now in wiki http://www.hard-light.net/wiki/index.php/Script_-_Scripted_Mouse and works with trunk builds

Just remember to get the icon from the archive from this thread (but do not mix the actual scripts).
Title: Re: hate how the mouse works? have i got the script for you!
Post by: Galemp on June 21, 2009, 03:24:24 pm
I've been trying this and it's a little frustrating--I'd really love to be able to actually steer my targeting reticle, as I seem to be overshooting my targets by too much. This appears to be because the sensitivity has a minimum of 100. Any chance of eliminating that limit?
Title: Re: hate how the mouse works? have i got the script for you!
Post by: Wanderer on June 22, 2009, 02:53:38 am
Steering the targeting reticle is something that is not readily doable. Not impossible however...

As for the minimum...
Code: [Select]
         if mousesensitivity < 100 then
            mousesensitivity = 100
That section in the script handles it... You can make it smaller but it also makes the response area for the mouse smaller..
Title: Re: hate how the mouse works? have i got the script for you!
Post by: Zacam on June 23, 2009, 07:30:36 pm
Galemp: Try the Velocity Indicator script.

This should give you something to steer with a little better.

That, and it's just kinda cool.
Title: Re: hate how the mouse works? have i got the script for you!
Post by: Nuke on June 24, 2009, 07:33:39 am
i once paired a stripped down version of my old mouse script with an early version of my turret aiming script to create a freelancer style control of turrets while steering with the mouse. it worked quite well. but scripting has changed so much that it might be better to rewrite it from scratch.
Title: Re: hate how the mouse works? have i got the script for you!
Post by: JGZinv on June 24, 2009, 12:35:59 pm
I didn't really get an answer to my question on the previous page, does this
reduce or eliminate the forced mouse slowness FS2 creates while in use?

Title: Re: hate how the mouse works? have i got the script for you!
Post by: Nuke on June 26, 2009, 01:48:52 pm
it makes the game feel kinda like privateer 2 with a mouse
Title: Re: hate how the mouse works? have i got the script for you!
Post by: eigenlambda on March 24, 2010, 01:45:08 am
The script is broken in the next version of fs2_open, it seems that getMouseControlStatus() and setMouseControlStatus(bool) have been replaced by a variable, MouseControlStatus

So you need to update the script here:
   if io.MouseControlStatus == true then
      mouse_reset_on_end = true
      io.MouseControlStatus = false
   end

and here:
if mouse_reset_on_end == true then
   io.MouseControlStatus = true
end


...and now, you need to keep two versions of the script around, for people on 3.6.10 and for people on 3.6.14.  wonderfull.
Title: Re: hate how the mouse works? have i got the script for you!
Post by: The E on March 24, 2010, 06:54:58 am
No, actually. Since .12 is in every way superior to .10, only the .12 version has to be kept.
Title: Re: hate how the mouse works? have i got the script for you!
Post by: jr2 on March 24, 2010, 09:48:56 am
No, actually. Since .12 is in every way superior to .10, only the .10 version has to be kept.
/me puts his thinking cap on

.12 has it built in?
Title: Re: hate how the mouse works? have i got the script for you!
Post by: The E on March 24, 2010, 09:52:33 am
Err. No. I just made a mistake. You saw nothing.
Title: Re: hate how the mouse works? have i got the script for you!
Post by: jr2 on March 24, 2010, 09:55:50 am
:(  Darn.
Title: Re: hate how the mouse works? have i got the script for you!
Post by: eigenlambda on March 28, 2010, 02:50:12 am
The problem with the current mouse script is that you need to mouse back to the middle when you're done turning, which is really hard to do accurately.  So, I took the control model from AirQuake, wherein you point the mouse, which points the camera in whatever direction you choose and then your airplane tries to keep up with the camera.

The only problem is that I can't figure out how to get the HUD to draw after I change the camera :(

But I find this a lot easier to use :D.  Set Control Mode: 2 in your mouse_script.cfg .

Code: [Select]
#Conditional Hooks

$Application: FS2_Open
$On Mission Start:

[

-- couple of functions to make things go easier
function find_after_keyword(line_to_parse, keyword)

   -- make sure both strings are in lower case
   line_to_parse = line_to_parse:lower()
   keyword = keyword:lower()

   -- find any instances of the keyword
   key_s, key_e = line_to_parse:find(keyword)

   -- if we cant find a thing
   if key_s == nil then
      return nil
   end

   result = line_to_parse:match("%d+", e_key)
   return tonumber(result)
end

function find_4_numbers_after_keyword(line_to_parse, keyword)

   -- make sure both strings are in lower case
   line_to_parse = line_to_parse:lower()
   keyword = keyword:lower()

   -- find any instances of the keyword
   key_s, key_e = line_to_parse:find(keyword)

   -- if we cant find a thing
   if key_s == nil then
      return nil
   end

   -- make sure r is an array
   r = {}
   i = 1

   -- stuff the array
   for p in line_to_parse:gmatch("%d+") do
      r[i] = p
      r[i] = tonumber(r[i])
      if r[i] > 255 then
         r[i] = 255
      elseif r[i] < 0 then
         r[i] = 0
      end
      i = i + 1
   end
   return r
end

function parse_mousefile_line(line_to_parse, mousefile)
   -- check for sensitivity
   if mousesensitivity == nil then
      mousesensitivity = find_after_keyword(line_to_parse, "Sensitivity:")
      if mousesensitivity ~= nil then
         if mousesensitivity < 100 then
            mousesensitivity = 100
         elseif mousesensitivity > 600 then
            mousesensitivity = 600
         end
      end
   -- if we already have sensitivity, check for sensitivity curve
   elseif mousesensitivitymode == nil then
      mousesensitivitymode = find_after_keyword(line_to_parse, "Sensitivity Curve:")
      if mousesensitivitymode ~= nil then
         if mousesensitivitymode < 0 then
            mousesensitivitymode = 1
         elseif mousesensitivitymode > 6 then
            mousesensitivitymode = 6
         end
      end
   -- if we have all the above, go for control mode
   elseif mousecontrolmode == nil then
      mousecontrolmode = find_after_keyword(line_to_parse, "Control Mode:")
   -- if we have all the above, go for deadzone
   elseif mousedeadzone == nil then
      mousedeadzone = find_after_keyword(line_to_parse, "Deadzone:")
      if mousedeadzone ~= nil then
         if mousedeadzone < 0 then
            mousedeadzone = 0
         end
      end
   -- if we have all the above, go for mouse invert
   elseif mouseinvert == nil then
      mouseinvert = find_after_keyword(line_to_parse, "Mouse Invert:")
      if mouseinvert ~= 1 then
         mouseinvert = 0
      end
   -- if we have all the above, go for mouse boundaries
   elseif mouseboundaries == nil then
      mouseboundaries = find_after_keyword(line_to_parse, "Boundary Limit:")
   -- if we have all the above, go for mouse colors
   elseif mousecolor == nil then
      mousecolors = find_4_numbers_after_keyword(line_to_parse, "Indicator Color:")
   -- all found - set the position to end of file
   else
      mousefile:seek("end")
   end
end

-----------------------------------------------------------------------
-- check if the file containing mouse references exists
-----------------------------------------------------------------------
filename_mouse = "mouse_script.cfg"
boolmousefileOK = cf.fileExists(filename_mouse, "data/", false)
boolscriptmouse = false

-- if file exists
if boolmousefileOK then
   -- reset all the variables to nil
   mousesensitivity = nil
   mousesensitivitymode = nil
   mousecontrolmode = nil
   mousedeadzone = nil
   mouseinvert = nil
   mouseboundaries = nil
   mousecolor = nil
   mousecolors = {}

   -- open the file in read only mode
   mousefile = cf.openFile(filename_mouse, "r", "data/")

   -- pick first line
   new_line = mousefile:read("*l")

   while new_line ~= nil do
      -- parse line and then jump on to the next line until end of file
      parse_mousefile_line(new_line,mousefile)
      new_line = mousefile:read("*l")
   end

   -- all data read.. time to close the file
   mousefile:close()

   -- if these three were found from the cfg file...
   if mousesensitivity and mousesensitivitymode and mousecontrolmode then

      -- set script to actually run, allow lua to override c coded controls
      boolscriptmouse = true
      ba.setControlMode(LUA_FULL_CONTROLS)

      -- make sure we have a number in deadzone var and not nil
      if mousedeadzone == nil then
         mousedeadzone = 0
      end

      -- define some variables
      mouse_reset_counter = nil
      missiontime_old = 0
      missiontime = nil

      -- if mouse invert was set to true, then invert the mouse (set it to '-1')
      -- otherwise define the multiplier as '1'
      if mouseinvert == 1 then
         mouseinvert = -1
      else
         mouseinvert = 1
      end

      -- check if boundaries are valid
      if mouseboundaries == nil then
         mouseboundaries = 1
      end

      -- check that defined control area is not larger than the actual area which can be controlled
      local max_limits
      max_limits = mousesensitivity * 2 + mousedeadzone * 2 + 10
      scr_width = gr.getScreenWidth()
      scr_height = gr.getScreenHeight()
      if max_limits > scr_width or max_limits > scr_height then
         ba.warning("Mouse control area defined to be larger than the window size, please resize")
      end

      --setup mouse bitmap
      mouse_bm = gr.loadTexture("mouse_ret_2.dds", true)
      if mouse_bm:isValid() then
         no_bitmap = false
         mouse_bm_w = mouse_bm:getWidth() / 2
         mouse_bm_h = mouse_bm:getHeight() / 2
      else
         no_bitmap = true
      end
   else
      ba.warning("Scripted mouse's init failed")
   end
else
   ba.warning("File '" .. filename_mouse .."' not found")
end

]

$Application: FS2_Open
$State: GS_STATE_GAME_PLAY
$On Frame:

[

------------------------
------ functions -------
------------------------
function mouse_control_A(value, centervalue, axis)
   -- get the actual difference from centerpoint
   delta = value - centervalue

   -- default multiplier to +1
   multiplier = 1

   -- if we are handling negative values set multiplier to -1
   -- and make sure we deal only with positive values
   if delta < 0 then
      multiplier = -1
      delta = math.abs(delta)
   end

   -- deduct deadzone from the delta
   delta = delta - mousedeadzone
   if delta < 0 then
      delta = 0
   end

   -- scale delta from 0 to 1 according to defined sensitivity
   delta = delta / mousesensitivity
   if delta > 1 then
      delta = 1
   end

   -- if we do not have extreme values
   -- apply the defined sensitivity curve
   if (delta > 0) and (delta < 1) then
      delta = math.pow(delta, mousesensitivitymode)
   end

   -- apply the multiplier
   delta = delta * multiplier

   return delta
end
------------------------
function do_boundaries_check(limit)
   f_mouse_x = nil
   f_mouse_y = nil

   -- do we go over width limits
   if mouse_x <= limit then
      f_mouse_x = limit
   elseif mouse_x >= (scr_width - limit) then
      f_mouse_x = scr_width - limit
   end

   -- do we go over height limits
   if mouse_y <= limit then
      f_mouse_y = limit
   elseif mouse_y >= (scr_height - limit) then
      f_mouse_y = scr_height - limit
   end

   -- reset the cursor to the nearest boundary
   if f_mouse_x ~= nil or f_mouse_y ~= nil then
      if f_mouse_x and f_mouse_y then
         io.forceMousePosition(f_mouse_x, f_mouse_y)
      elseif f_mouse_x then
         io.forceMousePosition(f_mouse_x, mouse_y)
      else
         io.forceMousePosition(mouse_x, f_mouse_y)
      end
   end
end
------------------------
--- end of functions ---
------------------------

if boolscriptmouse == true then
   -- check for center button reset...
   if mouse_reset_counter == nil then
      mouse_center_x = io.getMouseX()
      mouse_center_y = io.getMouseY()
      mouse_reset_counter = 0
   end

   -- get frametime (used to increment the timer)
   frametime = ba.getFrametime()

   -- make sure missiontime and old missiontime exist
   if missiontime ~= nil then
      missiontime_old = missiontime
   end
   missiontime = mn.getMissionTime()

   -- if the setting changes make sure to reset it to false
   if io.MouseControlStatus == true then
      mouse_reset_on_end = true
      io.MouseControlStatus = false
   end

   -- check if missiontime is actually running or not
   if missiontime ~= missiontime_old then

      -- after pause ends (ie. missiontime starts running again)
      -- reset the mouse to the center
      if end_of_pause == true then
         io.forceMousePosition(mouse_center_x, mouse_center_y)
         end_of_pause = nil
      end

      -- increment the center mouse button down counter
      if io.isMouseButtonDown(MOUSE_MIDDLE_BUTTON) then
         mouse_reset_counter = mouse_reset_counter + frametime
      else
         mouse_reset_counter = 0
      end

      -- if center mouse button has been pressed long enough
      -- reset the mouse
      if mouse_reset_counter > 0.1 then
         io.forceMousePosition(mouse_center_x, mouse_center_y)
         mouse_reset_counter = 0
      end

      -- get control values
      mouse_x = io.getMouseX()
      mouse_y = io.getMouseY()
      controls = ba.getControlInfo()

      if mousecontrolmode == 1 or mousecontrolmode == 2 then

         -- make sure we aint gonna go off the boundaries...
         do_boundaries_check(mouseboundaries)
         -- end of boundaries check

if mousecontrolmode == 1 then
    -- get the actual control values
    current_h = mouse_control_A(mouse_x, mouse_center_x, "x")
    current_p = mouseinvert * mouse_control_A(mouse_y, mouse_center_y, "y")
   
    -- increment, not replace the existing values
    controls.Heading = current_h + controls.Heading
    controls.Pitch = current_p + controls.Pitch

    -- get draw position
    center_x = scr_width / 2
    center_y = scr_height / 2
    drawpos_x = center_x + (current_h * 300)
    drawpos_y = center_y + (current_p * 300)
end

if mousecontrolmode == 2 then
    center_x = scr_width / 2
    center_y = scr_height / 2
    if inited == nil then
       plr = hv.Player
       cpos = plr.Position + plr.Orientation:rotateVector( ba.createVector(0,-15,-75) )
       ccam = gr.createCamera("ccam", cpos, plr.Orientation)
       gr.setCamera(ccam)
       inited = true
    end
    if inited == true then
       -- the documentation says getVectorFromCoords gives you a normal
       -- vector, but the code says it's a normal vector + camera pos
       wanted_dir = gr.getVectorFromCoords(mouse_x, mouse_y) - cpos

       -- camera ALWAYS points towards where the mouse is
       -- just like any other first-person shoter
       ccam:setOrientation(wanted_dir:getOrientation())
       io.forceMousePosition(center_x, center_y)
       cpos = plr.Position + plr.Orientation:unrotateVector( ba.createVector(0,15,-50) )
       ccam:setPosition(cpos)

       -- now let's try to make the player point the same direction
       local_wanted_dir = plr.Orientation:rotateVector(wanted_dir)
       forward = ba.createVector(0,0,-4)
       axis = local_wanted_dir:getCrossProduct(forward)
       controls.Heading = axis.y
       controls.Pitch = axis.x

       -- now ensure that the ship is banked correctly
       -- in the future, this should capture whatever keys the player
       -- uses to bank and adjust the camera first with them
       up = ba.createVector(0,1,0)
       camup = ccam.Orientation:rotateVector(up)
       plrup = plr.Orientation:rotateVector(up)
       should_be_forward = camup:getCrossProduct(plrup)
       controls.Bank = should_be_forward.z

       -- make aim indicators.  It would be nice if there was
       -- an instruction to draw the rest of the HUD :(
       vec500 = ba.createVector(0,0,500)
       vec1000 = ba.createVector(0,0,1000)
       aim500 = plr.Position + plr.Orientation:unrotateVector(vec500)
       aim1000 = plr.Position + plr.Orientation:unrotateVector(vec1000)
       x,y = aim1000:getScreenCoords()
       gr.setColor(100,0,40)
       if x ~= nil and x ~= false then
  gr.drawLine(x+3,y+3,x-3,y-3)
  gr.drawLine(x+3,y-3,x-3,y+3)
       end
       x,y = aim500:getScreenCoords()
       if x ~= nil and x ~= false then
  gr.drawLine(x+4,y+4,x-4,y+4)
  gr.drawLine(x-4,y+4,x-4,y-4)
  gr.drawLine(x-4,y-4,x+4,y-4)
  gr.drawLine(x+4,y-4,x+4,y+4)
       end

    end

    drawpos_x = center_x
    drawpos_y = center_y
end

         -- define the color of the cursor
         if mousecolors == nil then
            gr.setColor(0,64,220,196)
         else
            gr.setColor(mousecolors[1],mousecolors[2],mousecolors[3],mousecolors[4])
         end

         -- draw cursor
         if no_bitmap == true then
            gr.drawGradientLine(drawpos_x, drawpos_y, drawpos_x + 20, drawpos_y - 20)
            gr.drawGradientLine(drawpos_x, drawpos_y, drawpos_x - 20, drawpos_y + 20)
            gr.drawGradientLine(drawpos_x, drawpos_y, drawpos_x + 20, drawpos_y + 20)
            gr.drawGradientLine(drawpos_x, drawpos_y, drawpos_x - 20, drawpos_y - 20)
         else
            gr.drawMonochromeImage(mouse_bm, drawpos_x - mouse_bm_w, drawpos_y - mouse_bm_h, drawpos_x + mouse_bm_w, drawpos_y + mouse_bm_h)
         end
      end
   else
      end_of_pause = true
   end
end

]

$Application: FS2_Open
$On Mission End:

[

boolscriptmouse = false
ba.setControlMode(NORMAL_CONTROLS)
if mouse_reset_on_end == true then
   io.MouseControlStatus = true
end

]

#End
Title: Re: hate how the mouse works? have i got the script for you!
Post by: eigenlambda on March 30, 2010, 02:06:01 am
Now, with HUD fixes.  Thanks to Wanderer for figuring out how.  Set "Control Mode: 2", and please complain about the HUD modifications and suggest other configurations or options.  Also, SCP guys, can we get a hu.disableGauge()?

Code: [Select]
#Conditional Hooks

$Application: FS2_Open
$On Mission Start:

[

-- couple of functions to make things go easier
function find_after_keyword(line_to_parse, keyword)

   -- make sure both strings are in lower case
   line_to_parse = line_to_parse:lower()
   keyword = keyword:lower()

   -- find any instances of the keyword
   key_s, key_e = line_to_parse:find(keyword)

   -- if we cant find a thing
   if key_s == nil then
      return nil
   end

   result = line_to_parse:match("%d+", e_key)
   return tonumber(result)
end

function find_4_numbers_after_keyword(line_to_parse, keyword)

   -- make sure both strings are in lower case
   line_to_parse = line_to_parse:lower()
   keyword = keyword:lower()

   -- find any instances of the keyword
   key_s, key_e = line_to_parse:find(keyword)

   -- if we cant find a thing
   if key_s == nil then
      return nil
   end

   -- make sure r is an array
   r = {}
   i = 1

   -- stuff the array
   for p in line_to_parse:gmatch("%d+") do
      r[i] = p
      r[i] = tonumber(r[i])
      if r[i] > 255 then
         r[i] = 255
      elseif r[i] < 0 then
         r[i] = 0
      end
      i = i + 1
   end
   return r
end

function parse_mousefile_line(line_to_parse, mousefile)
   -- check for sensitivity
   if mousesensitivity == nil then
      mousesensitivity = find_after_keyword(line_to_parse, "Sensitivity:")
      if mousesensitivity ~= nil then
         if mousesensitivity < 100 then
            mousesensitivity = 100
         elseif mousesensitivity > 600 then
            mousesensitivity = 600
         end
      end
   -- if we already have sensitivity, check for sensitivity curve
   elseif mousesensitivitymode == nil then
      mousesensitivitymode = find_after_keyword(line_to_parse, "Sensitivity Curve:")
      if mousesensitivitymode ~= nil then
         if mousesensitivitymode < 0 then
            mousesensitivitymode = 1
         elseif mousesensitivitymode > 6 then
            mousesensitivitymode = 6
         end
      end
   -- if we have all the above, go for control mode
   elseif mousecontrolmode == nil then
      mousecontrolmode = find_after_keyword(line_to_parse, "Control Mode:")
   -- if we have all the above, go for deadzone
   elseif mousedeadzone == nil then
      mousedeadzone = find_after_keyword(line_to_parse, "Deadzone:")
      if mousedeadzone ~= nil then
         if mousedeadzone < 0 then
            mousedeadzone = 0
         end
      end
   -- if we have all the above, go for mouse invert
   elseif mouseinvert == nil then
      mouseinvert = find_after_keyword(line_to_parse, "Mouse Invert:")
      if mouseinvert ~= 1 then
         mouseinvert = 0
      end
   -- if we have all the above, go for mouse boundaries
   elseif mouseboundaries == nil then
      mouseboundaries = find_after_keyword(line_to_parse, "Boundary Limit:")
   -- if we have all the above, go for mouse colors
   elseif mousecolor == nil then
      mousecolors = find_4_numbers_after_keyword(line_to_parse, "Indicator Color:")
   -- all found - set the position to end of file
   else
      mousefile:seek("end")
   end
end

-----------------------------------------------------------------------
-- check if the file containing mouse references exists
-----------------------------------------------------------------------
filename_mouse = "mouse_script.cfg"
boolmousefileOK = cf.fileExists(filename_mouse, "data/", false)
boolscriptmouse = false

-- if file exists
if boolmousefileOK then
   -- reset all the variables to nil
   mousesensitivity = nil
   mousesensitivitymode = nil
   mousecontrolmode = nil
   mousedeadzone = nil
   mouseinvert = nil
   mouseboundaries = nil
   mousecolor = nil
   mousecolors = {}

   -- open the file in read only mode
   mousefile = cf.openFile(filename_mouse, "r", "data/")

   -- pick first line
   new_line = mousefile:read("*l")

   while new_line ~= nil do
      -- parse line and then jump on to the next line until end of file
      parse_mousefile_line(new_line,mousefile)
      new_line = mousefile:read("*l")
   end

   -- all data read.. time to close the file
   mousefile:close()

   -- if these three were found from the cfg file...
   if mousesensitivity and mousesensitivitymode and mousecontrolmode then

      -- set script to actually run, allow lua to override c coded controls
      boolscriptmouse = true
      ba.setControlMode(LUA_FULL_CONTROLS)

      -- make sure we have a number in deadzone var and not nil
      if mousedeadzone == nil then
         mousedeadzone = 0
      end

      -- define some variables
      mouse_reset_counter = nil
      missiontime_old = 0
      missiontime = nil

      -- if mouse invert was set to true, then invert the mouse (set it to '-1')
      -- otherwise define the multiplier as '1'
      if mouseinvert == 1 then
         mouseinvert = -1
      else
         mouseinvert = 1
      end

      -- check if boundaries are valid
      if mouseboundaries == nil then
         mouseboundaries = 1
      end

      -- check that defined control area is not larger than the actual area which can be controlled
      local max_limits
      max_limits = mousesensitivity * 2 + mousedeadzone * 2 + 10
      scr_width = gr.getScreenWidth()
      scr_height = gr.getScreenHeight()
      if max_limits > scr_width or max_limits > scr_height then
         ba.warning("Mouse control area defined to be larger than the window size, please resize")
      end

      --setup mouse bitmap
      mouse_bm = gr.loadTexture("mouse_ret_2.dds", true)
      if mouse_bm:isValid() then
         no_bitmap = false
         mouse_bm_w = mouse_bm:getWidth() / 2
         mouse_bm_h = mouse_bm:getHeight() / 2
      else
         no_bitmap = true
      end
   else
      ba.warning("Scripted mouse's init failed")
   end
else
   ba.warning("File '" .. filename_mouse .."' not found")
end

]

$Application: FS2_Open
$State: GS_STATE_GAME_PLAY
$On Frame:

[

------------------------
------ functions -------
------------------------
function mouse_control_A(value, centervalue, axis)
   -- get the actual difference from centerpoint
   delta = value - centervalue

   -- default multiplier to +1
   multiplier = 1

   -- if we are handling negative values set multiplier to -1
   -- and make sure we deal only with positive values
   if delta < 0 then
      multiplier = -1
      delta = math.abs(delta)
   end

   -- deduct deadzone from the delta
   delta = delta - mousedeadzone
   if delta < 0 then
      delta = 0
   end

   -- scale delta from 0 to 1 according to defined sensitivity
   delta = delta / mousesensitivity
   if delta > 1 then
      delta = 1
   end

   -- if we do not have extreme values
   -- apply the defined sensitivity curve
   if (delta > 0) and (delta < 1) then
      delta = math.pow(delta, mousesensitivitymode)
   end

   -- apply the multiplier
   delta = delta * multiplier

   return delta
end
------------------------
function do_boundaries_check(limit)
   f_mouse_x = nil
   f_mouse_y = nil

   -- do we go over width limits
   if mouse_x <= limit then
      f_mouse_x = limit
   elseif mouse_x >= (scr_width - limit) then
      f_mouse_x = scr_width - limit
   end

   -- do we go over height limits
   if mouse_y <= limit then
      f_mouse_y = limit
   elseif mouse_y >= (scr_height - limit) then
      f_mouse_y = scr_height - limit
   end

   -- reset the cursor to the nearest boundary
   if f_mouse_x ~= nil or f_mouse_y ~= nil then
      if f_mouse_x and f_mouse_y then
         io.forceMousePosition(f_mouse_x, f_mouse_y)
      elseif f_mouse_x then
         io.forceMousePosition(f_mouse_x, mouse_y)
      else
         io.forceMousePosition(mouse_x, f_mouse_y)
      end
   end
end
------------------------
--- end of functions ---
------------------------

if boolscriptmouse == true then
   -- check for center button reset...
   if mouse_reset_counter == nil then
      mouse_center_x = io.getMouseX()
      mouse_center_y = io.getMouseY()
      mouse_reset_counter = 0
   end

   -- get frametime (used to increment the timer)
   frametime = ba.getFrametime()

   -- make sure missiontime and old missiontime exist
   if missiontime ~= nil then
      missiontime_old = missiontime
   end
   missiontime = mn.getMissionTime()

   -- if the setting changes make sure to reset it to false
   if io.MouseControlStatus == true then
      mouse_reset_on_end = true
      io.MouseControlStatus = false
   end

   -- check if missiontime is actually running or not
   if missiontime ~= missiontime_old then

      -- after pause ends (ie. missiontime starts running again)
      -- reset the mouse to the center
      if end_of_pause == true then
         io.forceMousePosition(mouse_center_x, mouse_center_y)
         end_of_pause = nil
      end

      -- increment the center mouse button down counter
      if io.isMouseButtonDown(MOUSE_MIDDLE_BUTTON) then
         mouse_reset_counter = mouse_reset_counter + frametime
      else
         mouse_reset_counter = 0
      end

      -- if center mouse button has been pressed long enough
      -- reset the mouse
      if mouse_reset_counter > 0.1 then
         io.forceMousePosition(mouse_center_x, mouse_center_y)
         mouse_reset_counter = 0
      end

      -- get control values
      mouse_x = io.getMouseX()
      mouse_y = io.getMouseY()
      controls = ba.getControlInfo()

      if mousecontrolmode == 1 or mousecontrolmode == 2 then

         -- make sure we aint gonna go off the boundaries...
         do_boundaries_check(mouseboundaries)
         -- end of boundaries check

if mousecontrolmode == 1 then
    -- get the actual control values
    current_h = mouse_control_A(mouse_x, mouse_center_x, "x")
    current_p = mouseinvert * mouse_control_A(mouse_y, mouse_center_y, "y")
   
    -- increment, not replace the existing values
    controls.Heading = current_h + controls.Heading
    controls.Pitch = current_p + controls.Pitch

    -- get draw position
    center_x = scr_width / 2
    center_y = scr_height / 2
    drawpos_x = center_x + (current_h * 300)
    drawpos_y = center_y + (current_p * 300)
    -- define the color of the cursor
    if mousecolors == nil then
       gr.setColor(0,64,220,196)
    else
       gr.setColor(mousecolors[1],mousecolors[2],mousecolors[3],mousecolors[4])
    end
   
    -- draw cursor
    if no_bitmap == true then
       gr.drawGradientLine(drawpos_x, drawpos_y, drawpos_x + 20, drawpos_y - 20)
       gr.drawGradientLine(drawpos_x, drawpos_y, drawpos_x - 20, drawpos_y + 20)
       gr.drawGradientLine(drawpos_x, drawpos_y, drawpos_x + 20, drawpos_y + 20)
       gr.drawGradientLine(drawpos_x, drawpos_y, drawpos_x - 20, drawpos_y - 20)
    else
       gr.drawMonochromeImage(mouse_bm, drawpos_x - mouse_bm_w, drawpos_y - mouse_bm_h, drawpos_x + mouse_bm_w, drawpos_y + mouse_bm_h)
    end
   
end

if mousecontrolmode == 2 then --airquake mouse mode
    if inited == nil then
       plr = hv.Player
       cpos = plr.Position + plr.Orientation:rotateVector( ba.createVector(0,-15,-75) )
       ccam = gr.createCamera("ccam", cpos, plr.Orientation)
       gr.setCamera(ccam)
       inited = true
    end
    if inited == true then
       -- the documentation says getVectorFromCoords gives you a normal
       -- vector, but the code says it's a normal vector + camera pos
       wanted_dir = gr.getVectorFromCoords(mouse_x, mouse_y) - cpos

       -- camera ALWAYS points towards where the mouse is
       -- just like any other first-person shoter
       ccam:setOrientation(wanted_dir:getOrientation())
       io.forceMousePosition(scr_width/2, scr_height/2)
       cpos = plr.Position + plr.Orientation:unrotateVector( ba.createVector(0,15,-50) )
       ccam:setPosition(cpos)

       -- now let's try to make the player point the same direction
       local_wanted_dir = plr.Orientation:rotateVector(wanted_dir)
       forward = ba.createVector(0,0,-4)
       axis = local_wanted_dir:getCrossProduct(forward)
       controls.Heading = axis.y
       controls.Pitch = axis.x

       -- now ensure that the ship is banked correctly
       -- in the future, this should capture whatever keys the player
       -- uses to bank and adjust the camera first with them
       up = ba.createVector(0,1,0)
       camup = ccam.Orientation:rotateVector(up)
       plrup = plr.Orientation:rotateVector(up)
       should_be_forward = camup:getCrossProduct(plrup)
       controls.Bank = should_be_forward.z

       -- lastly, fix the HUD
       -- first kill the annoying gauges
       hu.setHUDGaugeColor( 9,0,0,0,0) --reticle center
       hu.setHUDGaugeColor(23,0,0,0,0) --target mini icon
       hu.setHUDGaugeColor(19,0,0,0,0) --threat gauge
       hu.setHUDGaugeColor( 6,0,0,0,0) --throttle gauge
       hu.setHUDGaugeColor(20,0,0,0,0) --afterburner energy
       hu.setHUDGaugeColor(21,0,0,0,0) --weapons energy
       -- then replace them
       gaugey = math.floor(.6*scr_height)
       gr.setColor(200, 200, 0, 100)
       energy_fraction = plr.WeaponEnergyLeft/plr.WeaponEnergyLeft
       gr.drawRectangle(0, gaugey+1, 100*energy_fraction, gaugey+9)
       burn_fraction = plr.AfterburnerFuelLeft/plr.AfterburnerFuelMax
       gr.drawRectangle(0, gaugey+11, 100*burn_fraction, gaugey+19)
       speed = math.floor(plr.Physics:getForwardSpeed()+.5)
       gr.drawString(speed, 100, gaugey+11)
       if plr.PrimaryTriggerDown then
  gr.setColor(100, 0, 0, 64)
  gr.drawCircle(5, 105, gaugey+5)
       end

       -- make aim indicators
       vec300 = ba.createVector(0,0,300)
       vec1000 = ba.createVector(0,0,1000)
       aim300 = plr.Position + plr.Orientation:unrotateVector(vec300)
       aim1000 = plr.Position + plr.Orientation:unrotateVector(vec1000)
       x,y = aim1000:getScreenCoords()
       gr.setColor(150,150,150,150)
       if x ~= nil and x ~= false then
  gr.drawLine(x+4,y+4,x-4,y-4)
  gr.drawLine(x+4,y-4,x-4,y+4)
       end
       x,y = aim300:getScreenCoords()
       if x ~= nil and x ~= false then
  gr.drawRectangle(x-6,y-6,x+6,y+6,false)
       end

       -- now tell the hud to draw
       hu.HUDDrawn = true
    end
end
      end
   else
      end_of_pause = true
   end
end

]

$Application: FS2_Open
$On Mission End:

[

boolscriptmouse = false
ba.setControlMode(NORMAL_CONTROLS)
if mouse_reset_on_end == true then
   io.MouseControlStatus = true
end

]

#End

update: fixed which gauges to remove.   Also, playtesting reveals that when you look up or down, you spin obnoxiously.  This is unacceptable in a true 3d game, so I'll have to look into how to fix that.
Title: Re: hate how the mouse works? have i got the script for you!
Post by: eigenlambda on March 31, 2010, 06:32:00 pm
I fixed the obnoxious spinning problem.  So that's good.

Lastly, the one thing that's keeping me from being able to shoot down dragons with the guns on an artemis is how slow the controls are to get centered on the center of the screen, and how they lazily bob back and forth around that center.  I need to figure out how to cancel rotational momentum precisely when it gets centered.  Any ideas?

Code: [Select]
#Conditional Hooks

$Application: FS2_Open
$On Mission Start:

[

-- couple of functions to make things go easier
function find_after_keyword(line_to_parse, keyword)

   -- make sure both strings are in lower case
   line_to_parse = line_to_parse:lower()
   keyword = keyword:lower()

   -- find any instances of the keyword
   key_s, key_e = line_to_parse:find(keyword)

   -- if we cant find a thing
   if key_s == nil then
      return nil
   end

   result = line_to_parse:match("%d+", e_key)
   return tonumber(result)
end

function find_4_numbers_after_keyword(line_to_parse, keyword)

   -- make sure both strings are in lower case
   line_to_parse = line_to_parse:lower()
   keyword = keyword:lower()

   -- find any instances of the keyword
   key_s, key_e = line_to_parse:find(keyword)

   -- if we cant find a thing
   if key_s == nil then
      return nil
   end

   -- make sure r is an array
   r = {}
   i = 1

   -- stuff the array
   for p in line_to_parse:gmatch("%d+") do
      r[i] = p
      r[i] = tonumber(r[i])
      if r[i] > 255 then
         r[i] = 255
      elseif r[i] < 0 then
         r[i] = 0
      end
      i = i + 1
   end
   return r
end

function parse_mousefile_line(line_to_parse, mousefile)
   -- check for sensitivity
   if mousesensitivity == nil then
      mousesensitivity = find_after_keyword(line_to_parse, "Sensitivity:")
      if mousesensitivity ~= nil then
         if mousesensitivity < 100 then
            mousesensitivity = 100
         elseif mousesensitivity > 600 then
            mousesensitivity = 600
         end
      end
   -- if we already have sensitivity, check for sensitivity curve
   elseif mousesensitivitymode == nil then
      mousesensitivitymode = find_after_keyword(line_to_parse, "Sensitivity Curve:")
      if mousesensitivitymode ~= nil then
         if mousesensitivitymode < 0 then
            mousesensitivitymode = 1
         elseif mousesensitivitymode > 6 then
            mousesensitivitymode = 6
         end
      end
   -- if we have all the above, go for control mode
   elseif mousecontrolmode == nil then
      mousecontrolmode = find_after_keyword(line_to_parse, "Control Mode:")
   -- if we have all the above, go for deadzone
   elseif mousedeadzone == nil then
      mousedeadzone = find_after_keyword(line_to_parse, "Deadzone:")
      if mousedeadzone ~= nil then
         if mousedeadzone < 0 then
            mousedeadzone = 0
         end
      end
   -- if we have all the above, go for mouse invert
   elseif mouseinvert == nil then
      mouseinvert = find_after_keyword(line_to_parse, "Mouse Invert:")
      if mouseinvert ~= 1 then
         mouseinvert = 0
      end
   -- if we have all the above, go for mouse boundaries
   elseif mouseboundaries == nil then
      mouseboundaries = find_after_keyword(line_to_parse, "Boundary Limit:")
   -- if we have all the above, go for mouse colors
   elseif mousecolor == nil then
      mousecolors = find_4_numbers_after_keyword(line_to_parse, "Indicator Color:")
   -- all found - set the position to end of file
   else
      mousefile:seek("end")
   end
end

-----------------------------------------------------------------------
-- check if the file containing mouse references exists
-----------------------------------------------------------------------
filename_mouse = "mouse_script.cfg"
boolmousefileOK = cf.fileExists(filename_mouse, "data/", false)
boolscriptmouse = false

-- if file exists
if boolmousefileOK then
   -- reset all the variables to nil
   mousesensitivity = nil
   mousesensitivitymode = nil
   mousecontrolmode = nil
   mousedeadzone = nil
   mouseinvert = nil
   mouseboundaries = nil
   mousecolor = nil
   mousecolors = {}

   -- open the file in read only mode
   mousefile = cf.openFile(filename_mouse, "r", "data/")

   -- pick first line
   new_line = mousefile:read("*l")

   while new_line ~= nil do
      -- parse line and then jump on to the next line until end of file
      parse_mousefile_line(new_line,mousefile)
      new_line = mousefile:read("*l")
   end

   -- all data read.. time to close the file
   mousefile:close()

   -- if these three were found from the cfg file...
   if mousesensitivity and mousesensitivitymode and mousecontrolmode then

      -- set script to actually run, allow lua to override c coded controls
      boolscriptmouse = true
      ba.setControlMode(LUA_FULL_CONTROLS)

      -- make sure we have a number in deadzone var and not nil
      if mousedeadzone == nil then
         mousedeadzone = 0
      end

      -- define some variables
      mouse_reset_counter = nil
      missiontime_old = 0
      missiontime = nil

      -- if mouse invert was set to true, then invert the mouse (set it to '-1')
      -- otherwise define the multiplier as '1'
      if mouseinvert == 1 then
         mouseinvert = -1
      else
         mouseinvert = 1
      end

      -- check if boundaries are valid
      if mouseboundaries == nil then
         mouseboundaries = 1
      end

      -- check that defined control area is not larger than the actual area which can be controlled
      local max_limits
      max_limits = mousesensitivity * 2 + mousedeadzone * 2 + 10
      scr_width = gr.getScreenWidth()
      scr_height = gr.getScreenHeight()
      if max_limits > scr_width or max_limits > scr_height then
         ba.warning("Mouse control area defined to be larger than the window size, please resize")
      end

      --setup mouse bitmap
      mouse_bm = gr.loadTexture("mouse_ret_2.dds", true)
      if mouse_bm:isValid() then
         no_bitmap = false
         mouse_bm_w = mouse_bm:getWidth() / 2
         mouse_bm_h = mouse_bm:getHeight() / 2
      else
         no_bitmap = true
      end
   else
      ba.warning("Scripted mouse's init failed")
   end
else
   ba.warning("File '" .. filename_mouse .."' not found")
end

]

$Application: FS2_Open
$State: GS_STATE_GAME_PLAY
$On Frame:

[

------------------------
------ functions -------
------------------------
function mouse_control_A(value, centervalue, axis)
   -- get the actual difference from centerpoint
   delta = value - centervalue

   -- default multiplier to +1
   multiplier = 1

   -- if we are handling negative values set multiplier to -1
   -- and make sure we deal only with positive values
   if delta < 0 then
      multiplier = -1
      delta = math.abs(delta)
   end

   -- deduct deadzone from the delta
   delta = delta - mousedeadzone
   if delta < 0 then
      delta = 0
   end

   -- scale delta from 0 to 1 according to defined sensitivity
   delta = delta / mousesensitivity
   if delta > 1 then
      delta = 1
   end

   -- if we do not have extreme values
   -- apply the defined sensitivity curve
   if (delta > 0) and (delta < 1) then
      delta = math.pow(delta, mousesensitivitymode)
   end

   -- apply the multiplier
   delta = delta * multiplier

   return delta
end
------------------------
function do_boundaries_check(limit)
   f_mouse_x = nil
   f_mouse_y = nil

   -- do we go over width limits
   if mouse_x <= limit then
      f_mouse_x = limit
   elseif mouse_x >= (scr_width - limit) then
      f_mouse_x = scr_width - limit
   end

   -- do we go over height limits
   if mouse_y <= limit then
      f_mouse_y = limit
   elseif mouse_y >= (scr_height - limit) then
      f_mouse_y = scr_height - limit
   end

   -- reset the cursor to the nearest boundary
   if f_mouse_x ~= nil or f_mouse_y ~= nil then
      if f_mouse_x and f_mouse_y then
         io.forceMousePosition(f_mouse_x, f_mouse_y)
      elseif f_mouse_x then
         io.forceMousePosition(f_mouse_x, mouse_y)
      else
         io.forceMousePosition(mouse_x, f_mouse_y)
      end
   end
end
------------------------
--- end of functions ---
------------------------

if boolscriptmouse == true then
   -- check for center button reset...
   if mouse_reset_counter == nil then
      mouse_center_x = io.getMouseX()
      mouse_center_y = io.getMouseY()
      mouse_reset_counter = 0
   end

   -- get frametime (used to increment the timer)
   frametime = ba.getFrametime()

   -- make sure missiontime and old missiontime exist
   if missiontime ~= nil then
      missiontime_old = missiontime
   end
   missiontime = mn.getMissionTime()

   -- if the setting changes make sure to reset it to false
   if io.MouseControlStatus == true then
      mouse_reset_on_end = true
      io.MouseControlStatus = false
   end

   -- check if missiontime is actually running or not
   if missiontime ~= missiontime_old then

      -- after pause ends (ie. missiontime starts running again)
      -- reset the mouse to the center
      if end_of_pause == true then
         io.forceMousePosition(mouse_center_x, mouse_center_y)
         end_of_pause = nil
      end

      -- increment the center mouse button down counter
      if io.isMouseButtonDown(MOUSE_MIDDLE_BUTTON) then
         mouse_reset_counter = mouse_reset_counter + frametime
      else
         mouse_reset_counter = 0
      end

      -- if center mouse button has been pressed long enough
      -- reset the mouse
      if mouse_reset_counter > 0.1 then
         io.forceMousePosition(mouse_center_x, mouse_center_y)
         mouse_reset_counter = 0
      end

      -- get control values
      mouse_x = io.getMouseX()
      mouse_y = io.getMouseY()
      controls = ba.getControlInfo()

      if mousecontrolmode == 1 or mousecontrolmode == 2 then

         -- make sure we aint gonna go off the boundaries...
         do_boundaries_check(mouseboundaries)
         -- end of boundaries check

if mousecontrolmode == 1 then
    -- get the actual control values
    current_h = mouse_control_A(mouse_x, mouse_center_x, "x")
    current_p = mouseinvert * mouse_control_A(mouse_y, mouse_center_y, "y")
   
    -- increment, not replace the existing values
    controls.Heading = current_h + controls.Heading
    controls.Pitch = current_p + controls.Pitch

    -- get draw position
    center_x = scr_width / 2
    center_y = scr_height / 2
    drawpos_x = center_x + (current_h * 300)
    drawpos_y = center_y + (current_p * 300)
    -- define the color of the cursor
    if mousecolors == nil then
       gr.setColor(0,64,220,196)
    else
       gr.setColor(mousecolors[1],mousecolors[2],mousecolors[3],mousecolors[4])
    end
   
    -- draw cursor
    if no_bitmap == true then
       gr.drawGradientLine(drawpos_x, drawpos_y, drawpos_x + 20, drawpos_y - 20)
       gr.drawGradientLine(drawpos_x, drawpos_y, drawpos_x - 20, drawpos_y + 20)
       gr.drawGradientLine(drawpos_x, drawpos_y, drawpos_x + 20, drawpos_y + 20)
       gr.drawGradientLine(drawpos_x, drawpos_y, drawpos_x - 20, drawpos_y - 20)
    else
       gr.drawMonochromeImage(mouse_bm, drawpos_x - mouse_bm_w, drawpos_y - mouse_bm_h, drawpos_x + mouse_bm_w, drawpos_y + mouse_bm_h)
    end
   
end

if mousecontrolmode == 2 then --airquake mouse mode
    if inited == nil then
       plr = hv.Player
       cpos = plr.Position + plr.Orientation:rotateVector( ba.createVector(0,-15,-75) )
       ccam = gr.createCamera("ccam", cpos, plr.Orientation)
       gr.setCamera(ccam)
       inited = true
    end
    if inited == true then
       -- the documentation says getVectorFromCoords gives you a normal
       -- vector, but the code says it's a normal vector + camera pos
       wanted_dir = gr.getVectorFromCoords(mouse_x, mouse_y) - cpos

       -- camera ALWAYS points towards where the mouse is
       -- just like any other first-person shoter
       delta = ccam.Orientation:rotateVector(wanted_dir):getOrientation()
       ccam:setOrientation(ccam.Orientation*delta)
       io.forceMousePosition(scr_width/2, scr_height/2)
       cpos = plr.Position + plr.Orientation:unrotateVector( ba.createVector(0,15,-50) )
       ccam:setPosition(cpos)

       -- now let's try to make the player point the same direction
       local_wanted_dir = plr.Orientation:rotateVector(wanted_dir)
       forward = ba.createVector(0,0,1)
       axis = local_wanted_dir:getCrossProduct(forward)
       cosdelta = local_wanted_dir:getDotProduct(forward)
       if cosdelta < 0 then -- obtuse angle between ship and cam forward
  r = math.sqrt(axis.x*axis.x + axis.y*axis.y)
  controls.Heading = -5*axis.y/r
  controls.Pitch = -5*axis.x/r
       else
  sindelta = axis:getMagnitude()
  control = 10*sindelta
  controls.Heading = -control*axis.y
  controls.Pitch = -control*axis.x
  gr.setColor(255,255,255)
  gr.drawString(control, 300, 300)
  gr.drawString(axis.y, 300, 310)
  gr.drawString(axis.x, 300, 320)
  gr.drawString(-control*axis.y, 300, 330)
  gr.drawString(-control*axis.x, 300, 340)
       end
       

       -- now ensure that the ship is banked correctly
       -- in the future, this should capture whatever keys the player
       -- uses to bank and adjust the camera first with them
       up = ba.createVector(0,1,0)
       camup = ccam.Orientation:rotateVector(up)
       plrup = plr.Orientation:rotateVector(up)
       should_be_forward = camup:getCrossProduct(plrup)
       controls.Bank = should_be_forward.z

       -- lastly, fix the HUD
       -- first kill the annoying gauges
       hu.setHUDGaugeColor( 9,0,0,0,0) --reticle center
       hu.setHUDGaugeColor(23,0,0,0,0) --target mini icon
       hu.setHUDGaugeColor(19,0,0,0,0) --threat gauge
       hu.setHUDGaugeColor( 6,0,0,0,0) --throttle gauge
       hu.setHUDGaugeColor(20,0,0,0,0) --afterburner energy
       hu.setHUDGaugeColor(21,0,0,0,0) --weapons energy
       -- then replace them
       gaugey = math.floor(.6*scr_height)
       gr.setColor(200, 200, 0, 100)
       energy_fraction = plr.WeaponEnergyLeft/plr.WeaponEnergyLeft
       gr.drawRectangle(0, gaugey+1, 100*energy_fraction, gaugey+9)
       burn_fraction = plr.AfterburnerFuelLeft/plr.AfterburnerFuelMax
       gr.drawRectangle(0, gaugey+11, 100*burn_fraction, gaugey+19)
       speed = math.floor(plr.Physics:getForwardSpeed()+.5)
       gr.drawString(speed, 100, gaugey+11)
       if plr.PrimaryTriggerDown then
  gr.setColor(100, 0, 0, 64)
  gr.drawCircle(5, 105, gaugey+5)
       end

       -- make aim indicators
       vec300 = ba.createVector(0,0,300)
       vec1000 = ba.createVector(0,0,1000)
       aim300 = plr.Position + plr.Orientation:unrotateVector(vec300)
       aim1000 = plr.Position + plr.Orientation:unrotateVector(vec1000)
       x,y = aim1000:getScreenCoords()
       gr.setColor(150,150,150,150)
       if x ~= nil and x ~= false then
  gr.drawLine(x+4,y+4,x-4,y-4)
  gr.drawLine(x+4,y-4,x-4,y+4)
       end
       x,y = aim300:getScreenCoords()
       if x ~= nil and x ~= false then
  gr.drawRectangle(x-6,y-6,x+6,y+6,false)
       end

       -- now tell the hud to draw
       hu.HUDDrawn = true
    end
end
      end
   else
      end_of_pause = true
   end
end

]

$Application: FS2_Open
$On Mission End:

[

boolscriptmouse = false
ba.setControlMode(NORMAL_CONTROLS)
if mouse_reset_on_end == true then
   io.MouseControlStatus = true
end

]

#End
Title: Re: hate how the mouse works? have i got the script for you!
Post by: Wanderer on April 07, 2010, 02:38:21 am
Not really.. other than possibly forcing ship to 'start turn' to opposite direction.
Title: Re: hate how the mouse works? have i got the script for you!
Post by: eigenlambda on April 07, 2010, 12:35:05 pm
Naturally.  According to control theory, the fastest way to get from point A to point B is full acceleration in both directions.

I've looked through the code at how things are done.  Did you know that the player ship's rotational inertia is determined by its max rotational velocity on each axis (kinda)?  Apparently, each frame your rotational velocity is recalculated for each axis, like so:
Code: [Select]
plr = hv.Player
controls = ba.getControlInfo()
wantedrvy = controls.Heading * plr.Physics.MaxRotationalVelocity.y
plr.Physics.RotationalVelocity.y = wantedrvy - (wantedrvy -  plr.Physics.RotationalVelocity.y) * math.exp(-ba.getFrametime()/ plr.Physics.RotationalVelocityDamping)
so it should be pretty clear from that when to apply max reverse... i'm currently tuning it
Title: Re: hate how the mouse works? have i got the script for you!
Post by: Lukeskywalkie on April 10, 2010, 10:51:55 am
Galemp: Try the Velocity Indicator script.

This should give you something to steer with a little better.

That, and it's just kinda cool.

I noticed this little gem activated while playing blue planet + glide, and after some searching I found a tbm to turn it off...
But how do I turn it on? I mean, for everything, all the time? It's awesome.
Title: Re: hate how the mouse works? have i got the script for you!
Post by: eigenlambda on April 10, 2010, 12:01:03 pm
This works, more or less.  I love owning stuff with only my guns.  By the way, Prometheus R sucks, I'd rather take on fighters with the Akheton SDG.

Code: [Select]
#Conditional Hooks

$Application: FS2_Open
$On Mission Start:

[

-- couple of functions to make things go easier
function find_after_keyword(line_to_parse, keyword)

   -- make sure both strings are in lower case
   line_to_parse = line_to_parse:lower()
   keyword = keyword:lower()

   -- find any instances of the keyword
   key_s, key_e = line_to_parse:find(keyword)

   -- if we cant find a thing
   if key_s == nil then
      return nil
   end

   result = line_to_parse:match("%d+", e_key)
   return tonumber(result)
end

function find_4_numbers_after_keyword(line_to_parse, keyword)

   -- make sure both strings are in lower case
   line_to_parse = line_to_parse:lower()
   keyword = keyword:lower()

   -- find any instances of the keyword
   key_s, key_e = line_to_parse:find(keyword)

   -- if we cant find a thing
   if key_s == nil then
      return nil
   end

   -- make sure r is an array
   r = {}
   i = 1

   -- stuff the array
   for p in line_to_parse:gmatch("%d+") do
      r[i] = p
      r[i] = tonumber(r[i])
      if r[i] > 255 then
         r[i] = 255
      elseif r[i] < 0 then
         r[i] = 0
      end
      i = i + 1
   end
   return r
end

function parse_mousefile_line(line_to_parse, mousefile)
   -- check for sensitivity
   if mousesensitivity == nil then
      mousesensitivity = find_after_keyword(line_to_parse, "Sensitivity:")
      if mousesensitivity ~= nil then
         if mousesensitivity < 100 then
            mousesensitivity = 100
         elseif mousesensitivity > 600 then
            mousesensitivity = 600
         end
      end
   -- if we already have sensitivity, check for sensitivity curve
   elseif mousesensitivitymode == nil then
      mousesensitivitymode = find_after_keyword(line_to_parse, "Sensitivity Curve:")
      if mousesensitivitymode ~= nil then
         if mousesensitivitymode < 0 then
            mousesensitivitymode = 1
         elseif mousesensitivitymode > 6 then
            mousesensitivitymode = 6
         end
      end
   -- if we have all the above, go for control mode
   elseif mousecontrolmode == nil then
      mousecontrolmode = find_after_keyword(line_to_parse, "Control Mode:")
   -- if we have all the above, go for deadzone
   elseif mousedeadzone == nil then
      mousedeadzone = find_after_keyword(line_to_parse, "Deadzone:")
      if mousedeadzone ~= nil then
         if mousedeadzone < 0 then
            mousedeadzone = 0
         end
      end
   -- if we have all the above, go for mouse invert
   elseif mouseinvert == nil then
      mouseinvert = find_after_keyword(line_to_parse, "Mouse Invert:")
      if mouseinvert ~= 1 then
         mouseinvert = 0
      end
   -- if we have all the above, go for mouse boundaries
   elseif mouseboundaries == nil then
      mouseboundaries = find_after_keyword(line_to_parse, "Boundary Limit:")
   -- if we have all the above, go for mouse colors
   elseif mousecolor == nil then
      mousecolors = find_4_numbers_after_keyword(line_to_parse, "Indicator Color:")
   -- all found - set the position to end of file
   else
      mousefile:seek("end")
   end
end

-----------------------------------------------------------------------
-- check if the file containing mouse references exists
-----------------------------------------------------------------------
filename_mouse = "mouse_script.cfg"
boolmousefileOK = cf.fileExists(filename_mouse, "data/", false)
boolscriptmouse = false

-- if file exists
if boolmousefileOK then
   -- reset all the variables to nil
   mousesensitivity = nil
   mousesensitivitymode = nil
   mousecontrolmode = nil
   mousedeadzone = nil
   mouseinvert = nil
   mouseboundaries = nil
   mousecolor = nil
   mousecolors = {}

   -- open the file in read only mode
   mousefile = cf.openFile(filename_mouse, "r", "data/")

   -- pick first line
   new_line = mousefile:read("*l")

   while new_line ~= nil do
      -- parse line and then jump on to the next line until end of file
      parse_mousefile_line(new_line,mousefile)
      new_line = mousefile:read("*l")
   end

   -- all data read.. time to close the file
   mousefile:close()

   -- if these three were found from the cfg file...
   if mousesensitivity and mousesensitivitymode and mousecontrolmode then

      -- set script to actually run, allow lua to override c coded controls
      boolscriptmouse = true
      ba.setControlMode(LUA_FULL_CONTROLS)

      -- make sure we have a number in deadzone var and not nil
      if mousedeadzone == nil then
         mousedeadzone = 0
      end

      -- define some variables
      mouse_reset_counter = nil
      missiontime_old = 0
      missiontime = nil

      -- if mouse invert was set to true, then invert the mouse (set it to '-1')
      -- otherwise define the multiplier as '1'
      if mouseinvert == 1 then
         mouseinvert = -1
      else
         mouseinvert = 1
      end

      -- check if boundaries are valid
      if mouseboundaries == nil then
         mouseboundaries = 1
      end

      -- check that defined control area is not larger than the actual area which can be controlled
      local max_limits
      max_limits = mousesensitivity * 2 + mousedeadzone * 2 + 10
      scr_width = gr.getScreenWidth()
      scr_height = gr.getScreenHeight()
      if max_limits > scr_width or max_limits > scr_height then
         ba.warning("Mouse control area defined to be larger than the window size, please resize")
      end

      --setup mouse bitmap
      mouse_bm = gr.loadTexture("mouse_ret_2.dds", true)
      if mouse_bm:isValid() then
         no_bitmap = false
         mouse_bm_w = mouse_bm:getWidth() / 2
         mouse_bm_h = mouse_bm:getHeight() / 2
      else
         no_bitmap = true
      end
   else
      ba.warning("Scripted mouse's init failed")
   end
else
   ba.warning("File '" .. filename_mouse .."' not found")
end

debugfile = cf.openFile("/home/eigenlambda/debugfile", "w")

]

$Application: FS2_Open
$State: GS_STATE_GAME_PLAY
$On Frame:

[

------------------------
------ functions -------
------------------------
function mouse_control_A(value, centervalue, axis)
   -- get the actual difference from centerpoint
   delta = value - centervalue

   -- default multiplier to +1
   multiplier = 1

   -- if we are handling negative values set multiplier to -1
   -- and make sure we deal only with positive values
   if delta < 0 then
      multiplier = -1
      delta = math.abs(delta)
   end

   -- deduct deadzone from the delta
   delta = delta - mousedeadzone
   if delta < 0 then
      delta = 0
   end

   -- scale delta from 0 to 1 according to defined sensitivity
   delta = delta / mousesensitivity
   if delta > 1 then
      delta = 1
   end

   -- if we do not have extreme values
   -- apply the defined sensitivity curve
   if (delta > 0) and (delta < 1) then
      delta = math.pow(delta, mousesensitivitymode)
   end

   -- apply the multiplier
   delta = delta * multiplier

   return delta
end
------------------------
function do_boundaries_check(limit)
   f_mouse_x = nil
   f_mouse_y = nil

   -- do we go over width limits
   if mouse_x <= limit then
      f_mouse_x = limit
   elseif mouse_x >= (scr_width - limit) then
      f_mouse_x = scr_width - limit
   end

   -- do we go over height limits
   if mouse_y <= limit then
      f_mouse_y = limit
   elseif mouse_y >= (scr_height - limit) then
      f_mouse_y = scr_height - limit
   end

   -- reset the cursor to the nearest boundary
   if f_mouse_x ~= nil or f_mouse_y ~= nil then
      if f_mouse_x and f_mouse_y then
         io.forceMousePosition(f_mouse_x, f_mouse_y)
      elseif f_mouse_x then
         io.forceMousePosition(f_mouse_x, mouse_y)
      else
         io.forceMousePosition(mouse_x, f_mouse_y)
      end
   end
end
------------------------
--- end of functions ---
------------------------

if boolscriptmouse == true then
   -- check for center button reset...
   if mouse_reset_counter == nil then
      mouse_center_x = io.getMouseX()
      mouse_center_y = io.getMouseY()
      mouse_reset_counter = 0
   end

   -- get frametime (used to increment the timer)
   frametime = ba.getFrametime()

   -- make sure missiontime and old missiontime exist
   if missiontime ~= nil then
      missiontime_old = missiontime
   end
   missiontime = mn.getMissionTime()

   -- if the setting changes make sure to reset it to false
   if io.MouseControlStatus == true then
      mouse_reset_on_end = true
      io.MouseControlStatus = false
   end

   -- check if missiontime is actually running or not
   if missiontime ~= missiontime_old then

      -- after pause ends (ie. missiontime starts running again)
      -- reset the mouse to the center
      if end_of_pause == true then
         io.forceMousePosition(mouse_center_x, mouse_center_y)
         end_of_pause = nil
      end

      -- increment the center mouse button down counter
      if io.isMouseButtonDown(MOUSE_MIDDLE_BUTTON) then
         mouse_reset_counter = mouse_reset_counter + frametime
      else
         mouse_reset_counter = 0
      end

      -- if center mouse button has been pressed long enough
      -- reset the mouse
      if mouse_reset_counter > 0.1 then
         io.forceMousePosition(mouse_center_x, mouse_center_y)
         mouse_reset_counter = 0
      end

      -- get control values
      mouse_x = io.getMouseX()
      mouse_y = io.getMouseY()
      controls = ba.getControlInfo()

      if mousecontrolmode == 1 or mousecontrolmode == 2 then

         -- make sure we aint gonna go off the boundaries...
         do_boundaries_check(mouseboundaries)
         -- end of boundaries check

if mousecontrolmode == 1 then
    -- get the actual control values
    current_h = mouse_control_A(mouse_x, mouse_center_x, "x")
    current_p = mouseinvert * mouse_control_A(mouse_y, mouse_center_y, "y")
   
    -- increment, not replace the existing values
    controls.Heading = current_h + controls.Heading
    controls.Pitch = current_p + controls.Pitch

    -- get draw position
    center_x = scr_width / 2
    center_y = scr_height / 2
    drawpos_x = center_x + (current_h * 300)
    drawpos_y = center_y + (current_p * 300)
    -- define the color of the cursor
    if mousecolors == nil then
       gr.setColor(0,64,220,196)
    else
       gr.setColor(mousecolors[1],mousecolors[2],mousecolors[3],mousecolors[4])
    end
   
    -- draw cursor
    if no_bitmap == true then
       gr.drawGradientLine(drawpos_x, drawpos_y, drawpos_x + 20, drawpos_y - 20)
       gr.drawGradientLine(drawpos_x, drawpos_y, drawpos_x - 20, drawpos_y + 20)
       gr.drawGradientLine(drawpos_x, drawpos_y, drawpos_x + 20, drawpos_y + 20)
       gr.drawGradientLine(drawpos_x, drawpos_y, drawpos_x - 20, drawpos_y - 20)
    else
       gr.drawMonochromeImage(mouse_bm, drawpos_x - mouse_bm_w, drawpos_y - mouse_bm_h, drawpos_x + mouse_bm_w, drawpos_y + mouse_bm_h)
    end
   
end

if mousecontrolmode == 2 then --airquake mouse mode
    debugfile:write("1")
    debugfile:flush()
    if inited == nil then
       plr = hv.Player
       cpos = plr.Position + plr.Orientation:rotateVector( ba.createVector(0,-15,-75) )
       ccam = gr.createCamera("ccam", cpos, plr.Orientation)
       gr.setCamera(ccam)
       inited = true
    end
    debugfile:write("2")
    debugfile:write("\n")
    debugfile:flush()
    if inited == true then
       -- the documentation says getVectorFromCoords gives you a normal
       -- vector, but the code says it's a normal vector + camera pos
       wanted_dir = gr.getVectorFromCoords(mouse_x, mouse_y) - cpos
       
       -- camera alway points towards where the mouse is
       -- just like any other first-person shoter
       delta = ccam.Orientation:rotateVector(wanted_dir):getOrientation()
       ccam:setOrientation(ccam.Orientation*delta)
       io.forceMousePosition(scr_width/2, scr_height/2)
       cpos = plr.Position + plr.Orientation:unrotateVector( ba.createVector(0,15,-50) )
       ccam:setPosition(cpos)
       
       gr.setColor(255,255,255)

       -- now let's try to make the player point the same direction
       local_wanted_dir = plr.Orientation:rotateVector(wanted_dir)
       local_wanted_dir = local_wanted_dir / local_wanted_dir:getMagnitude()
       -- compute the cross product with <0,0,1> by hand
       xdiff = local_wanted_dir.y
       ydiff = -local_wanted_dir.x
       -- the magnitude of the cross product is the sine of angle between the vectors
       theta = math.asin(math.sqrt(xdiff*xdiff + ydiff+ydiff))
       costheta = local_wanted_dir.z -- this was the dot product with <0,0,1>
       -- these are needed for everything that follows
       rotvel = plr.Physics.RotationalVelocity
       rvx = rotvel.x
       rvy = rotvel.y
       if costheta < 0 then
  -- obtuse angle between camera and ship forward
  if theta == 0 then
     -- pointing in the exact opposite direction
     -- so, go in the direction that we're already rotating, fast
     -- if we're not rotating, start as quickly as possible
     rvr = math.sqrt(rvx*rvx + rvy*rvy)
     if rvr == 0 then
controls.Heading = 1
controls.Pitch = 1
     else
controls.Heading = 5*rvy
controls.Pitch = 5*rvx
     end
  else
     controls.Heading = -5*ydiff
     controls.Pitch = -5*xdiff
  end
       else
  -- ok, heres some theory to explain what happens next
  -- next frame's rotvel is calculated as
  -- apply_physics( rotdamp, pi->desired_rotvel.xyz.x,
  --                pi->rotvel.xyz.x, sim_time,
  --                &new_vel.xyz.x, NULL );
  -- controls.Heading and controls.Pitch can have
  -- values between -1 and 1, from which desired_rotvel
  -- is calculated as that number times the maximum
  -- rotational speed around the axis in question.
  -- rotdamp is a single scalar that determines how fast
  -- rotvel becomes desired_rotvel by exponential decay:
  -- (rotvel - desired_rotvel)*exp(-frametime/rotdamp)
  maxrv = plr.Physics.RotationalVelocityMax
  maxrvx = maxrv.x
  maxrvy = maxrv.y
  rotdamp = plr.Physics.RotationalVelocityDamping
  frametime = ba.getFrametime()

  -- we need the sign of these for later calculations
  if rvx < 0 then
     rvxs = -1
  else
     rvxs = 1
  end
  if rvy < 0 then
     rvys = -1
  else
     rvys = 1
  end

  if xdiff < 0 then
     xsign = -1
  else
     if xdiff > 0 then
xsign = 1
     else
xsign = 0
     end
  end
  if ydiff < 0 then
     ysign = -1
  else
     if ydiff > 0 then
ysign = 1
     else
ysign = 0
     end
  end


  -- i'm not sure about this part
  xangle = math.asin(xdiff)
  yangle = math.asin(ydiff)

  -- so now we calculate how long it will take to center the controls
  -- using the integral of rotational momentum assuming full acceleration
  -- ignoring the exponential term, which should go away quickly enough
  -- i hope
  timetocenterx  = xsign*(xangle + rotdamp*(xsign + rvx))
  timetocentery  = ysign*(yangle + rotdamp*(ysign + rvy))
 
  -- how quickly can we stop by applying full reverse?
  -- this is much easier, so it can be exact
  timeto0x = rotdamp*math.log(-rvxs*maxrvx/(-rvxs*maxrvx+rvx))
  timeto0y = rotdamp*math.log(-rvys*maxrvy/(-rvys*maxrvy+rvy))

  -- rotate unless we're going to overshoot
  -- if so, stop rotating as quickly as possible
  if yangle*ysign > .2 or timetocentery > timeto0y then
     controls.Heading = -ysign
  else
     x = math.exp(-frametime/rotdamp)
     forceto0 = rvy*x/(1-x) / maxrvy
     controls.Heading = -forceto0
  end
  if xangle*xsign > .1 or timetocenterx > timeto0x then
     controls.Pitch = -xsign
  else
     x = math.exp(-frametime/rotdamp)
     forceto0 = rvx*x/(1-x) / maxrvx
     controls.Pitch = -forceto0
  end
       end


       -- now ensure that the ship is banked correctly
       -- in the future, this should capture whatever keys the player
       -- uses to bank and adjust the camera first with them
       up = ba.createVector(0,1,0)
       camup = ccam.Orientation:rotateVector(up)
       plrup = plr.Orientation:rotateVector(up)
       should_be_forward = camup:getCrossProduct(plrup)
       controls.Bank = should_be_forward.z

       -- lastly, fix the HUD
       -- first kill the annoying gauges
       hu.setHUDGaugeColor( 9,0,0,0,0) --reticle center
       hu.setHUDGaugeColor(23,0,0,0,0) --target mini icon
       hu.setHUDGaugeColor(19,0,0,0,0) --threat gauge
       hu.setHUDGaugeColor( 6,0,0,0,0) --throttle gauge
       hu.setHUDGaugeColor(20,0,0,0,0) --afterburner energy
       hu.setHUDGaugeColor(21,0,0,0,0) --weapons energy
       -- then replace them
       gaugey = math.floor(.6*scr_height)
       gr.setColor(200, 200, 0, 100)
       energy_fraction = plr.WeaponEnergyLeft/plr.WeaponEnergyLeft
       gr.drawRectangle(0, gaugey+1, 100*energy_fraction, gaugey+9)

       burn_fraction = plr.AfterburnerFuelLeft/plr.AfterburnerFuelMax
       gr.drawRectangle(0, gaugey+11, 100*burn_fraction, gaugey+19)
       speed = math.floor(plr.Physics:getForwardSpeed()+.5)
       gr.drawString(speed, 100, gaugey+11)
       if plr.PrimaryTriggerDown then
  gr.setColor(100, 0, 0, 64)
  gr.drawCircle(5, 105, gaugey+5)
       end

       -- make aim indicators
       vec300 = ba.createVector(0,0,300)
       vec1000 = ba.createVector(0,0,1000)
       aim300 = plr.Position + plr.Orientation:unrotateVector(vec300)
       aim1000 = plr.Position + plr.Orientation:unrotateVector(vec1000)
       x,y = aim1000:getScreenCoords()
       gr.setColor(150,150,150,150)
       if x ~= nil and x ~= false then
  gr.drawLine(x+4,y+4,x-4,y-4)
  gr.drawLine(x+4,y-4,x-4,y+4)
       end
       x,y = aim300:getScreenCoords()
       if x ~= nil and x ~= false then
  gr.drawRectangle(x-6,y-6,x+6,y+6,false)
       end

       -- now tell the hud to draw
       hu.HUDDrawn = true
       debugfile:write("5")
       debugfile:flush()
    end
end
      end
   else
      end_of_pause = true
   end
end

]

$Application: FS2_Open
$On Mission End:

[

boolscriptmouse = false
ba.setControlMode(NORMAL_CONTROLS)
if mouse_reset_on_end == true then
   io.MouseControlStatus = true
end

]

#End
Title: Re: hate how the mouse works? have i got the script for you!
Post by: Lukeskywalkie on April 10, 2010, 12:49:52 pm
Scratch my previous question - I just took the tbm out from one of the blue planet vps and added it to my other mod directories. The velocity indicator is mine!
Title: Re: hate how the mouse works? have i got the script for you!
Post by: Commander Zane on April 10, 2010, 12:51:57 pm
I'm not 100% sure how to get this script set up to play around with, I have one of the earlier ones on my folder so I have stuff like the .cfg and a .tbm, or perhaps I'm just not noticing what's supposed to change. Could someone who uses the script give me a comparison of how the ship flies?

Edit: Before someone tries quoting the Privateer 2 post, I haven't played that so I don't know what that's like.
Title: Re: hate how the mouse works? have i got the script for you!
Post by: eigenlambda on April 11, 2010, 03:17:06 am
OK!  I have this working properly now.  It's responsive, stable, and good enough to shoot down Maras with HL-7s on a Medusa.  But not quite good enough to shoot down Dragons with HL-7s on a HercII (actually, i probably could of gotten him if I'd waited around long enough.  Also gotten killed.  You know you're expected to jump out when the game spawns 6 Dragons on top of you.)

Code: [Select]
#Conditional Hooks

$Application: FS2_Open
$On Mission Start:

[

-- couple of functions to make things go easier
function find_after_keyword(line_to_parse, keyword)

   -- make sure both strings are in lower case
   line_to_parse = line_to_parse:lower()
   keyword = keyword:lower()

   -- find any instances of the keyword
   key_s, key_e = line_to_parse:find(keyword)

   -- if we cant find a thing
   if key_s == nil then
      return nil
   end

   result = line_to_parse:match("%d+", e_key)
   return tonumber(result)
end

function find_4_numbers_after_keyword(line_to_parse, keyword)

   -- make sure both strings are in lower case
   line_to_parse = line_to_parse:lower()
   keyword = keyword:lower()

   -- find any instances of the keyword
   key_s, key_e = line_to_parse:find(keyword)

   -- if we cant find a thing
   if key_s == nil then
      return nil
   end

   -- make sure r is an array
   r = {}
   i = 1

   -- stuff the array
   for p in line_to_parse:gmatch("%d+") do
      r[i] = p
      r[i] = tonumber(r[i])
      if r[i] > 255 then
         r[i] = 255
      elseif r[i] < 0 then
         r[i] = 0
      end
      i = i + 1
   end
   return r
end

function parse_mousefile_line(line_to_parse, mousefile)
   -- check for sensitivity
   if mousesensitivity == nil then
      mousesensitivity = find_after_keyword(line_to_parse, "Sensitivity:")
      if mousesensitivity ~= nil then
         if mousesensitivity < 100 then
            mousesensitivity = 100
         elseif mousesensitivity > 600 then
            mousesensitivity = 600
         end
      end
   -- if we already have sensitivity, check for sensitivity curve
   elseif mousesensitivitymode == nil then
      mousesensitivitymode = find_after_keyword(line_to_parse, "Sensitivity Curve:")
      if mousesensitivitymode ~= nil then
         if mousesensitivitymode < 0 then
            mousesensitivitymode = 1
         elseif mousesensitivitymode > 6 then
            mousesensitivitymode = 6
         end
      end
   -- if we have all the above, go for control mode
   elseif mousecontrolmode == nil then
      mousecontrolmode = find_after_keyword(line_to_parse, "Control Mode:")
   -- if we have all the above, go for deadzone
   elseif mousedeadzone == nil then
      mousedeadzone = find_after_keyword(line_to_parse, "Deadzone:")
      if mousedeadzone ~= nil then
         if mousedeadzone < 0 then
            mousedeadzone = 0
         end
      end
   -- if we have all the above, go for mouse invert
   elseif mouseinvert == nil then
      mouseinvert = find_after_keyword(line_to_parse, "Mouse Invert:")
      if mouseinvert ~= 1 then
         mouseinvert = 0
      end
   -- if we have all the above, go for mouse boundaries
   elseif mouseboundaries == nil then
      mouseboundaries = find_after_keyword(line_to_parse, "Boundary Limit:")
   -- if we have all the above, go for mouse colors
   elseif mousecolor == nil then
      mousecolors = find_4_numbers_after_keyword(line_to_parse, "Indicator Color:")
   -- all found - set the position to end of file
   else
      mousefile:seek("end")
   end
end

-----------------------------------------------------------------------
-- check if the file containing mouse references exists
-----------------------------------------------------------------------
filename_mouse = "mouse_script.cfg"
boolmousefileOK = cf.fileExists(filename_mouse, "data/", false)
boolscriptmouse = false

-- if file exists
if boolmousefileOK then
   -- reset all the variables to nil
   mousesensitivity = nil
   mousesensitivitymode = nil
   mousecontrolmode = nil
   mousedeadzone = nil
   mouseinvert = nil
   mouseboundaries = nil
   mousecolor = nil
   mousecolors = {}

   -- open the file in read only mode
   mousefile = cf.openFile(filename_mouse, "r", "data/")

   -- pick first line
   new_line = mousefile:read("*l")

   while new_line ~= nil do
      -- parse line and then jump on to the next line until end of file
      parse_mousefile_line(new_line,mousefile)
      new_line = mousefile:read("*l")
   end

   -- all data read.. time to close the file
   mousefile:close()

   -- if these three were found from the cfg file...
   if mousesensitivity and mousesensitivitymode and mousecontrolmode then

      -- set script to actually run, allow lua to override c coded controls
      boolscriptmouse = true
      ba.setControlMode(LUA_FULL_CONTROLS)

      -- make sure we have a number in deadzone var and not nil
      if mousedeadzone == nil then
         mousedeadzone = 0
      end

      -- define some variables
      mouse_reset_counter = nil
      missiontime_old = 0
      missiontime = nil

      -- if mouse invert was set to true, then invert the mouse (set it to '-1')
      -- otherwise define the multiplier as '1'
      if mouseinvert == 1 then
         mouseinvert = -1
      else
         mouseinvert = 1
      end

      -- check if boundaries are valid
      if mouseboundaries == nil then
         mouseboundaries = 1
      end

      -- check that defined control area is not larger than the actual area which can be controlled
      local max_limits
      max_limits = mousesensitivity * 2 + mousedeadzone * 2 + 10
      scr_width = gr.getScreenWidth()
      scr_height = gr.getScreenHeight()
      if max_limits > scr_width or max_limits > scr_height then
         ba.warning("Mouse control area defined to be larger than the window size, please resize")
      end

      --setup mouse bitmap
      mouse_bm = gr.loadTexture("mouse_ret_2.dds", true)
      if mouse_bm:isValid() then
         no_bitmap = false
         mouse_bm_w = mouse_bm:getWidth() / 2
         mouse_bm_h = mouse_bm:getHeight() / 2
      else
         no_bitmap = true
      end
   else
      ba.warning("Scripted mouse's init failed")
   end
else
   ba.warning("File '" .. filename_mouse .."' not found")
end

]

$Application: FS2_Open
$State: GS_STATE_GAME_PLAY
$On Frame:

[

------------------------
------ functions -------
------------------------
function mouse_control_A(value, centervalue, axis)
   -- get the actual difference from centerpoint
   delta = value - centervalue

   -- default multiplier to +1
   multiplier = 1

   -- if we are handling negative values set multiplier to -1
   -- and make sure we deal only with positive values
   if delta < 0 then
      multiplier = -1
      delta = math.abs(delta)
   end

   -- deduct deadzone from the delta
   delta = delta - mousedeadzone
   if delta < 0 then
      delta = 0
   end

   -- scale delta from 0 to 1 according to defined sensitivity
   delta = delta / mousesensitivity
   if delta > 1 then
      delta = 1
   end

   -- if we do not have extreme values
   -- apply the defined sensitivity curve
   if (delta > 0) and (delta < 1) then
      delta = math.pow(delta, mousesensitivitymode)
   end

   -- apply the multiplier
   delta = delta * multiplier

   return delta
end
------------------------
function do_boundaries_check(limit)
   f_mouse_x = nil
   f_mouse_y = nil

   -- do we go over width limits
   if mouse_x <= limit then
      f_mouse_x = limit
   elseif mouse_x >= (scr_width - limit) then
      f_mouse_x = scr_width - limit
   end

   -- do we go over height limits
   if mouse_y <= limit then
      f_mouse_y = limit
   elseif mouse_y >= (scr_height - limit) then
      f_mouse_y = scr_height - limit
   end

   -- reset the cursor to the nearest boundary
   if f_mouse_x ~= nil or f_mouse_y ~= nil then
      if f_mouse_x and f_mouse_y then
         io.forceMousePosition(f_mouse_x, f_mouse_y)
      elseif f_mouse_x then
         io.forceMousePosition(f_mouse_x, mouse_y)
      else
         io.forceMousePosition(mouse_x, f_mouse_y)
      end
   end
end
------------------------
--- end of functions ---
------------------------

if boolscriptmouse == true then
   -- check for center button reset...
   if mouse_reset_counter == nil then
      mouse_center_x = io.getMouseX()
      mouse_center_y = io.getMouseY()
      mouse_reset_counter = 0
   end

   -- get frametime (used to increment the timer)
   frametime = ba.getFrametime()

   -- make sure missiontime and old missiontime exist
   if missiontime ~= nil then
      missiontime_old = missiontime
   end
   missiontime = mn.getMissionTime()

   -- if the setting changes make sure to reset it to false
   if io.MouseControlStatus == true then
      mouse_reset_on_end = true
      io.MouseControlStatus = false
   end

   -- check if missiontime is actually running or not
   if missiontime ~= missiontime_old then

      -- after pause ends (ie. missiontime starts running again)
      -- reset the mouse to the center
      if end_of_pause == true then
         io.forceMousePosition(mouse_center_x, mouse_center_y)
         end_of_pause = nil
      end

      -- increment the center mouse button down counter
      if io.isMouseButtonDown(MOUSE_MIDDLE_BUTTON) then
         mouse_reset_counter = mouse_reset_counter + frametime
      else
         mouse_reset_counter = 0
      end

      -- if center mouse button has been pressed long enough
      -- reset the mouse
      if mouse_reset_counter > 0.1 then
         io.forceMousePosition(mouse_center_x, mouse_center_y)
         mouse_reset_counter = 0
      end

      -- get control values
      mouse_x = io.getMouseX()
      mouse_y = io.getMouseY()
      controls = ba.getControlInfo()

      if mousecontrolmode == 1 or mousecontrolmode == 2 then

         -- make sure we aint gonna go off the boundaries...
         do_boundaries_check(mouseboundaries)
         -- end of boundaries check

if mousecontrolmode == 1 then
    -- get the actual control values
    current_h = mouse_control_A(mouse_x, mouse_center_x, "x")
    current_p = mouseinvert * mouse_control_A(mouse_y, mouse_center_y, "y")
   
    -- increment, not replace the existing values
    controls.Heading = current_h + controls.Heading
    controls.Pitch = current_p + controls.Pitch

    -- get draw position
    center_x = scr_width / 2
    center_y = scr_height / 2
    drawpos_x = center_x + (current_h * 300)
    drawpos_y = center_y + (current_p * 300)
    -- define the color of the cursor
    if mousecolors == nil then
       gr.setColor(0,64,220,196)
    else
       gr.setColor(mousecolors[1],mousecolors[2],mousecolors[3],mousecolors[4])
    end
   
    -- draw cursor
    if no_bitmap == true then
       gr.drawGradientLine(drawpos_x, drawpos_y, drawpos_x + 20, drawpos_y - 20)
       gr.drawGradientLine(drawpos_x, drawpos_y, drawpos_x - 20, drawpos_y + 20)
       gr.drawGradientLine(drawpos_x, drawpos_y, drawpos_x + 20, drawpos_y + 20)
       gr.drawGradientLine(drawpos_x, drawpos_y, drawpos_x - 20, drawpos_y - 20)
    else
       gr.drawMonochromeImage(mouse_bm, drawpos_x - mouse_bm_w, drawpos_y - mouse_bm_h, drawpos_x + mouse_bm_w, drawpos_y + mouse_bm_h)
    end
   
end

if mousecontrolmode == 2 then --airquake mouse mode
    if inited == nil then
       plr = hv.Player
       cpos = plr.Position + plr.Orientation:rotateVector( ba.createVector(0,-15,-75) )
       ccam = gr.createCamera("ccam", cpos, plr.Orientation)
       gr.setCamera(ccam)
       inited = true
    end
    if inited == true then
       -- the documentation says getVectorFromCoords gives you a normal
       -- vector, but the code says it's a normal vector + camera pos
       wanted_dir = gr.getVectorFromCoords(mouse_x, mouse_y) - cpos
       
       -- camera alway points towards where the mouse is
       -- just like any other first-person shoter
       delta = ccam.Orientation:rotateVector(wanted_dir):getOrientation()
       ccam:setOrientation(ccam.Orientation*delta)
       io.forceMousePosition(scr_width/2, scr_height/2)
       cpos = plr.Position + ccam.Orientation:unrotateVector( ba.createVector(0,15,-50) )
       ccam:setPosition(cpos)
       
       gr.setColor(255,255,255)

       -- now let's try to make the player point the same direction
       local_wanted_dir = plr.Orientation:rotateVector(wanted_dir)
       local_wanted_dir = local_wanted_dir / local_wanted_dir:getMagnitude()
       -- compute the cross product with <0,0,1> by hand
       xdiff = local_wanted_dir.y
       ydiff = -local_wanted_dir.x
       -- the magnitude of the cross product is the sine of angle between the vectors
       theta = math.asin(math.sqrt(xdiff*xdiff + ydiff+ydiff))
       costheta = local_wanted_dir.z -- this was the dot product with <0,0,1>
       -- these are needed for everything that follows
       rotvel = plr.Physics.RotationalVelocity
       rvx = rotvel.x
       rvy = rotvel.y
       if costheta < 0 then
  -- obtuse angle between camera and ship forward
  if theta == 0 then
     -- pointing in the exact opposite direction
     -- so, go in the direction that we're already rotating, fast
     -- if we're not rotating, start as quickly as possible
     rvr = math.sqrt(rvx*rvx + rvy*rvy)
     if rvr == 0 then
controls.Heading = 1
controls.Pitch = 1
     else
controls.Heading = 5*rvy
controls.Pitch = 5*rvx
     end
  else
     controls.Heading = -5*ydiff
     controls.Pitch = -5*xdiff
  end
       else
  -- ok, heres some theory to explain what happens next
  -- next frame's rotvel is calculated as
  -- apply_physics( rotdamp, pi->desired_rotvel.xyz.x,
  --                pi->rotvel.xyz.x, sim_time,
  --                &new_vel.xyz.x, NULL );
  -- controls.Heading and controls.Pitch can have
  -- values between -1 and 1, from which desired_rotvel
  -- is calculated as that number times the maximum
  -- rotational speed around the axis in question.
  -- rotdamp is a single scalar that determines how fast
  -- rotvel becomes desired_rotvel by exponential decay:
  -- (rotvel - desired_rotvel)*exp(-frametime/rotdamp)
  maxrv = plr.Physics.RotationalVelocityMax
  maxrvx = maxrv.x
  maxrvy = maxrv.y
  rotdamp = plr.Physics.RotationalVelocityDamping
  frametime = ba.getFrametime()
  gr.drawString(1/frametime, 0, 0)

  -- we need the sign of these for later calculations
  if rvx < 0 then
     rvxs = -1
  else
     rvxs = 1
  end
  if rvy < 0 then
     rvys = -1
  else
     rvys = 1
  end

  if xdiff < 0 then
     xsign = -1
  else
     if xdiff > 0 then
xsign = 1
     else
xsign = 0
     end
  end
  if ydiff < 0 then
     ysign = -1
  else
     if ydiff > 0 then
ysign = 1
     else
ysign = 0
     end
  end


  -- the angle is the inverse sine of the cross product
  xangle = math.asin(xdiff)
  yangle = math.asin(ydiff)
 
  -- how quickly can we stop by applying full reverse?
  timeto0x = rotdamp*math.log(-rvxs*maxrvx/(-rvxs*maxrvx+rvx))
  timeto0y = rotdamp*math.log(-rvys*maxrvy/(-rvys*maxrvy+rvy))
 
  -- how far do we go until we stop
  -- integral of rotational velocity from now until timeto0x from now
  -- assuming full acceleration against the direction we're going in
  angleto0x = -rvxs*maxrvx*timeto0x + rotdamp*(-rvxs*maxrvx*timeto0x-rvx)*(math.exp(-timeto0x/rotdamp)-1)
  angleto0y = -rvys*maxrvy*timeto0y + rotdamp*(-rvys*maxrvy*timeto0y-rvy)*(math.exp(-timeto0y/rotdamp)-1)


  -- rotate unless we're going to overshoot
  -- if so, stop rotating as quickly as possible
  xfactor = math.exp(-frametime/rotdamp)
  if yangle*ysign > angleto0y*ysign then
     controls.Heading = -ysign
  else
     forceto0 = rvy*xfactor/(1-xfactor) / maxrvy
     controls.Heading = -forceto0
  end
  if xangle*xsign > angleto0x*xsign then
     controls.Pitch = -xsign
  else
     forceto0 = rvx*xfactor/(1-xfactor) / maxrvx
     controls.Pitch = -forceto0
  end
       end


       -- now ensure that the ship is banked correctly
       -- in the future, this should capture whatever keys the player
       -- uses to bank and adjust the camera first with them
       up = ba.createVector(0,1,0)
       camup = ccam.Orientation:rotateVector(up)
       plrup = plr.Orientation:rotateVector(up)
       should_be_forward = camup:getCrossProduct(plrup)
       controls.Bank = should_be_forward.z

       -- lastly, fix the HUD
       -- first kill the annoying gauges
       hu.setHUDGaugeColor( 9,0,0,0,0) --reticle center
       hu.setHUDGaugeColor(23,0,0,0,0) --target mini icon
       hu.setHUDGaugeColor(19,0,0,0,0) --threat gauge
       hu.setHUDGaugeColor( 6,0,0,0,0) --throttle gauge
       hu.setHUDGaugeColor(20,0,0,0,0) --afterburner energy
       hu.setHUDGaugeColor(21,0,0,0,0) --weapons energy
       -- then replace them
       gaugey = math.floor(.6*scr_height)
       gr.setColor(200, 200, 0, 100)
       energy_fraction = plr.WeaponEnergyLeft/plr.WeaponEnergyLeft
       gr.drawRectangle(0, gaugey+1, 100*energy_fraction, gaugey+9)

       burn_fraction = plr.AfterburnerFuelLeft/plr.AfterburnerFuelMax
       gr.drawRectangle(0, gaugey+11, 100*burn_fraction, gaugey+19)
       speed = math.floor(plr.Physics:getForwardSpeed()+.5)
       gr.drawString(speed, 100, gaugey+11)
       if plr.PrimaryTriggerDown then
  gr.setColor(100, 0, 0, 64)
  gr.drawCircle(5, 105, gaugey+5)
       end

       -- make aim indicators
       vec300 = ba.createVector(0,0,300)
       vec1000 = ba.createVector(0,0,1000)
       aim300 = plr.Position + plr.Orientation:unrotateVector(vec300)
       aim1000 = plr.Position + plr.Orientation:unrotateVector(vec1000)
       x,y = aim1000:getScreenCoords()
       gr.setColor(150,150,150,150)
       if x ~= nil and x ~= false then
  gr.drawLine(x+4,y+4,x-4,y-4)
  gr.drawLine(x+4,y-4,x-4,y+4)
       end
       x,y = aim300:getScreenCoords()
       if x ~= nil and x ~= false then
  gr.drawRectangle(x-6,y-6,x+6,y+6,false)
       end

       -- now tell the hud to draw
       hu.HUDDrawn = true
    end
end
      end
   else
      end_of_pause = true
   end
end

]

$Application: FS2_Open
$On Mission End:

[

boolscriptmouse = false
ba.setControlMode(NORMAL_CONTROLS)
if mouse_reset_on_end == true then
   io.MouseControlStatus = true
end
if mousecontrolmode == 2 then
   inited = nil
end

]

#End
Title: Re: hate how the mouse works? have i got the script for you!
Post by: eigenlambda on May 02, 2010, 11:00:10 pm
To install this script, all you need to do is create a new folder in your fs2 folder, call it like aqmouse or something, then put a new folder in that called data, and a folder in that called tables, and finally put the following code in a file called aqmouse-sct.tbm or something.  To use this script, launch fs2 as usual, but include aqmouse or whatever you called the folder in your -mod directive.

Here's the current version:
Code: [Select]
#Conditional Hooks

$Application: FS2_Open
$On Mission Start:

[

ba.setControlMode(LUA_FULL_CONTROLS)
inited = false
function sign(n)
   if n>0 then
      return 1
   else
      if n<0 then
return -1
      else
return 0
      end
   end
end

function signpositive0(n)
   if n >= 0 then
      return 1
   else
      return 0
   end
end

debugmode = false

]

$Application: FS2_Open
$State: GS_STATE_GAME_PLAY
$On Frame:

[

if true then
   -- check for center button reset...
   if mouse_reset_counter == nil then
      mouse_center_x = io.getMouseX()
      mouse_center_y = io.getMouseY()
      mouse_reset_counter = 0
   end

   -- get frametime (used to increment the timer)
   frametime = ba.getFrametime()

   -- make sure missiontime and old missiontime exist
   if missiontime ~= nil then
      missiontime_old = missiontime
   end
   missiontime = mn.getMissionTime()

   -- if the setting changes make sure to reset it to false
   if io.MouseControlStatus == true then
      mouse_reset_on_end = true
      io.MouseControlStatus = false
   end

   -- check if missiontime is actually running or not
   if missiontime ~= missiontime_old then

      -- after pause ends (ie. missiontime starts running again)
      -- reset the mouse to the center
      if end_of_pause == true then
         io.forceMousePosition(mouse_center_x, mouse_center_y)
         end_of_pause = nil
      end

      -- get control values
      mouse_x = io.getMouseX()
      mouse_y = io.getMouseY()
      controls = ba.getControlInfo()
     
      if not inited then
plr = hv.Player
cpos = plr.Position + plr.Orientation:rotateVector( ba.createVector(0,-15,-75) )
ccam = gr.createCamera("ccam", cpos, plr.Orientation)
gr.setCamera(ccam)
inited = true
scr_width = gr.getScreenWidth()
scr_height = gr.getScreenHeight()
      end
      if inited then
-- the documentation says getVectorFromCoords gives you a normal
-- vector, but the code says it's a normal vector + camera pos
wanted_dir = gr.getVectorFromCoords(mouse_x, mouse_y) - cpos
       
-- camera alway points towards where the mouse is
-- just like any other first-person shoter
delta = ccam.Orientation:rotateVector(wanted_dir):getOrientation()
ccam:setOrientation(ccam.Orientation*delta)
io.forceMousePosition(scr_width/2, scr_height/2)
         clocate = ba.createVector(0,15,-50)
cpos = plr.Position + ccam.Orientation:unrotateVector(clocate)
ccam:setPosition(cpos)

gr.setColor(255,255,255)

-- now let's try to make the player point the same direction
local_wanted_dir = plr.Orientation:rotateVector(wanted_dir)
local_wanted_dir = local_wanted_dir / local_wanted_dir:getMagnitude()
-- compute the cross product with <0,0,1> by hand
xdiff = local_wanted_dir.y
ydiff = -local_wanted_dir.x
-- the magnitude of the cross product is the sine of angle between the vectors
theta = math.asin(math.sqrt(xdiff*xdiff + ydiff+ydiff))
costheta = local_wanted_dir.z -- this was the dot product with <0,0,1>
-- these are needed for everything that follows
rotvel = plr.Physics.RotationalVelocity
rvx = rotvel.x
rvy = rotvel.y
if costheta < 0 then
    -- obtuse angle between camera and ship forward
    if theta == 0 then
       -- pointing in the exact opposite direction
       -- so, go in the direction that we're already rotating, fast
       -- if we're not rotating, start as quickly as possible
       rvr = math.sqrt(rvx*rvx + rvy*rvy)
       if rvr == 0 then
  controls.Heading = 1
  controls.Pitch = 1
       else
  controls.Heading = 5*rvy
  controls.Pitch = 5*rvx
       end
    else
       controls.Heading = -5*ydiff
       controls.Pitch = -5*xdiff
    end
else
    -- ok, heres some theory to explain what happens next
    -- next frame's rotvel is calculated as
    -- apply_physics( rotdamp, pi->desired_rotvel.xyz.x,
    --                pi->rotvel.xyz.x, sim_time,
    --                &new_vel.xyz.x, NULL );
    -- controls.Heading and controls.Pitch can have
    -- values between -1 and 1, from which desired_rotvel
    -- is calculated as that number times the maximum
    -- rotational speed around the axis in question.
    -- rotdamp is a single scalar that determines how fast
    -- rotvel becomes desired_rotvel by exponential decay:
    -- (rotvel - desired_rotvel)*exp(-frametime/rotdamp)
    maxrv = plr.Physics.RotationalVelocityMax
    maxrvx = maxrv.x
    maxrvy = maxrv.y
    rotdamp = plr.Physics.RotationalVelocityDamping
    frametime = ba.getFrametime()
    gr.drawString(1/frametime, 0, 0)
   
    -- we need the sign of these for later calculations
    rvxs = sign(rvx)
    rvys = sign(rvy)
    xsign = sign(xdiff)
    ysign = sign(ydiff)
   
    -- the angle is the inverse sine of the cross product
    xangle = math.asin(xdiff)
    yangle = math.asin(ydiff)

    -- how quickly can we stop by applying full reverse?
    timeto0x = rotdamp*math.log(-rvxs*maxrvx/(-rvxs*maxrvx+rvx))
    timeto0y = rotdamp*math.log(-rvys*maxrvy/(-rvys*maxrvy+rvy))

    -- x ~= x is how you check for NaN in lua
    -- we will get NaN as math.log(0) when rvx == 0, so rvxs == 0
    if timeto0x ~= timeto0x then
       timeto0x = 0
    end
    if timeto0y ~= timeto0y then
       timeto0y = 0
    end

    -- how far do we go until we stop
    -- integral of rotational velocity from now until timeto0x from now
    -- assuming full acceleration against the direction we're going in
    angleto0x = -rvxs*maxrvx*timeto0x + rotdamp*(-rvxs*maxrvx*timeto0x-rvx)*(math.exp(-timeto0x/rotdamp)-1)
    angleto0y = -rvys*maxrvy*timeto0y + rotdamp*(-rvys*maxrvy*timeto0y-rvy)*(math.exp(-timeto0y/rotdamp)-1)
   
    if debugmode then
       gr.drawString(yangle, 300,300)
       gr.drawString(timeto0y, 200, 310)
       gr.drawString(angleto0y, 300, 310)
    end
    -- calculate how fast to rotate
    xfactor = math.exp(-frametime/rotdamp)
    if yangle*ysign > angleto0y*ysign then
       controls.Heading = -(rvy - (yangle-rvy*frametime)/(rotdamp*(xfactor-1)))/maxrvy
       if debugmode then
  gr.drawString(controls.Heading, 300,320)
       end
    else
       forceto0 = rvy*xfactor/(1-xfactor) / maxrvy
       controls.Heading = -forceto0
       if debugmode then
  gr.drawString(controls.Heading, 300, 320)
       end
    end
    if xangle*xsign > angleto0x*xsign then
       controls.Pitch = -(rvx - (xangle-rvx*frametime)/(rotdamp*(xfactor-1)))/maxrvx
    else
       forceto0 = rvx*xfactor/(1-xfactor) / maxrvx
       controls.Pitch = -forceto0
    end
end


-- now ensure that the ship is banked correctly
-- in the future, this should capture whatever keys the player
-- uses to bank and adjust the camera first with them
up = ba.createVector(0,1,0)
camup = ccam.Orientation:rotateVector(up)
plrup = plr.Orientation:rotateVector(up)
should_be_forward = camup:getCrossProduct(plrup)
controls.Bank = should_be_forward.z

-- lastly, fix the HUD
-- first kill the annoying gauges
hu.setHUDGaugeColor( 9,0,0,0,0) --reticle center
hu.setHUDGaugeColor(23,0,0,0,0) --target mini icon
hu.setHUDGaugeColor(19,0,0,0,0) --threat gauge
hu.setHUDGaugeColor( 6,0,0,0,0) --throttle gauge
hu.setHUDGaugeColor(20,0,0,0,0) --afterburner energy
hu.setHUDGaugeColor(21,0,0,0,0) --weapons energy
-- then replace them
gaugey = math.floor(.6*scr_height)
gr.setColor(200, 200, 0, 100)
energy_fraction = plr.WeaponEnergyLeft/plr.WeaponEnergyMax
gr.drawRectangle(0, gaugey+1, 100*energy_fraction, gaugey+9)

burn_fraction = plr.AfterburnerFuelLeft/plr.AfterburnerFuelMax
gr.drawRectangle(0, gaugey+11, 100*burn_fraction, gaugey+19)
speed = math.floor(plr.Physics:getForwardSpeed()+.5)
gr.drawString(speed, 100, gaugey+11)
if plr.PrimaryTriggerDown then
    gr.setColor(100, 0, 0, 64)
    gr.drawCircle(5, 105, gaugey+5)
end

-- make aim indicators
vec100 = ba.createVector(0,0,100)
vec300 = ba.createVector(0,0,300)
vec1000 = ba.createVector(0,0,1000)
aim100 = plr.Position + plr.Orientation:unrotateVector(vec100)
aim300 = plr.Position + plr.Orientation:unrotateVector(vec300)
aim1000 = plr.Position + plr.Orientation:unrotateVector(vec1000)
x,y = aim1000:getScreenCoords()
gr.setColor(150,150,150,150)
if x ~= nil and x ~= false then
    gr.drawLine(x+4,y+4,x-4,y-4)
    gr.drawLine(x+4,y-4,x-4,y+4)
end
x,y = aim300:getScreenCoords()
if x ~= nil and x ~= false then
    gr.drawRectangle(x-6,y-6,x+6,y+6,false)
end
x,y = aim100:getScreenCoords()
if x ~= nil and x ~= false then
    gr.drawLine(x-9,y-9,x-6,y-9,false)
    gr.drawLine(x-9,y-9,x-9,y-6,false)
    gr.drawLine(x-9,y+9,x-6,y+9,false)
    gr.drawLine(x-9,y+9,x-9,y+6,false)
    gr.drawLine(x+9,y-9,x+6,y-9,false)
    gr.drawLine(x+9,y-9,x+9,y-6,false)
    gr.drawLine(x+9,y+9,x+6,y+9,false)
    gr.drawLine(x+9,y+9,x+9,y+6,false)
end

-- now tell the hud to draw
hu.HUDDrawn = true
      end
   else
      end_of_pause = true
   end
end

]

$Application: FS2_Open
$On Mission End:

[

boolscriptmouse = false
ba.setControlMode(NORMAL_CONTROLS)
if mouse_reset_on_end == true then
   io.MouseControlStatus = true
end
inited = false -- this line should not be needed

]

#End

Good luck and happy hunting.
Title: Re: hate how the mouse works? have i got the script for you!
Post by: Commander Zane on May 03, 2010, 11:45:02 am
What about FreeSpace 2\data\tables\[Filename]? I want it to apply on everything.

There's also a shield script that I saw but the download is down, does anyone have that and can upload it again?
Title: Re: hate how the mouse works? have i got the script for you!
Post by: jr2 on May 03, 2010, 11:53:28 am
This one?

http://www.hard-light.net/forums/index.php?topic=67712.0
Title: Re: hate how the mouse works? have i got the script for you!
Post by: Commander Zane on May 03, 2010, 11:57:19 am
Yeah.
Title: Re: hate how the mouse works? have i got the script for you!
Post by: eigenlambda on May 03, 2010, 12:34:50 pm
What about FreeSpace 2\data\tables\[Filename]? I want it to apply on everything.

That should work, but for some reason it doesn't work for some people :/
Title: Re: hate how the mouse works? have i got the script for you!
Post by: The E on May 03, 2010, 12:37:26 pm
Also, non-retail tbls in the standard data folder are a bad idea in general. Using a separate mod folder, even for something as seemingly inconsequential as this, is recommended.
Title: Re: hate how the mouse works? have i got the script for you!
Post by: Commander Zane on May 08, 2010, 01:08:29 am
Okay, so what does this do other than turn off the entire reticle on my HUD?
Title: Re: hate how the mouse works? have i got the script for you!
Post by: eigenlambda on May 08, 2010, 01:21:32 am
Okay, so what does this do other than turn off the entire reticle on my HUD?

It should also decouple the direction you're looking from the direction you're pointing.  i wonder how your situation is different from mine... do you have mouse control turned on?
Title: Re: hate how the mouse works? have i got the script for you!
Post by: Commander Zane on May 08, 2010, 02:06:13 am
I can turn it off but then it doesn't let me move at all.
Title: Re: hate how the mouse works? have i got the script for you!
Post by: eigenlambda on May 27, 2010, 09:02:46 pm
Finally, a new release.

This fixes the 'aqmouse does nothing when the computer isn't slow enough' bug.  It also provides a method to toggle suspending aqmouse control- hold the middle mouse button for more than 100ms, and also provides an improved reticle that shows you where your shots are going to be when they reach the distance to your target.

as always, put aqmouse-sct.tbl in $FS2_DIR/aqmouse/data/tables and use -mod whateverelse,aqmouse

Code: [Select]
$State: GS_STATE_GAME_PLAY
$On Frame:

[

frametime = ba.getFrametime()

if middle_button_time == nil then
    middle_button_time = 0
end
if io.isMouseButtonDown(MOUSE_MIDDLE_BUTTON) then
    middle_button_time = middle_button_time + frametime
else
    middle_button_time = 0
end
-- if the middle button is pressed for more that .1s,
-- toggle suspension of aqmouse
if middle_button_time > .1 then
    if suspended then   
        suspended = false
    else
        suspended = true
        inited = false
        gr.setCamera()
    end
end

if suspended then
    gr.setColor(255,255,255)
    gr.drawString("aqmouse suspended",0,0)
else   
    -- if the setting changes, take note of it to set it back later
    -- in order to avoid stepping on the users toes too much
    if io.MouseControlStatus == true then
        mouse_reset_on_end = true
        io.MouseControlStatus = false
    end

    -- get control values
    mouse_x = io.getMouseX()
    mouse_y = io.getMouseY()
    controls = ba.getControlInfo()


    if not inited then
        plr = hv.Player
        cpos = plr.Position + plr.Orientation:rotateVector( ba.createVector(0,-15,-75) )
        ccam = gr.createCamera("ccam", cpos, plr.Orientation)
        gr.setCamera(ccam)
        inited = true
        scr_width = gr.getScreenWidth()
        scr_height = gr.getScreenHeight()
    else
        -- the documentation says getVectorFromCoords gives you a normal
        -- vector, but the code says it's a normal vector + camera pos
        wanted_dir = gr.getVectorFromCoords(mouse_x, mouse_y) - cpos
           
        -- camera alway points towards where the mouse is
        -- just like any other first-person shoter
        delta = ccam.Orientation:rotateVector(wanted_dir):getOrientation()
        ccam:setOrientation(ccam.Orientation*delta)
        io.forceMousePosition(scr_width/2, scr_height/2)
        clocate = ba.createVector(0,15,-50)
        cpos = plr.Position + ccam.Orientation:unrotateVector(clocate)
        ccam:setPosition(cpos)
        -- now let's try to make the player point the same direction
        local_wanted_dir = plr.Orientation:rotateVector(wanted_dir)
        local_wanted_dir = local_wanted_dir / local_wanted_dir:getMagnitude()
        -- compute the cross product with <0,0,1> by hand
        xdiff = local_wanted_dir.y
        ydiff = -local_wanted_dir.x
        -- the magnitude of the cross product is the sine of angle between the vectors
        theta = math.asin(math.sqrt(xdiff*xdiff + ydiff+ydiff))
        costheta = local_wanted_dir.z -- this was the dot product with <0,0,1>
        -- these are needed for everything that follows
        rotvel = plr.Physics.RotationalVelocity
        rvx = rotvel.x
        rvy = rotvel.y
        if costheta < 0 then
            -- obtuse angle between camera and ship forward
            if theta == 0 then
                -- pointing in the exact opposite direction
                -- so, go in the direction that we're already rotating, fast
                -- if we're not rotating, start as quickly as possible
                rvr = math.sqrt(rvx*rvx + rvy*rvy)
                if rvr == 0 then
                    controls.Heading = 1
                    controls.Pitch = 1
                else
                    controls.Heading = 5*rvy
                    controls.Pitch = 5*rvx
                end
            else
                controls.Heading = -5*ydiff
                controls.Pitch = -5*xdiff
            end
        else
            -- ok, heres some theory to explain what happens next
            -- next frame's rotvel is calculated as
            -- apply_physics( rotdamp, pi->desired_rotvel.xyz.x,
            --                pi->rotvel.xyz.x, sim_time,
            --                &new_vel.xyz.x, NULL );
            -- controls.Heading and controls.Pitch can have
            -- values between -1 and 1, from which desired_rotvel
            -- is calculated as that number times the maximum
            -- rotational speed around the axis in question.
            -- rotdamp is a single scalar that determines how fast
            -- rotvel becomes desired_rotvel by exponential decay:
            -- (rotvel - desired_rotvel)*exp(-frametime/rotdamp)
            maxrv = plr.Physics.RotationalVelocityMax
            maxrvx = maxrv.x
            maxrvy = maxrv.y
            rotdamp = plr.Physics.RotationalVelocityDamping
            frametime = ba.getFrametime()
           
            -- we need the sign of these for later calculations
            rvxs = sign(rvx)
            rvys = sign(rvy)
            xsign = sign(xdiff)
            ysign = sign(ydiff)
           
            -- the angle is the inverse sine of the cross product
            xangle = math.asin(xdiff)
            yangle = math.asin(ydiff)

            -- how quickly can we stop by applying full reverse?
            timeto0x = rotdamp*math.log(-rvxs*maxrvx/(-rvxs*maxrvx+rvx))
            timeto0y = rotdamp*math.log(-rvys*maxrvy/(-rvys*maxrvy+rvy))

            -- x ~= x is how you check for NaN in lua
            -- we will get NaN as math.log(0) when rvx == 0, so rvxs == 0
            if timeto0x ~= timeto0x then
                timeto0x = 0
            end
            if timeto0y ~= timeto0y then
                timeto0y = 0
            end

            -- how far do we go until we stop
            -- integral of rotational velocity from now until timeto0x from now
            -- assuming full acceleration against the direction we're going in
            angleto0x = -rvxs*maxrvx*timeto0x + rotdamp*(-rvxs*maxrvx*timeto0x-rvx)*(math.exp(-timeto0x/rotdamp)-1)
            angleto0y = -rvys*maxrvy*timeto0y + rotdamp*(-rvys*maxrvy*timeto0y-rvy)*(math.exp(-timeto0y/rotdamp)-1)
           
            -- calculate how fast to rotate
            xfactor = math.exp(-frametime/rotdamp)
            if yangle*ysign > angleto0y*ysign then
                controls.Heading = -(rvy - (yangle-rvy*frametime)/(rotdamp*(xfactor-1)))/maxrvy
            else
                forceto0 = rvy*xfactor/(1-xfactor) / maxrvy
                controls.Heading = -forceto0
            end
            if xangle*xsign > angleto0x*xsign then
                controls.Pitch = -(rvx - (xangle-rvx*frametime)/(rotdamp*(xfactor-1)))/maxrvx
            else
                forceto0 = rvx*xfactor/(1-xfactor) / maxrvx
                controls.Pitch = -forceto0
            end
        end
       
       
        -- now ensure that the ship is banked correctly
        -- in the future, this should capture whatever keys the player
        -- uses to bank and adjust the camera first with them
        up = ba.createVector(0,1,0)
        camup = ccam.Orientation:rotateVector(up)
        plrup = plr.Orientation:rotateVector(up)
        should_be_forward = camup:getCrossProduct(plrup)
        controls.Bank = should_be_forward.z
       
        -- lastly, fix the HUD
        -- first kill the annoying gauges
        hu.setHUDGaugeColor( 9,0,0,0,0) --reticle center
        hu.setHUDGaugeColor(23,0,0,0,0) --target mini icon
        hu.setHUDGaugeColor(19,0,0,0,0) --threat gauge
        hu.setHUDGaugeColor( 6,0,0,0,0) --throttle gauge
        hu.setHUDGaugeColor(20,0,0,0,0) --afterburner energy
        hu.setHUDGaugeColor(21,0,0,0,0) --weapons energy
        -- then replace them
        gaugey = math.floor(.6*scr_height)
        gr.setColor(200, 200, 0, 100)
        energy_fraction = plr.WeaponEnergyLeft/plr.WeaponEnergyMax
        gr.drawRectangle(0, gaugey+1, 100*energy_fraction, gaugey+9)
       
        burn_fraction = plr.AfterburnerFuelLeft/plr.AfterburnerFuelMax
        gr.drawRectangle(0, gaugey+11, 100*burn_fraction, gaugey+19)
        speed = math.floor(plr.Physics:getForwardSpeed()+.5)
        gr.drawString(speed, 100, gaugey+11)
        if plr.PrimaryTriggerDown then
            gr.setColor(100, 0, 0, 64)
            gr.drawCircle(5, 105, gaugey+5)
        end
     
        -- now to make the aim gauge.  this tells you where on screen your
        -- shots are going to be when they get out to the target distance
        gr.setColor(0, 255, 0, 255)
        if plr.Target then
            r = (plr.Target.Position - plr.Position):getMagnitude()
            aimr = plr.Position + plr.Orientation:unrotateVector(ba.createVector(0,0,r))
            x,y = aimr:getScreenCoords()
            if x ~= false then
                gr.drawLine(x-9,y-9,x-6,y-9,false)
                gr.drawLine(x-9,y-9,x-9,y-6,false)
                gr.drawLine(x-9,y+9,x-6,y+9,false)
                gr.drawLine(x-9,y+9,x-9,y+6,false)
                gr.drawLine(x+9,y-9,x+6,y-9,false)
                gr.drawLine(x+9,y-9,x+9,y-6,false)
                gr.drawLine(x+9,y+9,x+6,y+9,false)
                gr.drawLine(x+9,y+9,x+9,y+6,false)
            end
        end
     
        -- now tell the hud to draw
        hu.HUDDrawn = true
    end
end

]

$Application: FS2_Open
$On Mission End:

[

boolscriptmouse = false
ba.setControlMode(NORMAL_CONTROLS)
if mouse_reset_on_end == true then
   io.MouseControlStatus = true
end
inited = false -- this line should not be needed

]

#End
Title: Re: hate how the mouse works? have i got the script for you!
Post by: Zapp on July 07, 2010, 02:42:24 pm
Maybe I'm a bit slow, but I didn't quite understand what I have to do to get this to work.

[edit]

Nevermind. I just found this (http://www.hard-light.net/wiki/index.php/Script_-_Scripted_Mouse) and have:


Didn't work if I pasted the code from eigenlambda in the .tbm-file though... but at least I have something to play around with now :)

[edit2]

Got it.
eigenlambda posted only half of his code... if you put that and half of an older code together it works ;)

Pretty freaky viewpoint though. Doesn't this make the game incredibly easy?
Hmmm... we'll see :)

Zapp
Title: Re: hate how the mouse works? have i got the script for you!
Post by: Kiloku on September 22, 2010, 08:57:52 am
Can someone just post all the files I must add in the mod folder? With all the changes since the first version, I got lost...
Title: Re: hate how the mouse works? have i got the script for you!
Post by: eigenlambda on September 23, 2010, 08:27:57 pm
My code is subtly wrong, it overshoots even with a smooth, high frame rate, and I have no idea why, since I checked the integrals several times.  Perhaps approximating Freespace's Euler's method with differential equations is a mistake in itself.  Anyway, you need to put the code I put three posts ago in an aqmouse-sct.tbl in aqmouse/data/tables.
Title: Re: hate how the mouse works? have i got the script for you!
Post by: zath on October 16, 2010, 03:06:52 pm
Hi,

Im new here, and I cant figure out how to get this to work.

Im running FSO 3.6.12 on OSX using the inferno build and Soulstorms launcher.

I put the script in [mainFSfolder}/aqmouse/data/tables

and under select mod in the launcher I wrote aqmouse

nothing changes in game, with mouse on or off.

Can someone help me out?

thanx
Title: Re: hate how the mouse works? have i got the script for you!
Post by: potatochief on August 08, 2011, 06:42:38 am
Maybe I'm a bit slow, but I didn't quite understand what I have to do to get this to work.

[edit]

Nevermind. I just found this (http://www.hard-light.net/wiki/index.php/Script_-_Scripted_Mouse) and have:

  • created the file c:\games\freespace2\aqmouse\data\tables\script_mouse-sct.tbm
  • filled in the code from the wiki-page
  • created the file c:\games\freespace2\aqmouse\data\config\mouse_script.cfg
  • filled in the code from the bottom of the wiki-page
  • started the game with fs2_open_3_6_12r_INF_SSE2.exe -mod aqmouse
  • and it finally works :)

Didn't work if I pasted the code from eigenlambda in the .tbm-file though... but at least I have something to play around with now :)

[edit2]

Got it.
eigenlambda posted only half of his code... if you put that and half of an older code together it works ;)

Pretty freaky viewpoint though. Doesn't this make the game incredibly easy?
Hmmm... we'll see :)

Zapp

Thanks Zapp! Thanks guys for the code! got it to work... similar to freelancer but it wasn't exactly smooth to boot...

I remember that only when the mouse is close to the edge of the screen (30%) that the mouse begins to rotate and the rotaton speed is incremental depending on the closeness to the edge of the screen...
The speed on which it turns is indicated by ">>>" one > is slow; >> means faster turn; >>> is full tilt...

Sorry for being so pesky... a lot of my friends would like freespace except for the damned mouse "clawing" action! It turns them off with the game despite the work done on it so far...

as an objective review, I'm kinda feeling nauseated at the moment from the new mouse movement. I know it isn't great news, sorry guys...

Hope the feedback helps! :)
Title: Re: hate how the mouse works? have i got the script for you!
Post by: jr2 on August 08, 2011, 05:24:21 pm
Does this (http://www.hard-light.net/forums/index.php?topic=74435.0) one work better?
Title: Re: hate how the mouse works? have i got the script for you!
Post by: Sushi on August 08, 2011, 07:04:46 pm
jr2: Look at the last couple of posts in that thread. :D

potatochief: Try toggling the "Don't use DirectX for mouse control" flag in the launcher (Features tab, select the "Troubleshoot" list type). You may find it makes mouse control smoother (especially when doing it Freelancer-style).