Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added: QTE Framework #1649

Open
wants to merge 32 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 29 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
ea657b5
Added: QTE Framework
john681611 Mar 19, 2024
964cefe
Update addons/common/fnc_generateQTESequence.sqf
john681611 Mar 21, 2024
45929cd
refactor to use Keybinds
john681611 Mar 23, 2024
bfa6ea8
Merge branch 'quickTimeEvents' of github.com:john681611/CBA_A3 into q…
john681611 Mar 23, 2024
3576e8e
Fix null issue on key press
john681611 Mar 23, 2024
dbc5abe
review improvements
john681611 Mar 23, 2024
d35bfb8
Support localization
john681611 Mar 23, 2024
986d828
Update addons/common/XEH_preInit.sqf
john681611 Mar 26, 2024
26529cc
Update addons/common/fnc_generateQTESequence.sqf
john681611 Mar 26, 2024
5255969
Update addons/common/fnc_keyPressedQTE.sqf
john681611 Mar 26, 2024
96806a9
Update addons/common/fnc_runQTE.sqf
john681611 Mar 26, 2024
6597fc8
Update addons/common/stringtable.xml
john681611 Mar 26, 2024
9feffc8
Update addons/common/fnc_keyPressedQTE.sqf
john681611 Mar 26, 2024
c851040
Update addons/common/fnc_keyPressedQTE.sqf
john681611 Mar 26, 2024
68c586b
Update addons/common/fnc_keyPressedQTE.sqf
john681611 Mar 26, 2024
f48ebaa
review comments
john681611 Mar 26, 2024
d99bb4f
minor improvements
john681611 Mar 27, 2024
97fc243
Update addons/common/fnc_keyPressedQTE.sqf
john681611 Mar 27, 2024
29f9f11
Update addons/common/fnc_runQTE.sqf
john681611 Mar 27, 2024
1fbb063
Update addons/common/fnc_runQTE.sqf
john681611 Apr 2, 2024
c8e951b
Update addons/common/fnc_runQTE.sqf
john681611 Apr 2, 2024
24bf821
Update addons/common/fnc_runQTE.sqf
john681611 Apr 2, 2024
9eb7b18
format: camelcasing
john681611 Apr 30, 2024
7dc983f
Merge branch 'quickTimeEvents' of github.com:john681611/CBA_A3 into q…
john681611 Apr 30, 2024
a22d373
Update addons/common/XEH_preInit.sqf
john681611 Apr 30, 2024
9a6cfb2
migrate to quicktime component
john681611 Apr 30, 2024
976eca3
Merge branch 'quickTimeEvents' of github.com:john681611/CBA_A3 into q…
john681611 Apr 30, 2024
6d2f3fe
minor fixes
john681611 Apr 30, 2024
6024704
Fix sneaky keybind error
john681611 Apr 30, 2024
8e236f2
Review comment improvements
john681611 May 5, 2024
83ca39f
Use more generic condition and reset counter
john681611 May 5, 2024
46d200d
Update addons/quicktime/fnc_runQTE.sqf
john681611 Jun 24, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion addons/main/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ class CfgPatches {
"cba_ui",
"cba_versioning",
"cba_optics",
"cba_disposable"
"cba_disposable",
"cba_quicktime"
};
author = "$STR_CBA_Author";
authors[] = {};
Expand Down
1 change: 1 addition & 0 deletions addons/quicktime/$PBOPREFIX$
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
x\cba\addons\quicktime
12 changes: 12 additions & 0 deletions addons/quicktime/CfgEventHandlers.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
class Extended_PreStart_EventHandlers {
class ADDON {
init = QUOTE(call COMPILE_SCRIPT(XEH_preStart));
};
};

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove along with the file.

class Extended_PreInit_EventHandlers {
class ADDON {
init = QUOTE(call COMPILE_SCRIPT(XEH_preInit));
};
};

10 changes: 10 additions & 0 deletions addons/quicktime/CfgFunctions.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
class CfgFunctions {
class CBA {
class QuickTimeEvent {
PATHTO_FNC(generateQTESequence);
PATHTO_FNC(getFormattedQTESequence);
PATHTO_FNC(runQTE);
PATHTO_FNC(keyPressedQTE);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Order them alphabetically.

Suggested change
PATHTO_FNC(runQTE);
PATHTO_FNC(keyPressedQTE);
PATHTO_FNC(keyPressedQTE);
PATHTO_FNC(runQTE);

};
};
};
24 changes: 24 additions & 0 deletions addons/quicktime/XEH_preInit.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#include "script_component.hpp"
#include "\a3\ui_f\hpp\defineDIKCodes.inc"

