// F4: play the GTA5RP whistle animation locally.
const WHISTLE_KEY = 0x73;
const DICT = 'rcmnigel1c';
const ANIM = 'hailing_whistle_waive_a';
let loading = false;
let nextWhistleAt = 0;
mp.keys.bind(WHISTLE_KEY, true, async () => {
const player = mp.players.local;
if (!player || !player.handle || mp.gui.cursor.visible) return;
if (loading || Date.now() < nextWhistleAt) return;
loading = true;
try {
mp.game.streaming.requestAnimDict(DICT);
const deadline = Date.now() + 5000;
while (!mp.game.streaming.hasAnimDictLoaded(DICT)) {
if (Date.now() >= deadline) {
throw new Error('Animation dictionary loading timed out');
}
await mp.game.waitAsync(0);
}
if (!player.handle) return;
const blend = { f_17: 0.125, f_18: 0.125 };
player.taskScriptedAnimation({
dict: DICT,
anim: ANIM,
boneMaskHash: mp.game.joaat('BONEMASK_HEAD_NECK_AND_L_ARM') >> 0,
animationFlags: 48,
f_17: 2.7,
f_18: 2.7,
}, blend, blend, 0.5, 0.5);
nextWhistleAt = Date.now() + 3500;
} catch (error) {
mp.gui.chat.push('[whistle] ' + error.message);
} finally {
loading = false;
}
});