Forum Jump :

Author Message


Posts: 131
Rank:


Level: Member

Country: us
Location:
Occupation:
Age: 22
In-game name: Joshua

 
#1 Posted at 2015-05-10 14:00        
     
I have been working with the key up event handler, but no matter what I set _handled to in the code, it still registers the action assigned to the key (m pulls up the map etc.). I create the event handler and then go into a while loop after the event handler is created that waits for input and processes it for my program. How can I get _handled to properly return true in the event handler?

If you need more information or I am unclear, please let me know.

My code (note this is only the "main method" of the program, but its the function that has the event handler):
/**
 * ArmaTerminal
 * armaTerminal.sqf
 * By Joshua Shear
 * Allows users to open computers and interface with virtual files and data through a Linux inspired command line and text editor
 */

//Get params
	_target = _this select 0;					//Computer
	_caller = _this select 1;					//Player Activating computer
	_actionID = _this select 2;					//Action ID
	_users = _this select 3 select 0;			//Users registered with computer
	_files = _this select 3 select 1;			//Starting File Structure

_computer = [_target,_caller,_actionID,_users,_files] call Computer_fnc_open;

//Initializes Key Logger for basic input

pressedKey = -1;
	/*
	 *This is the ID of the key from the action listener below
	 */
shift = false;
(findDisplay 46) displayAddEventHandler ["KeyUp", {pressedKey = _this select 1; shift = _this select 2; _handled = true; _handled;}];

/**
 * Execution loop
 * Runs for as long as user doesn't input quit and user is alive
 * Has a switch statement to get the given state and execute the proper commands for that given state (Command line, login, editor)
 */
 while{_computer select 4 != "QUIT"}do{

	if(floor(time) mod 9 == 0)then{							//Refreshes black background every 9 seconds
		cutText ["", "BLACK FADED",0];						//fade screen to black
	};
	
	//Gets key and logs it
	_input = -1;
	
	if(pressedKey != -1 && pressedKey != 54 && pressedKey != 42)then{
		_tempIn = pressedKey;
		_input = [0, _tempIn, shift, false,false] call Computer_fnc_getUserInput;
		
		//Executes proper code for current state
		_state = _computer select 4;
		if(str(_state) == str("EDITOR")) then{
			
		};
		if(str(_state) == str("COMMANDLINE"))then{
			_computer = [_input, _computer] call CommandLine_fnc_processUserInput;
		};
		if(str(_state) == str("LOGIN"))then{};
		pressedKey = -1;
	};
	
	_print = [_computer] call Computer_fnc_print;
};

[_target,_caller] call Computer_fnc_close;


Author Message


Posts: 1484
Rank:


Level: Member

Country: uk
Location:
Occupation:
Age:
In-game name:

 
#2 Posted at 2015-05-10 15:43        
     
I'm not at my right PC but I do remember blocking certain actions using actionkeys

keybindings = actionKeys "Prone";// stop prone
keybindings1 = actionKeys "showmap";// stop map

example code only
dokeyDown={
     private ["_r"] ;
     _r = false ; 
     player sidechat str keybindings1;
     if ((_this select 1) in keybindings or (_this select 1) in keybindings1) then {
	     // removed code
	     hint "down";
	       _r=true;
	  };
     _r;
} ;


It would be better to make an array of the keys you wish to block and it may not even work in A3.
I found trying to block the numbers never seemed to work.


Advertisement


Author Message


Posts: 131
Rank:


Level: Member

Country: us
Location:
Occupation:
Age: 22
In-game name: Joshua

 
#3 Posted at 2015-05-10 16:29        
     
Would processing the data outside of the event handler be the issue? I looked at the code you used in your example and I think that's part of my problem. All the examples I see process the data from the event handler in the code block or call a script from inside the code block. In my program, I only record the data and then process it completely outside of the event handler. I don't think for what I want to do, I can process the data inside the event handler.

As for the actionKeys, I looked them up and I am a bit confused as to how they would stop the input, I am also unsure how I would get every single action in the game with those. For what I am doing I need complete control of the keyboard (I am essentially making a command prompt/terminal/command line inside of the game, so I need the full keyboard so people can type commands).

Thanks for your super quick reply F2kSel :)


Author Message


Posts: 83
Rank:


Level: Member

Country: us
Location:
Occupation:
Age:
In-game name: J.Shock

 
#4 Posted at 2015-05-10 16:49        
     
All code used inside the braces of the EH are local scope to that EH, you can't use it elsewhere (outside of scope). As for the action keys, in your case, it isn't necessary I don't believe because you need the specific keys, not specific actions based on those keys. So all you need is the key pressed, if it's one of your keys used in your command prompt, execute whatever necessary code for that key press/release.