SCRIPT(XEH_preInit);

ADDON = false;

[LSTRING(QTEKeybindGroup), QGVAR(qteUpKey), ["↑", LSTRING(QTEKeybindUpTooltip)], {
["↑"] call CBA_fnc_keyPressedQTE // return
}, {}, [DIK_UP, [false, true, false]]] call CBA_fnc_addKeybind;

[LSTRING(QTEKeybindGroup), QGVAR(qteDownKey), ["↓", LSTRING(QTEKeybindDownTooltip)], {
["↓"] call CBA_fnc_keyPressedQTE // return
}, {}, [DIK_DOWN, [false, true, false]]] call CBA_fnc_addKeybind;

[LSTRING(QTEKeybindGroup), QGVAR(qteLeftKey), ["←", LSTRING(QTEKeybindLeftTooltip)], {
["←"] call CBA_fnc_keyPressedQTE // return
}, {}, [DIK_LEFT, [false, true, false]]] call CBA_fnc_addKeybind;

[LSTRING(QTEKeybindGroup), QGVAR(qteRightKey), ["→", LSTRING(QTEKeybindRightTooltip)], {
["→"] call CBA_fnc_keyPressedQTE // return
}, {}, [DIK_RIGHT, [false, true, false]]] call CBA_fnc_addKeybind;

ADDON = true;
1 change: 1 addition & 0 deletions addons/quicktime/XEH_preStart.sqf
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't need this file, remove it.

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#include "script_component.hpp"
18 changes: 18 additions & 0 deletions addons/quicktime/config.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#include "script_component.hpp"

class CfgPatches {
class ADDON {
name = CSTRING(component);
units[] = {};
weapons[] = {};
requiredVersion = REQUIRED_VERSION;
requiredAddons[] = {"cba_common","cba_events"};
author = "$STR_CBA_Author";
authors[] = {"john681611"};
url = "$STR_CBA_URL";
VERSION_CONFIG;
};
};

#include "CfgFunctions.hpp"
#include "CfgEventHandlers.hpp"
31 changes: 31 additions & 0 deletions addons/quicktime/fnc_generateQTESequence.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#include "script_component.hpp"
/* ----------------------------------------------------------------------------
Function: CBA_fnc_generateQTESequence

Description:
Generate a Quick-Time sequence of a given length.

Parameters:
_length - Length of QTE sequence <NUMBER>

Example:
[5] call CBA_fnc_generateQTESequence;

Returns:
Quick-Time sequence of requested length made up of ["↑", "↓", "→", "←"] <ARRAY>

Author:
john681611
---------------------------------------------------------------------------- */

params [["_length", 0, [0]]];

if (_length <= 0) exitWith {[]};

private _code = [];

for "_i" from 0 to _length do {
_code pushBack (selectRandom ["↑", "↓", "→", "←"]);
};

_code
24 changes: 24 additions & 0 deletions addons/quicktime/fnc_getFormattedQTESequence.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#include "script_component.hpp"
/* ----------------------------------------------------------------------------
Function: CBA_fnc_getFormattedQTESequence

Description:
Formats Quick-Time sequence into a displayable string.

Parameters:
_code - Quick-Time sequence <ARRAY>


Example:
[["↑", "↓", "→", "←"]] call CBA_fnc_getFormattedQTESequence;

Returns:
Formatted Quick-Time sequence <STRING>

Author:
john681611
---------------------------------------------------------------------------- */

params ["_code"];

_code joinString " " // Arma doesn't know how to space ↑ so we need loads of spaces between
60 changes: 60 additions & 0 deletions addons/quicktime/fnc_keyPressedQTE.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#include "script_component.hpp"
/* ----------------------------------------------------------------------------
Function: CBA_fnc_keyPressedQTE

Description:
Process Quick-Time Key Press

Parameters:
_eventQTE - Character to test against Quick-Time Event <STRING>

Example:
["↑"] call CBA_fnc_keyPressedQTE;

Returns:
True if QTE is running <BOOLEAN>

Author:
john681611
---------------------------------------------------------------------------- */


