qte is a compact Quick Time Event and skill-check include for SA-MP 0.3.7 and open.mp. It creates a PlayerTextDraw timing bar, moves a pointer across the track, and reports success or failure through callbacks.
The include is designed for roleplay interactions such as lockpicking, fishing, repair jobs, crafting checks, medical actions, and other short timing-based tasks.
| Feature | Description |
|---|---|
| Timing bar | Displays a track, moving pointer, success zone, key prompt, and stage counter. |
| Multi-stage checks | Requires one or more successful hits before the QTE completes. |
| PlayerTextDraw lifecycle | Creates, updates, and destroys all QTE textdraws per player. |
| Framework compatibility | Supports SA-MP 0.3.7 and open.mp, including tagged KEY, textdraw font, and alignment arguments. |
| Callback integration | Reports stage success, stage failure, cancellation, and final result through public callbacks. |
| Runtime state getters | Exposes active stage, total stages, pointer position, and extra_id for surrounding systems. |
| Runtime styling | Allows each player or feature to set its own layout, colors, text, and sounds before starting a QTE. |
| Default macros | Provides compile-time defaults for servers that want one shared style. |
| Hook compatibility | Uses y_hooks when present and falls back to ALS-style callback chaining otherwise. |
| Step | Action |
|---|---|
| 1 | Place qte.inc in your pawno/include directory. |
| 2 | Include <open.mp> or <a_samp> before qte. |
| 3 | Start a QTE with StartPlayerQTE and handle the result in callbacks. |
sa-mp :
#include <a_samp>
#include <qte>open.mp:
#include <open.mp>
#include <qte>#include <open.mp>
#include <zcmd>
#include <qte>
#define QTE_LOCKPICK (101)
CMD:lockpick(playerid, params[])
{
if(IsPlayerInQTE(playerid))
{
return SendClientMessage(playerid, 0xE74C3CFF, "You are already doing a skill check.");
}
QTE_ResetPlayerStyle(playerid);
SetPlayerQTEColors(playerid, 0x111827FF, 0x38BDF8FF, 0xF97316FF, 0xFFFFFFFF, 0xE5E7EBFF);
SetPlayerQTEText(playerid, "~w~LOCKPICK ~y~[%s] ~w~ON GREEN", "~y~PIN ~w~%d/%d");
StartPlayerQTE(playerid, KEY_WALK, 3.0, 20.0, 3, QTE_LOCKPICK);
SendClientMessage(playerid, 0xF1C40FFF, "Press ALT/WALK when the pointer enters the green zone.");
return 1;
}
public OnPlayerQTEComplete(playerid, bool:success, stages_cleared, total_stages, extra_id)
{
if(extra_id != QTE_LOCKPICK)
{
return 1;
}
if(success)
{
SendClientMessage(playerid, 0x2ECC71FF, "Lockpick completed.");
}
else
{
SendClientMessage(playerid, 0xE74C3CFF, "Lockpick failed.");
}
return 1;
}
public OnPlayerQTEResult(playerid, result, stages_cleared, total_stages, extra_id)
{
if(extra_id == QTE_LOCKPICK && result == QTE_RESULT_CANCELLED)
{
SendClientMessage(playerid, 0xAAAAAAFF, "Lockpick cancelled.");
}
return 1;
}| Function | Returns | Description |
|---|---|---|
StartPlayerQTE(playerid, KEY:key = KEY_SPRINT, Float:speed = 2.5, Float:zone_size = 20.0, stages = 1, extra_id = 0) |
1 on start, 0 for invalid player |
Starts or replaces a player's active QTE. |
StopPlayerQTE(playerid) |
1 when stopped, 0 when inactive or invalid |
Cancels the active QTE, kills its timer, destroys its UI, and emits cancellation callbacks. |
bool:IsPlayerInQTE(playerid) |
true or false |
Checks whether the player currently has an active QTE. |
GetPlayerQTEStage(playerid) |
int |
Returns the player's current stage, or 0 for invalid players. |
GetPlayerQTETotalStages(playerid) |
int |
Returns the configured stage count, or 0 for invalid players. |
GetPlayerQTEExtraID(playerid) |
int |
Returns the custom identifier passed to StartPlayerQTE. |
KEY:GetPlayerQTEKey(playerid) |
KEY: |
Returns the key assigned to the active QTE. |
Float:GetPlayerQTEZoneSize(playerid) |
Float: |
Returns the success zone width percentage. |
Float:GetPlayerQTEPosition(playerid) |
Float: |
Returns the current pointer position from 0.0 to 100.0. |
QTE_GetResultName(result, dest[], size = sizeof(dest)) |
1 |
Writes success, failed, cancelled, or unknown into dest. |
QTE_ResetPlayerStyle(playerid) |
1 on success |
Resets a player's style to the macro defaults. |
SetPlayerQTELayout(playerid, orientation, Float:left, Float:top, Float:length, Float:thickness) |
1 on success |
Sets horizontal or vertical layout for one player. |
SetPlayerQTEColors(playerid, track_color, zone_color, pointer_color, prompt_color = -1, stage_color = -1) |
1 on success |
Sets bar, zone, pointer, prompt, and stage colors for one player. |
SetPlayerQTEText(playerid, const prompt_format[], const stage_format[]) |
1 on success |
Sets prompt and stage formats for one player. |
SetPlayerQTETextDrawStyle(playerid, Float:prompt_offset_y, Float:stage_offset_y, Float:prompt_letter_x = QTE_PROMPT_LETTER_X, Float:prompt_letter_y = QTE_PROMPT_LETTER_Y, Float:stage_letter_x = QTE_STAGE_LETTER_X, Float:stage_letter_y = QTE_STAGE_LETTER_Y) |
1 on success |
Sets text offsets and letter sizes for one player. |
SetPlayerQTESounds(playerid, success_sound, fail_sound) |
1 on success |
Sets success and failure sounds for one player. |
| Parameter | Type | Default | Notes |
|---|---|---|---|
playerid |
int |
Required | Target player. |
key |
KEY: |
KEY_SPRINT |
Key that must be pressed to pass a stage. Prefer KEY_YES, KEY_NO, KEY_SPRINT, or KEY_ACTION for Android-friendly public features. Use KEY_WALK for ALT/WALK prompts on desktop clients. |
speed |
Float: |
2.5 |
Pointer movement per tick. Higher values make the QTE harder. |
zone_size |
Float: |
20.0 |
Success zone width as a percentage of the track. Clamped between QTE_ZONE_MIN_SIZE and QTE_ZONE_MAX_SIZE. |
stages |
int |
1 |
Number of successful hits required. Values below 1 are clamped to 1. |
extra_id |
int |
0 |
Custom identifier passed back to callbacks. Useful when multiple systems use QTEs. |
| Callback | When It Runs |
|---|---|
OnPlayerQTESuccessStage(playerid, current_stage, total_stages, extra_id) |
After a player hits the correct key inside the success zone. |
OnPlayerQTEFailedStage(playerid, current_stage, total_stages, extra_id) |
After a player hits the correct key outside the success zone. |
OnPlayerQTEComplete(playerid, bool:success, stages_cleared, total_stages, extra_id) |
After the QTE succeeds completely or fails. |
OnPlayerQTECancel(playerid, stages_cleared, total_stages, extra_id) |
After StopPlayerQTE cancels an active QTE. Also runs when an active QTE is replaced or the player disconnects. |
OnPlayerQTEResult(playerid, result, stages_cleared, total_stages, extra_id) |
After success, failure, or cancellation. Use this when one callback should handle every end state. |
Example callback signatures:
forward OnPlayerQTEComplete(playerid, bool:success, stages_cleared, total_stages, extra_id);
forward OnPlayerQTESuccessStage(playerid, current_stage, total_stages, extra_id);
forward OnPlayerQTEFailedStage(playerid, current_stage, total_stages, extra_id);
forward OnPlayerQTECancel(playerid, stages_cleared, total_stages, extra_id);
forward OnPlayerQTEResult(playerid, result, stages_cleared, total_stages, extra_id);| Constant | Value | Meaning |
|---|---|---|
QTE_RESULT_SUCCESS |
1 |
All required stages were completed. |
QTE_RESULT_FAILED |
2 |
The player pressed the target key outside the success zone. |
QTE_RESULT_CANCELLED |
3 |
The QTE was stopped before success or failure. |
Use the runtime style functions when different systems need different QTE looks. This works well in gamemodes where lockpicking, fishing, repair jobs, and other features live in separate script modules.
Call QTE_ResetPlayerStyle(playerid) before applying a feature-specific style if you do not want the player to inherit the style from the previous QTE.
#define QTE_FISHING (201)
StartFishingQTE(playerid)
{
QTE_ResetPlayerStyle(playerid);
SetPlayerQTELayout(playerid, QTE_ORIENTATION_VERTICAL, 585.0, 170.0, 170.0, 12.0);
SetPlayerQTEColors(playerid, 0x082F49FF, 0x22C55EFF, 0xF8FAFCFF, 0xFFFFFFFF, 0xE5E7EBFF);
SetPlayerQTEText(playerid, "~w~FISHING ~y~[%s] ~w~ON GREEN", "~y~FISH ~w~%d/%d");
SetPlayerQTETextDrawStyle(playerid, -22.0, 6.0);
return StartPlayerQTE(playerid, KEY_SPRINT, 2.4, 24.0, 2, QTE_FISHING);
}| Function | Notes |
|---|---|
QTE_ResetPlayerStyle |
Copies the compile-time defaults into the player's runtime style. |
SetPlayerQTELayout |
Use QTE_ORIENTATION_HORIZONTAL or QTE_ORIENTATION_VERTICAL. length is width for horizontal bars and height for vertical bars. |
SetPlayerQTEColors |
Accepts Pawn RGBA colors such as 0x2ECC71FF. |
SetPlayerQTEText |
Prompt format must contain one %s for the key name. Stage format receives current stage and total stages. |
SetPlayerQTETextDrawStyle |
Adjusts prompt/stage vertical offsets and textdraw letter sizes. |
SetPlayerQTESounds |
Set either sound to 0 if your script wants silence. |
Define these before including qte only when you want to change the default style for the whole script. Runtime setters can still override these defaults per player before StartPlayerQTE.
| Macro | Default | Description |
|---|---|---|
QTE_ORIENTATION |
QTE_ORIENTATION_HORIZONTAL |
Track direction. Use QTE_ORIENTATION_HORIZONTAL or QTE_ORIENTATION_VERTICAL. |
QTE_TICK_RATE |
40 |
Timer interval in milliseconds. Lower values make movement smoother and call the timer more often. |
QTE_ZONE_MIN_SIZE |
5.0 |
Minimum allowed success zone width. |
QTE_ZONE_MAX_SIZE |
80.0 |
Maximum allowed success zone width. |
QTE_ZONE_START_MIN |
10.0 |
Lowest random start position for the success zone. |
QTE_ZONE_START_MAX |
90.0 |
Upper bound used when rolling the success zone. |
QTE_TRACK_LEFT |
220.0 |
Left position of the QTE track on the 640x448 textdraw canvas. |
QTE_TRACK_WIDTH |
200.0 |
Width of the QTE track. |
QTE_TRACK_TOP |
375.0 |
Top position of the QTE track. |
QTE_TRACK_HEIGHT |
14.0 |
Height of the QTE track. |
QTE_PROMPT_OFFSET_Y |
-20.0 |
Vertical offset for the prompt relative to QTE_TRACK_TOP. |
QTE_STAGE_OFFSET_Y |
4.0 |
Vertical spacing below the track for the stage counter. |
QTE_PROMPT_LETTER_X |
0.28 |
Prompt text letter width. |
QTE_PROMPT_LETTER_Y |
1.2 |
Prompt text letter height. |
QTE_STAGE_LETTER_X |
0.24 |
Stage counter letter width. |
QTE_STAGE_LETTER_Y |
1.1 |
Stage counter letter height. |
QTE_TRACK_COLOR |
0x1A1A1AFF |
Background track color. |
QTE_ZONE_COLOR |
0x2ECC71FF |
Success zone color. |
QTE_POINTER_COLOR |
0xE74C3CFF |
Moving pointer color. |
QTE_PROMPT_COLOR |
-1 |
Prompt text color. |
QTE_STAGE_COLOR |
-1 |
Stage counter text color. |
QTE_PROMPT_FORMAT |
"~w~PRESS ~y~[%s] ~w~IN THE GREEN ZONE!" |
Prompt format. Must contain one %s placeholder for the key name. |
QTE_PROMPT_SIZE |
96 |
Buffer size used for the formatted prompt. Increase this for longer translated prompts. |
QTE_STAGE_FORMAT |
"~y~STAGE ~w~%d/%d" |
Stage counter format. Receives current stage and total stages. |
QTE_STAGE_SIZE |
32 |
Buffer size used for the formatted stage text. |
QTE_SUCCESS_SOUND |
1083 |
Sound played when a stage is hit correctly. |
QTE_FAIL_SOUND |
1085 |
Sound played when a stage is missed. |
Global default example:
#define QTE_TICK_RATE 35
#define QTE_ZONE_MIN_SIZE 8.0
#define QTE_ZONE_MAX_SIZE 65.0
#define QTE_TRACK_TOP 360.0
#define QTE_TRACK_COLOR 0x111827FF
#define QTE_ZONE_COLOR 0x38BDF8FF
#define QTE_POINTER_COLOR 0xF97316FF
#define QTE_PROMPT_COLOR 0xFFFFFFFF
#define QTE_STAGE_COLOR 0xE5E7EBFF
#define QTE_PROMPT_FORMAT "~w~TEKAN ~y~[%s] ~w~SAAT MASUK AREA HIJAU"
#define QTE_PROMPT_SIZE 128
#define QTE_STAGE_FORMAT "~y~PIN ~w~%d/%d"
#define QTE_SUCCESS_SOUND 1057
#define QTE_FAIL_SOUND 1085
#include <open.mp>
#include <qte>This makes the default style vertical for the whole script. For per-feature vertical QTEs, prefer SetPlayerQTELayout.
#define QTE_ORIENTATION QTE_ORIENTATION_VERTICAL
#define QTE_TRACK_LEFT 585.0
#define QTE_TRACK_TOP 170.0
#define QTE_TRACK_WIDTH 170.0
#define QTE_TRACK_HEIGHT 12.0
#define QTE_PROMPT_OFFSET_Y -22.0
#define QTE_STAGE_OFFSET_Y 6.0
#include <open.mp>
#include <qte>| Area | Details |
|---|---|
| TextDraw tags | The include uses tagged alignment and font values to avoid open.mp tag mismatch warnings. |
| Key tags | StartPlayerQTE accepts KEY: values, matching open.mp's callback prototype. |
| TextDraw colour spelling | open.mp uses PlayerTextDrawColour; SA-MP uses PlayerTextDrawColor. The include selects the available spelling internally. |
| Callback chaining | If y_hooks is loaded, hooks are used. Otherwise, ALS-style chaining is used for OnPlayerKeyStateChange and OnPlayerDisconnect. |
Android clients can map some controls differently from desktop clients. For public features, prefer simple keys such as KEY_YES, KEY_NO, KEY_SPRINT, and KEY_ACTION. For desktop ALT/WALK prompts, use KEY_WALK.
| Recommended key | Typical prompt |
|---|---|
KEY_YES |
Y |
KEY_NO |
N |
KEY_SPRINT |
SPACE / SPRINT |
KEY_ACTION |
ACTION |
KEY_WALK |
ALT / WALK |
Released under the MIT License. See LICENSE.