John Shock
Scripter, Mission Developer

My scripts: Simple Mortar Script, Redressing Script, Cruise Control Script

My Missions: [COOP-40]Operation Bloody Bayonet

Author Message


Posts: 131
Rank:


Level: Member

Country: us
Location:
Occupation:
Age: 22
In-game name: Joshua

 
#5 Posted at 2015-05-10 17:13        
     
Ok, I'm not quite sure I am following you JShock.

I understand that you are saying I don't need the actionKeys. I also understand that the braces in the EH are the scope, which is why I use 'pressedKey' and 'shift' as global variables so that I can access them in the loop below. Are you saying that '_handled' needs to be global ('handled')?
I just tried making handled global and the journal and map still came up. (In case that's what you meant.)

Also, I am getting the key presses just fine and I can print the input on screen like I want, its just when typing, actions execute in the background (pressing 'j' for instance opens the journal and prevents any more input until you press 'j' again to close the journal) which is annoying and can suspend input collection.

Does this help any? Also, can you perhaps explain what you were trying to say differently, I don't quite understand what you are getting at in your last sentence.


Author Message


Posts: 1589
Rank:


Level: Member

Country: pf
Location: Tahiti
Occupation: too many Arma
Age: 57
In-game name: Kobayashi Maru

 
#6 Posted at 2015-05-10 18:54        
     
Everything above is right. EH are local scope (and unscheduled until you spawn something in it: no direct waituntil).

For keys, you have several ways to reach the aim. I used with success:
See example at the bottom of this page (works also for keyUp) :
https://community.bistudio.com/wiki/User_Interface_Event_Handlers#onKeyDown
You don't need a while loop but you must pay attention to the way you call your scripts or keys will not fire anything.
I prefer this sequence:
In init, compile preprocessfile a sqf with keyUp code:
example: MGI_HUD_look = compile preprocessFileLineNumbers "\MGI_TG_v2\HUD_look.sqf";

Place the keyUp code with all your keys in an sqf (here HUD_look.sqf), no function but directly, something like:
_ctrl = _this select 0;
_dikCode = _this select 1;
_shift = _this select 2;
_ctrlKey = _this select 3;
_alt = _this select 4;
_HUD_input = false;

if (!_shift && _ctrlKey && !_alt) then {
    if (_dikCode == 0xC9 ) then {
		kod_color = kod_color + 1;
		_hud_mod = kod_color mod 10;
		HUD_color = HUD_color_panel select _hud_mod;
		HUD_RGB = HUD_RGB_panel select _hud_mod;
 		_HUD_input = true};
....

Then ,call in whatever next script:
keys = (findDisplay 46) displayAddEventHandler ["keyUp", "_this call MGI_HUD_look"];
That works!

Or inputAction. For example:
[_coef_zoom_GPS, _max_grid] spawn {
  _coef = _this select 0;
  _grid = _this select 1;
if (inputAction "switchCommand" == 0) exitWith {adapt_GPS_scale = 4.5*_coef/_grid; sleep 0.1};

if (inputAction "switchCommand" > 0) exitWith {
//_essai = adapt_GPS_scale;
if (inputAction "PrevAction" > 0) then {
        adapt_GPS_scale = (adapt_GPS_scale *1.2) min 1;
    };
if (inputAction "NextAction" > 0) then {
        adapt_GPS_scale = (adapt_GPS_scale * 0.83) max 0.01;
    };
	};
  sleep 0.1;
  if {true} exitWith {};
};
but that means changing Arma's default keybinding. By the way, "Adjust" which was linked to "ctrl" key is no more available since 1.42 version. The reason why I chose "swithCommand" here. Grrrr!

PLEASE CONTACT ME ON BI FORUMS FOR ANY SCRIPT / MOD QUESTION. TKS

Author Message


Posts: 131
Rank:


Level: Member

Country: us
Location:
Occupation:
Age: 22
In-game name: Joshua

 
#7 Posted at 2015-05-10 20:01        
     
I tried following your first method Pierre and it didn't work for me. Here is what I did, perhaps I messed up somewhere.

First, I created an init.sqf (I hadn't needed one until now with the test mission.)
script = compile preprocessFile "test.sqf";

I then created test.sqf
_ctrl = _this select 0;
_dikCode = _this select 1;
_shift = _this select 2;
_ctrlKey = _this select 3;
_alt = _this select 4;
_handled = false;
hint "HI";
_handled = true
I started by copying your 'HUD_look' file. Then I removed your logic except for '_hud_input'. I assume that was your equivalent to '_handled', so I replaced it with '_handled' and added the hint just so I knew that it executed (which when I tested it, it ran)

After that, I commented out most of my code in my 'armaTerminal.sqf' file and put in your event handler line with some minor modifications. This is the code in 'armaTerminal.sqf' that is uncommented:
_target = _this select 0;					//Computer
_caller = _this select 1;					//Player Activating computer
_actionID = _this select 2;					//Action ID
_users = _this select 3 select 0;			//Users registered with computer
_files = _this select 3 select 1;			//Starting File Structure

_computer = [_target,_caller,_actionID,_users,_files] call Computer_fnc_open;

keys = (findDisplay 46) displayAddEventHandler ["keyUp", "_this call script"];

[_target,_caller] call Computer_fnc_close;

When I ran this, it gave the hint "HI" as it was supposed to but all my actions still executed ('m' still opened the map for instance).

Some other things:

-I assume that when '_handled' is set to true, the engine ignores the input. I remember reading that somewhere. Is this correct?

-I am positive that I need the while loop. I use 'BIS_fnc_dynamicText' to display the terminal text on screen, this will fade out after a time and the loop needs to keep the text refreshing. It also restricts when the input is valid to just while the user is in the terminal, among other things.

-I didn't realize Event Handlers were unscheduled, it doesn't change what I am doing but it's good to know, thanks for the information.

-Just to clarify, my program is taking user input and printing a processed version of it on screen. My problem is when pressing keys, their actions still trigger in addition to their registering with the eventHandler. I would like the actions to not trigger.


Author Message


Posts: 1589
Rank:


Level: Member

Country: pf
Location: Tahiti
Occupation: too many Arma
Age: 57
In-game name: Kobayashi Maru

 
#8 Posted at 2015-05-10 23:19        
     
Yes, for true / false in _handled, you're right. OK for you loop concerning only dynamic text (sorry).
I have no idea with computer_fnc_open / close but as keyUp EH works on its own, perhaps it's better to begin with it then open /close fnc, instead of open, call EH, close computer. I'm afraid I have no more idea so far.

PLEASE CONTACT ME ON BI FORUMS FOR ANY SCRIPT / MOD QUESTION. TKS

Author Message


Posts: 131
Rank:


Level: Member

Country: us
Location:
Occupation:
Age: 22
In-game name: Joshua

 
#9 Posted at 2015-05-11 00:05        
     
I tried putting it right after the declaration for the parameters for the action command, so it was before Computer_fnc_open. It still didn't solve it. I appreciate the help.
Perhaps there is a way to disable specific player actions like the map, Zeus and journal. Those are the two most annoying as they will disable input until you press their key again. Is there any way to do that?

<edit>
I found this:
if(visibleMap)then{openMap false;};
Its not perfect but it does make the map disappear an instant after it comes up. I can't find anything similar though for journal.
</edit>

This post was edited by jshear95 (2015-05-11 00:10, 946 days ago)


Author Message


Posts: 131
Rank:


Level: Member

Country: us
Location:
Occupation:
Age: 22
In-game name: Joshua

 
#10 Posted at 2015-05-15 15:48        
     
I found a fix!

We were setting _handled for key up. Arma doesn't process key presses when they are released, but rather when they are depressed. By adding a second event handler searching for key downs and then setting handled to true for everything, it ignores all input, but still lets me type stuff into my terminal.

Just make sure to remove the event handler when you are finished! The first time I forgot and my whole keyboard couldn't do anything. I had to alt F4 out because even escape was blocked.

Here is the code I have:
/*Init stuff for the terminal*/

_KeyUp = (findDisplay 46) displayAddEventHandler ["KeyUp", {/*stuff*/}];
_KeyDown =(findDisplay 46) displayAddEventHandler ["KeyDown", {_handled = true; _handled}];

/*Logic loop*/

(findDisplay 46) displayRemoveEventHandler ["KeyDown", _KeyDown];
(findDisplay 46) displayRemoveEventHandler ["KeyUp", _KeyUp];

/*Shut down stuff for the terminal*/
Thanks again for all your help everyone!


Author Message


Posts: 1589
Rank:


Level: Member

Country: pf
Location: Tahiti
Occupation: too many Arma
Age: 57
In-game name: Kobayashi Maru

 
#11 Posted at 2015-05-15 17:24        
     
Good work! Thanks

PLEASE CONTACT ME ON BI FORUMS FOR ANY SCRIPT / MOD QUESTION. TKS