params ["_eventQTE"];

if !(missionNamespace getVariable [QGVAR(QTERunning), false]) exitWith {
false
};


private _args = GVAR(QTEArgs) get "args";
private _qteSequence = GVAR(QTEArgs) get "qteSeqence";
private _elapsedTime = CBA_missionTime - (GVAR(QTEArgs) get "startTime");

GVAR(QTEHistory) pushBack _eventQTE;


Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Check if the input corresponds to the sequence

if (GVAR(QTEHistory) isEqualTo _qteSequence) exitWith {
GVAR(QTEHistory) = [];
GVAR(QTERunning) = false;
TRACE_1("QTE Completed",_elapsedTime);
private _onFinish = GVAR(QTEArgs) get "onFinish";
if (_onFinish isEqualType "") then {
[_onFinish, [_args, _elapsedTime]] call CBA_fnc_localEvent;
} else {
[_args, _elapsedTime] call _onFinish;
};
true
};

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// If the user failed an input, wipe the previous input from memory

if (GVAR(QTEHistory) isNotEqualTo (_qteSequence select [0, count GVAR(QTEHistory)])) then {
GVAR(QTEHistory) = [];
};

private _onDisplay = GVAR(QTEArgs) get "onDisplay";
if (_onDisplay isEqualType "") then {
[_onDisplay, [_args, _qteSequence, GVAR(QTEHistory)]] call CBA_fnc_localEvent;
} else {
[_args, _qteSequence, GVAR(QTEHistory)] call _onDisplay;
};

true
94 changes: 94 additions & 0 deletions addons/quicktime/fnc_runQTE.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
#include "script_component.hpp"
/* ----------------------------------------------------------------------------
Function: CBA_fnc_runQTE

Description:
Runs a Quick-Time Event.

Parameters:
_object - <OBJECT>
_args - Extra arguments passed to the _on... functions<ARRAY>
_onDisplay - Code callback on displayable event passed [_args, _qteSequence, _qteHistory]. <CODE, STRING>
_onFinish - Code callback on Quick-Time Event completed passed [_args, _elapsedTime]. <CODE, STRING>
_onFinish - Code callback on Quick-Time Event timeout/outranged passed [_args, _elapsedTime]. <CODE, STRING>
_qteSequence - Quick-Time sequence made up of ["↑", "↓", "→", "←"] <ARRAY>
_maxDistance - max interaction distance from attached object <NUMBER> (default: 10)
_timeout - ingame timeout <NUMBER> (default: 30)

Example:
[car,
[],
{
hint format [
"%1 \n %2",
[_this select 1] call CBA_fnc_getFormattedQTESequence,
[_this select 2] call CBA_fnc_getFormattedQTESequence
]
},
{
hint "Finished!";
},
{
hint "Failure!";
},
["↑", "↓", "→", "←"]] call CBA_fnc_runQTE

Returns:
True if the QTE was started, false if it was already running <BOOELAN>
john681611 marked this conversation as resolved.
Show resolved Hide resolved

Author:
john681611
---------------------------------------------------------------------------- */


params ["_object", "_args", "_onDisplay", "_onFinish", "_onFail", "_qteSequence", ["_maxDistance", 10], ["_timeout", 30]];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is a public function, we need to sanitise the input:

Suggested change
params ["_object", "_args", "_onDisplay", "_onFinish", "_onFail", "_qteSequence", ["_maxDistance", 10], ["_timeout", 30]];
params [["_object", objNull, [objNull]], "_args", ["_onDisplay", {}, ["", {}]], ["_onFinish", {}, ["", {}]], ["_onFail", {}, ["", {}]], ["_qteSequence", [], [[]]], ["_maxDistance", 10, [0]], ["_timeout", 30, [0]]];

You need to check if the input are valid (e.g. an empty QTE sequence should not be allowed).

I haven't taken into account the other proposals I've made, so you'll need to adapt accordingly.

