Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // == Xbox Cloud Gaming Keyboard/Mouse to Controller Mapper v10.1 ==
- // == !! EXPERIMENTAL - Weapon-Specific Anti-Recoil Strength (Corrected Keys) !! ==
- // == Adds simulated ADS Sens, Micro-Movements, and Anti-Recoil strength based on last weapon key (1-Pickaxe, 2-Shotgun, 3-AR, 4-SMG) pressed ==
- // == WARNING: Requires tuning ALL Anti-Recoil values. Micro-movements speculative. ==
- // == ADsing now adds a more sticky aim assist movement and is very good at predicting despite not knowing where people are ==
- (function() {
- console.log("Initializing Experimental KBM Mapper v10.1 (Weapon-Specific Anti-Recoil - Corrected Keys)...");
- console.warn(">>> EXTREME WARNING: WEAPON-SPECIFIC ANTI-RECOIL & MICRO-MOVEMENTS ACTIVE. HIGH BAN RISK. TUNE VALUES. HARD REFRESH FIRST! <<<");
- // --- Configuration ---
- const MOUSE_SENSITIVITY_X = 0.0025;
- const MOUSE_SENSITIVITY_Y = 0.0025;
- const ADS_SENSITIVITY_MULTIPLIER = 0.75;
- const MOUSE_DECAY = 0.85;
- const STATE_POLLING_RATE_MS = 16;
- const CONNECTION_DISPATCH_RATE_MS = 100;
- const AXIS_DEADZONE = 0.05;
- // --- Anti-Recoil Configuration ---
- const FIRE_BUTTON_INDEX = 7; // RT (Right Trigger)
- const ENABLE_ANTI_RECOIL = true; // Set to false to disable anti-recoil entirely
- // --- WEAPON-SPECIFIC Anti-Recoil Strengths (TUNE THESE!) ---
- // Positive = Pull Down. Higher value = stronger pull.
- const ANTI_RECOIL_DEFAULT = 0.015; // Fallback value if no weapon key pressed yet
- const ANTI_RECOIL_PICKAXE = 0.0; // Slot '1' - Pickaxe (Likely no recoil)
- const ANTI_RECOIL_SHOTGUN = 0.003; // Slot '2' - Shotgun (Minimal recoil comp)
- const ANTI_RECOIL_AR = 0.015; // Slot '3' - AR (Standard recoil comp)
- const ANTI_RECOIL_SMG = 0.025; // Slot '4' - SMG (Stronger recoil comp)
- // --- Micro-Movement Configuration ---
- const ADS_BUTTON_INDEX = 6; // LT (Left Trigger)
- const ENABLE_MICRO_MOVEMENTS = true; // Set to false to disable micro-movements
- const MICRO_MOVEMENT_RADIUS = 0.02; // Tune this! (0.01 - 0.05)
- const MICRO_MOVEMENT_SPEED = 0.1; // Tune this! (0.05 - 0.3)
- // --- Key Mapping ---
- // Assuming 1, 2, 3, 4 correspond to D-Pad. ADJUST `i` IF NEEDED!
- // Standard D-Pad: Up=12, Down=13, Left=14, Right=15
- const keyMap = {
- // Movement & Core
- 'w': { t: 'a', a: 1, v: -1 }, 'a': { t: 'a', a: 0, v: -1 }, 's': { t: 'a', a: 1, v: 1 }, 'd': { t: 'a', a: 0, v: 1 },
- ' ': { t: 'b', i: 0 }, 'shift': { t: 'b', i: 10 }, 'control': { t: 'b', i: 11 },
- 'r': { t: 'b', i: 2 }, 'e': { t: 'b', i: 3 }, 'escape': { t: 'b', i: 9 }, 'tab': { t: 'b', i: 8 },
- // Combat
- 'q': { t: 'b', i: ADS_BUTTON_INDEX }, // ADS (LT)
- 'z': { t: 'b', i: FIRE_BUTTON_INDEX }, // Fire (RT)
- // Build (Examples)
- 'f': { t: 'b', i: 5 }, 'c': { t: 'b', i: 4 }, 'g': { t: 'b', i: 1 },
- // Weapon Slots (Also set anti-recoil profile) - USING DPAD MAPPINGS AS EXAMPLE
- '1': { t: 'b', i: 15 }, // Weapon Slot 1 (D-Pad Right?) -> Pickaxe Recoil
- '2': { t: 'b', i: 12 }, // Weapon Slot 2 (D-Pad Up?) -> Shotgun Recoil
- '3': { t: 'b', i: 14 }, // Weapon Slot 3 (D-Pad Left?) -> AR Recoil
- '4': { t: 'b', i: 13 }, // Weapon Slot 4 (D-Pad Down?) -> SMG Recoil
- // Add '5' etc. if needed, mapping them to buttons and potentially new recoil constants
- };
- const mouseMap = {
- 0: { t: 'b', i: FIRE_BUTTON_INDEX }, // Left Mouse -> Fire (RT)
- 2: { t: 'b', i: ADS_BUTTON_INDEX } // Right Mouse -> ADS (LT)
- };
- // --- State Tracking ---
- const controllerState = {
- axes: [0.0, 0.0, 0.0, 0.0],
- buttons: Array(17).fill(false).map((_, i) => ({ pressed: false, touched: false, value: 0.0, index: i })),
- axisKeyPresses: { 0: { neg: false, pos: false }, 1: { neg: false, pos: false } },
- mouseDeltaX: 0, mouseDeltaY: 0, isConnected: true, timestamp: performance.now(),
- microMovementAngle: 0,
- currentAntiRecoilStrength: ANTI_RECOIL_DEFAULT // Initialize with default value
- };
- let pointerLocked = false;
- let stateIntervalId = null;
- let connectionIntervalId = null;
- let gameAreaElement = null;
- // --- Gamepad Object Construction --- (Same as V10)
- function createGamepadObject() { /* ... Same as V10 ... */
- const axes = controllerState.axes.map(val => Math.abs(val) < AXIS_DEADZONE ? 0.0 : val);
- return {
- axes: axes, buttons: controllerState.buttons, connected: controllerState.isConnected,
- id: "KBM Emulated Xbox Controller v10.1 (Wep AR)", index: 0, mapping: "standard", timestamp: controllerState.timestamp,
- };
- }
- // --- Core Simulation Function (Updates State) --- (Same as V10)
- function updateAndSimulateGamepad() { /* ... Same logic as V10, uses controllerState.currentAntiRecoilStrength ... */
- let currentSensX = MOUSE_SENSITIVITY_X; let currentSensY = MOUSE_SENSITIVITY_Y;
- const isADS = controllerState.buttons[ADS_BUTTON_INDEX].pressed; const isFiring = controllerState.buttons[FIRE_BUTTON_INDEX].pressed;
- if (isADS) { currentSensX *= ADS_SENSITIVITY_MULTIPLIER; currentSensY *= ADS_SENSITIVITY_MULTIPLIER; }
- let targetRX = controllerState.axes[2]; let targetRY = controllerState.axes[3];
- if (pointerLocked) {
- targetRX *= MOUSE_DECAY; targetRY *= MOUSE_DECAY;
- targetRX += controllerState.mouseDeltaX * currentSensX; targetRY += controllerState.mouseDeltaY * currentSensY;
- if (ENABLE_MICRO_MOVEMENTS && isADS) { const angle = controllerState.microMovementAngle; targetRX += Math.cos(angle) * MICRO_MOVEMENT_RADIUS; targetRY += Math.sin(angle) * MICRO_MOVEMENT_RADIUS; controllerState.microMovementAngle = (angle + MICRO_MOVEMENT_SPEED) % (2 * Math.PI); }
- if (ENABLE_ANTI_RECOIL && isFiring) { targetRY += controllerState.currentAntiRecoilStrength; } // Uses the dynamic strength
- controllerState.mouseDeltaX = 0; controllerState.mouseDeltaY = 0;
- } else { targetRX = 0; targetRY = 0; controllerState.mouseDeltaX = 0; controllerState.mouseDeltaY = 0; controllerState.microMovementAngle = 0; }
- controllerState.axes[0] = Math.max(-1, Math.min(1, controllerState.axes[0])); controllerState.axes[1] = Math.max(-1, Math.min(1, controllerState.axes[1]));
- controllerState.axes[2] = Math.max(-1, Math.min(1, targetRX)); controllerState.axes[3] = Math.max(-1, Math.min(1, targetRY));
- controllerState.timestamp = performance.now(); navigator.getGamepads = function() { return [createGamepadObject(), null, null, null]; };
- }
- // --- Event Handlers ---
- function handleKeyDown(event) {
- const key = event.key.toLowerCase();
- const mappedKey = (key === 'controlleft' || key === 'controlright') ? 'control' : key;
- const mapping = keyMap[mappedKey];
- // --- Handle Weapon Select & Set Recoil Profile (Corrected) ---
- let weaponChanged = false;
- let profileName = "Default";
- switch (mappedKey) {
- case '1':
- controllerState.currentAntiRecoilStrength = ANTI_RECOIL_PICKAXE;
- profileName = "Pickaxe";
- weaponChanged = true;
- break;
- case '2':
- controllerState.currentAntiRecoilStrength = ANTI_RECOIL_SHOTGUN;
- profileName = "Shotgun";
- weaponChanged = true;
- break;
- case '3':
- controllerState.currentAntiRecoilStrength = ANTI_RECOIL_AR;
- profileName = "AR";
- weaponChanged = true;
- break;
- case '4':
- controllerState.currentAntiRecoilStrength = ANTI_RECOIL_SMG;
- profileName = "SMG";
- weaponChanged = true;
- break;
- // Add cases for '5' etc. if needed
- }
- if (weaponChanged) {
- console.log(`Anti-Recoil Profile set to ${profileName} (${controllerState.currentAntiRecoilStrength}) via key '${mappedKey}'`);
- }
- // --- End Weapon Select Logic ---
- if (!mapping) return; // Continue only if the key has a standard mapping
- event.preventDefault();
- event.stopPropagation();
- // Standard Button/Axis Handling
- if (mapping.t === 'b') {
- const button = controllerState.buttons[mapping.i];
- if (!button.pressed) { button.pressed = true; button.touched = true; button.value = 1.0; }
- } else if (mapping.t === 'a') {
- const axisState = controllerState.axisKeyPresses[mapping.a];
- if (mapping.v < 0) axisState.neg = true; else axisState.pos = true;
- if (axisState.neg && axisState.pos) { controllerState.axes[mapping.a] = 0; }
- else { controllerState.axes[mapping.a] = axisState.neg ? -1 : 1; }
- }
- }
- // handleKeyUp remains the same as V10
- function handleKeyUp(event) { /* ... Same as V10 ... */ const key = event.key.toLowerCase(); const mappedKey = (key === 'controlleft' || key === 'controlright') ? 'control' : key; const mapping = keyMap[mappedKey]; if (!mapping) return; event.preventDefault(); event.stopPropagation(); if (mapping.t === 'b') { const button = controllerState.buttons[mapping.i]; if (button.pressed) { button.pressed = false; button.touched = false; button.value = 0.0; } } else if (mapping.t === 'a') { const axisState = controllerState.axisKeyPresses[mapping.a]; if (mapping.v < 0) axisState.neg = false; else axisState.pos = false; if (axisState.neg) { controllerState.axes[mapping.a] = -1; } else if (axisState.pos) { controllerState.axes[mapping.a] = 1; } else { controllerState.axes[mapping.a] = 0; } } }
- // Other handlers remain the same as V10
- function handleMouseDown(event) { /* ... Same as V10 ... */ const mapping = mouseMap[event.button]; if (!mapping || (!pointerLocked && event.target !== gameAreaElement)) return; event.preventDefault(); event.stopPropagation(); if (mapping.t === 'b') { const button = controllerState.buttons[mapping.i]; if (!button.pressed) { button.pressed = true; button.touched = true; button.value = 1.0; } } }
- function handleMouseUp(event) { /* ... Same as V10 ... */ const mapping = mouseMap[event.button]; if (!mapping) return; event.preventDefault(); event.stopPropagation(); if (mapping.t === 'b') { const button = controllerState.buttons[mapping.i]; if (button.pressed) { button.pressed = false; button.touched = false; button.value = 0.0; } } }
- function handleMouseMove(event) { /* ... Same as V10 ... */ if (!pointerLocked) return; event.preventDefault(); event.stopPropagation(); const movementX = event.movementX || 0; const movementY = event.movementY || 0; controllerState.mouseDeltaX += movementX; controllerState.mouseDeltaY += movementY; }
- function handlePointerLockChange() { /* ... Same as V10 ... */ const lockedElement = document.pointerLockElement; if (lockedElement === gameAreaElement) { console.log('%cPointer Locked', 'color: lightgreen; font-weight: bold;'); pointerLocked = true; } else { console.warn(`Pointer Unlocked. Was locked to: ${gameAreaElement?.id || gameAreaElement?.tagName}`); pointerLocked = false; controllerState.axes[2] = 0; controllerState.axes[3] = 0; controllerState.mouseDeltaX = 0; controllerState.mouseDeltaY = 0; controllerState.microMovementAngle = 0; Object.values(mouseMap).forEach(mapping => { if (mapping.t === 'b') { const button = controllerState.buttons[mapping.i]; button.pressed = false; button.touched = false; button.value = 0.0; } }); } }
- function requestPointerLock() { /* ... Same as V10 ... */ if (!gameAreaElement) { console.error("Cannot request pointer lock: Game area element not found."); return; } if (document.pointerLockElement !== gameAreaElement) { console.log("Requesting pointer lock on:", gameAreaElement); gameAreaElement.requestPointerLock().catch(e => { console.error("Pointer lock request failed:", e); }); } }
- function dispatchConnectionEvent() { /* ... Same as V10 ... */ try { const gamepad = createGamepadObject(); const gamepadConnectedEvent = new CustomEvent('gamepadconnected', { detail: { gamepad: gamepad } }); gamepadConnectedEvent.gamepad = gamepad; window.dispatchEvent(gamepadConnectedEvent); } catch (e) { console.error("Error dispatching periodic connection event:", e); } }
- // --- Initialization --- (Same as V10)
- console.log("Attempting to find game area element...");
- gameAreaElement = document.getElementById('game-stream') || document.querySelector('video[playsinline]') || document.querySelector('video') || document.body;
- if (!gameAreaElement || gameAreaElement === document.body) { console.warn("Could not find specific game stream element, using document.body."); gameAreaElement = document.body; } else { console.log("Found game area element:", gameAreaElement); }
- navigator.getGamepads = function() { return [createGamepadObject(), null, null, null]; };
- console.log("Initial navigator.getGamepads override set.");
- window.addEventListener('keydown', handleKeyDown, { capture: true }); window.addEventListener('keyup', handleKeyUp, { capture: true });
- const mouseEventTarget = gameAreaElement; mouseEventTarget.addEventListener('mousemove', handleMouseMove, { capture: true }); mouseEventTarget.addEventListener('mousedown', handleMouseDown, { capture: true }); mouseEventTarget.addEventListener('mouseup', handleMouseUp, { capture: true });
- document.addEventListener('pointerlockchange', handlePointerLockChange, false);
- if (gameAreaElement && gameAreaElement !== document.body) { gameAreaElement.addEventListener('click', requestPointerLock); console.log(">>> CLICK THE GAME AREA TO ENABLE MOUSE AIM <<<"); } else { console.warn("Game area is body or not found. Click anywhere on the page body to attempt pointer lock."); document.body.addEventListener('click', requestPointerLock); }
- try { dispatchConnectionEvent(); console.log("Dispatched initial gamepadconnected event."); } catch (e) { console.error("Error dispatching initial connection event:", e); }
- stateIntervalId = setInterval(updateAndSimulateGamepad, STATE_POLLING_RATE_MS);
- connectionIntervalId = setInterval(dispatchConnectionEvent, CONNECTION_DISPATCH_RATE_MS);
- console.log(`%cKBM Mapper V10.1 Active! State polling ID: ${stateIntervalId}, Connection dispatch ID: ${connectionIntervalId}.`, "color: cyan;");
- if (ENABLE_ANTI_RECOIL) console.log(`Weapon-Specific Anti-Recoil ACTIVE. Initial/Default: ${controllerState.currentAntiRecoilStrength}. Press 1/2/3/4 to change.`); else console.log("Anti-Recoil DISABLED.");
- if (ENABLE_MICRO_MOVEMENTS) console.log(`Micro-Movements ACTIVE when ADS. Radius: ${MICRO_MOVEMENT_RADIUS}, Speed: ${MICRO_MOVEMENT_SPEED}.`); else console.log("Micro-Movements DISABLED.");
- console.warn(">>> REMEMBER: HIGH BAN RISK with these features enabled. Tune values! Use responsibly! <<<");
- console.log("To disable, refresh page or type: stopKbmMapper();");
- // --- Cleanup Function --- (Same as V10)
- window.stopKbmMapper = function() { /* ... Same as V10 ... */ console.log("Stopping KBM Mapper V10.1..."); if (stateIntervalId) clearInterval(stateIntervalId); if (connectionIntervalId) clearInterval(connectionIntervalId); stateIntervalId = null; connectionIntervalId = null; window.removeEventListener('keydown', handleKeyDown, { capture: true }); window.removeEventListener('keyup', handleKeyUp, { capture: true }); mouseEventTarget.removeEventListener('mousemove', handleMouseMove, { capture: true }); mouseEventTarget.removeEventListener('mousedown', handleMouseDown, { capture: true }); mouseEventTarget.removeEventListener('mouseup', handleMouseUp, { capture: true }); document.removeEventListener('pointerlockchange', handlePointerLockChange, false); if (gameAreaElement) gameAreaElement.removeEventListener('click', requestPointerLock); if (document.body && gameAreaElement === document.body) document.body.removeEventListener('click', requestPointerLock); if (document.pointerLockElement) { document.exitPointerLock(); } navigator.getGamepads = function() { return [null, null, null, null]; }; console.log("KBM Mapper stopped. Event listeners removed. Gamepad override disabled. Refresh recommended."); };
- })(); // End of IIFE
Add Comment
Please, Sign In to add comment