if (GVAR(QTERunning)) exitWith {
false
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GVAR(QTERunning) is undefined on the first time it's run.

Suggested change
if (GVAR(QTERunning)) exitWith {
false
};
if !(missionNamespace getVariable [QGVAR(QTERunning), false]) exitWith {
false
};

You could move this line above the params line, as this doesn't require any arguments.


GVAR(QTEHistory) = [];
GVAR(QTERunning) = true;
private _startTime = CBA_missionTime;
private _qteArgsArray = [
["object", _object],
["args", _args],
["onDisplay", _onDisplay],
["onFinish", _onFinish],
["onFail", _onFail],
["maxDistance", _maxDistance],
["qteSeqence", _qteSequence],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor typo has slipped in (change where necessary).

Suggested change
["qteSeqence", _qteSequence],
["qteSequence", _qteSequence],

["startTime", _startTime],
["timeout", _timeout]
];
GVAR(QTEArgs) = createHashMapFromArray _qteArgsArray;

// Setup
[{
private _timeout = GVAR(QTEArgs) get "timeout";
private _object = GVAR(QTEArgs) get "object";
private _maxDistance = GVAR(QTEArgs) get "maxDistance";
private _elapsedTime = CBA_missionTime - (GVAR(QTEArgs) get "startTime");

!GVAR(QTERunning) || player distance _object > _maxDistance || _elapsedTime > _timeout;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think having player distance _object > _maxDistance as a condition is a very limiting factor. In some cases one might not want or need to have such a condition, but would rather use others.
The condition code should be passed by the user, it would be {false} by default (meaning the timeout would be the default method of ending the QTE if it isn't solved in time). object and maxDistance would no longer be needed.

You'd evaluate it by calling _args call _condition, with _args being the same args as the event/function one.
The function header would need to be adjusted accordingly.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not go a step further and remove the timeout and just pass [_args, _elapsedTime]. This would allow for unlimited time variants too. Its also standard for all functions then.

}, {
TRACE_1("QTE ended",GVAR(QTERunning));
if(!GVAR(QTERunning)) exitWith {};
GVAR(QTERunning) = false;
GVAR(QTEHistory) = [];
private _onFail = (GVAR(QTEArgs) get "onFail");
private _args = (GVAR(QTEArgs) get "args");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unnecessary parenthesis:

Suggested change
private _onFail = (GVAR(QTEArgs) get "onFail");
private _args = (GVAR(QTEArgs) get "args");
private _onFail = GVAR(QTEArgs) get "onFail";
private _args = GVAR(QTEArgs) get "args";

TRACE_1("QTE Failed",_args);
if (_onFail isEqualType "") then {
[_onFail, [_args, _elapsedTime]] call CBA_fnc_localEvent;
} else {
[_args, _elapsedTime] call _onFail;
};
}, []] call CBA_fnc_waitUntilAndExecute;

if (_onDisplay isEqualType "") then {
[_onDisplay, [_args, _qteSequence, []]] call CBA_fnc_localEvent;
} else {
[_args, _qteSequence, []] call _onDisplay;
};

true
20 changes: 20 additions & 0 deletions addons/quicktime/script_component.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#define COMPONENT quicktime
#include "\x\cba\addons\main\script_mod.hpp"

//#define DEBUG_MODE_FULL
//#define DISABLE_COMPILE_CACHE
//#define DEBUG_ENABLED_quicktime

#ifdef DEBUG_ENABLED_QUICKTIME
#define DEBUG_MODE_FULL
#endif

#ifdef DEBUG_SETTINGS_QUICKTIME
#define DEBUG_SETTINGS DEBUG_SETTINGS_QUICKTIME
#endif

#define DEBUG_SYNCHRONOUS
#include "\x\cba\addons\main\script_macros.hpp"

#include "\a3\ui_f\hpp\defineResincl.inc"

20 changes: 20 additions & 0 deletions addons/quicktime/stringtable.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<Project name="CBA_A3">
<Package name="Quicktime">
<Key ID="STR_cba_quicktime_QTEKeybindGroup">
<English>CBA Quick-Time Events</English>
</Key>
<Key ID="STR_cba_quicktime_QTEKeybindUpTooltip">
<English>Up key used in Quick-Time Events.</English>
</Key>
<Key ID="STR_cba_quicktime_QTEKeybindDownTooltip">
<English>Down key used in Quick-Time Events.</English>
</Key>
<Key ID="STR_cba_quicktime_QTEKeybindLeftTooltip">
<English>Left key used in Quick-Time Events.</English>
</Key>
<Key ID="STR_cba_quicktime_QTEKeybindRightTooltip">
<English>Right key used in Quick-Time Events.</English>
</Key>
</Package>
</Project>