[extension_name] MickFX Squish [extension_info] Squish effect for MickFX. Squishes webcam with a giant hammer. [extension_version] 1.0.0 [insert_external]
Starting MickFX Squish in 5...
`; statusDiv.parentNode.insertBefore(completeContainer, statusDiv.nextSibling); let timeLeft = 5; const countdownElement = document.getElementById('MickFX-Squish-Countdown'); const timer = setInterval(() => { timeLeft--; if (timeLeft > 0) { countdownElement.textContent = `Starting MickFX Squish in ${timeLeft}...`; } else { clearInterval(timer); MickFXSquishCompleteInstall(); } }, 1000); statusDiv.dataset.completeTimer = timer; return; } } catch (error) { console.error('[MickFX Squish] Error processing download stage:', error); } }); } function MickFXSquishIniCheck() { const settingsPath = MickFX_MainDirectory + "/Information/fxsettings.ini"; Promise.all([ SAMMI.loadIni(settingsPath, "Squish", "Timer", "number"), SAMMI.loadIni(settingsPath, "Squish", "Frame Choice", "number"), SAMMI.loadIni(settingsPath, "Squish", "ToT", "number"), SAMMI.loadIni(settingsPath, "Squish", "Speed", "number"), SAMMI.loadIni(settingsPath, "Squish", "Rotation", "number") ]) .then(([timer, frameChoice, toggleType, fallSpeed, rotation]) => { // Timer document.getElementById('MickFX-Squish-Timer').value = parseInt(timer.Value); // Frame Choice const frameChoiceSelect = document.getElementById('MickFX-Squish-FrameChoice'); frameChoiceSelect.value = String(parseInt(frameChoice.Value) || 0); const frameChoiceSelected = frameChoiceSelect.closest('.MickFX-FXSection-Group').querySelector('.MickFX-OptionSelected span'); // Handle Frame Choice text (including Random option) const baseText = MickFX_VTuberMode === 1 ? 'VTuber' : 'Camera'; let frameText; switch(parseInt(frameChoice.Value)) { case 1: frameText = 'Include Frame'; break; case 2: frameText = 'Random'; break; default: frameText = `Only ${baseText}`; } frameChoiceSelected.textContent = frameText; // Fall Speed const fallSpeedSelect = document.getElementById('MickFX-Squish-FallSpeed'); fallSpeedSelect.value = String(parseInt(fallSpeed.Value) || 0); const fallSpeedSelected = fallSpeedSelect.closest('.MickFX-FXSection-Group').querySelector('.MickFX-OptionSelected span'); const fallSpeedTexts = ['Slow', 'Fast', 'Random']; fallSpeedSelected.textContent = fallSpeedTexts[parseInt(fallSpeed.Value) || 0]; // Rotation const rotationSelect = document.getElementById('MickFX-Squish-Rotation'); rotationSelect.value = String(parseInt(rotation.Value) || 0); const rotationSelected = rotationSelect.closest('.MickFX-FXSection-Group').querySelector('.MickFX-OptionSelected span'); const rotationTexts = ['Off', 'On', 'Random']; rotationSelected.textContent = rotationTexts[parseInt(rotation.Value) || 0]; // Toggle Type const toggleTypeSelect = document.getElementById('MickFX-Squish-EffectType'); toggleTypeSelect.value = toggleType.Value || "0"; const toggleTypeSelected = toggleTypeSelect.closest('.MickFX-FXSection-Group').querySelector('.MickFX-OptionSelected span'); toggleTypeSelected.textContent = toggleType.Value === 1 ? "Manual Toggle" : "Timed Toggle"; // Timer visibility const timerGroup = document.getElementById('MickFX-Squish-Timer-Group'); timerGroup.style.display = toggleType.Value === 1 ? 'none' : 'block'; }) .catch(error => { console.error('[MickFX Squish] Settings Load Error:', error); }); } function MickFXSquishInstallClicked() { let MickFX_SquishInstalling = true; let statusDiv = document.getElementById('MickFX-Squish-Popup'); const installButton = document.getElementById('MickFX-Squish-InstallButton'); // Create or reset status elements if (!statusDiv) { statusDiv = document.createElement('div'); statusDiv.id = 'MickFX-Squish-Popup'; statusDiv.className = 'MickFX-Popup-ContainerFX'; statusDiv.innerHTML = ` Please wait. Setting up MickFX Squish `; installButton.parentNode.insertBefore(statusDiv, installButton); } else { // Reset existing status div statusDiv.innerHTML = ` Please wait. Setting up MickFX Squish `; } // Show status message and hide install button statusDiv.style.display = 'block'; installButton.style.display = 'none'; SAMMI.triggerButton('MickFXSquishInstall') .catch(error => console.error('[MickFX Squish] Install error:', error)); } function MickFXSquishCompleteInstall() { MickFX_SquishInstalling = false; MickFX_SquishInstalled = 1; // Clear any existing timer const timer = document.getElementById('MickFX-Squish-Popup')?.dataset.completeTimer; if (timer) clearInterval(Number(timer)); // Remove the complete container (which includes button and countdown) const completeContainer = document.getElementById('MickFX-Squish-CompleteContainer'); if (completeContainer) completeContainer.remove(); // Let BaseCheck handle the rest of the UI state MickFXSquishInit(); } function MickFXSquishSaveSettings() { const settingsPath = MickFX_MainDirectory + "/Information/fxsettings.ini"; const toggleType = document.getElementById('MickFX-Squish-EffectType').value; const timer = Math.max(0, parseInt(document.getElementById('MickFX-Squish-Timer').value) || 0); const frameChoice = document.getElementById('MickFX-Squish-FrameChoice').value; const fallSpeed = document.getElementById('MickFX-Squish-FallSpeed').value; const rotation = document.getElementById('MickFX-Squish-Rotation').value; Promise.all([ SAMMI.saveIni(settingsPath, "Squish", "ToT", toggleType, "number"), SAMMI.saveIni(settingsPath, "Squish", "Timer", timer, "number"), SAMMI.saveIni(settingsPath, "Squish", "Frame Choice", frameChoice, "number"), SAMMI.saveIni(settingsPath, "Squish", "Speed", fallSpeed, "number"), SAMMI.saveIni(settingsPath, "Squish", "Rotation", rotation, "number") ]).then(() => { MickFXHandleButton('MickFX-Squish-FXSaveButton', 'success'); }).catch(error => { console.error('[MickFX Squish] Error saving settings:', error); MickFXHandleButton('MickFX-Squish-FXSaveButton', 'error'); }); } function MickFXSquishUninstall() { const button = document.getElementById('MickFX-Squish-UninstallFXButton'); if (!button) return; if (!button.hasAttribute('data-warning-state')) { button.setAttribute('data-warning-state', 'true'); MickFXHandleButton('MickFX-Squish-UninstallFXButton', 'warning', { originalText: 'Uninstall Effect' }); } else { MickFXHandleButton('MickFX-Squish-UninstallFXButton', 'uninstalling', { duration: 0 // No auto-reset }); SAMMI.triggerButton('MickFXSquishUninstall') .catch(error => { console.error('[MickFX Squish] Error triggering uninstall:', error); MickFXHandleButton('MickFX-Squish-UninstallFXButton', 'error', { originalText: 'Uninstall Effect' }); }); } } function MickFXSquishCRCheck() { const channelPointsPath = MickFX_MainDirectory + "/Information/channelpoints.ini"; MickFXCRCallback = null; SAMMI.loadIni(channelPointsPath, "Squish", "Point ID", "string") .then((pointID) => { const createDiv = document.getElementById('MickFX-Squish-CPoints-Create'); const settingsDiv = document.getElementById('MickFX-Squish-CPoints-Settings'); if (!pointID.Value) { createDiv.style.display = 'block'; settingsDiv.style.display = 'none'; } else { createDiv.style.display = 'none'; settingsDiv.style.display = 'block'; // Load and set CP settings Promise.all([ SAMMI.loadIni(channelPointsPath, "Squish", "Cost", "number"), SAMMI.loadIni(channelPointsPath, "Squish", "Timer", "number"), SAMMI.loadIni(channelPointsPath, "Squish", "Name", "string"), SAMMI.loadIni(channelPointsPath, "Squish", "Description", "string") ]).then(([cost, timer, name, description]) => { const nameInput = document.getElementById('MickFX-Squish-CPoints-Name'); nameInput.value = name.Value || ''; nameInput.dataset.originalName = name.Value || ''; // Store original name in the element document.getElementById('MickFX-Squish-CPoints-Cost').value = parseInt(cost.Value); document.getElementById('MickFX-Squish-CPoints-Timer').value = parseInt(timer.Value); document.getElementById('MickFX-Squish-CPoints-Description').value = description.Value || ''; }); } const cpContainer = document.getElementById('MickFX-Squish-Discord-ChannelPoints-Container'); if (cpContainer) { // Check current Discord settings to see if we should show it const screenshotEnabled = document.getElementById('MickFX-Squish-Discord-Enable')?.checked; const overrideEnabled = document.getElementById('MickFX-Squish-Discord-Override')?.checked; const channelPointRewardExists = settingsDiv.style.display !== 'none'; cpContainer.style.display = (screenshotEnabled && overrideEnabled && channelPointRewardExists) ? 'flex' : 'none'; } }) .catch(error => { console.error('[MickFX Squish] Channel Points Error:', error); }); } function MickFXSquishCRCreateReward() { const buttonId = 'MickFX-Squish-CPoints-CreateButton'; MickFXHandleButton(buttonId, 'creating', { duration: 2000}); const channelPointsPath = MickFX_MainDirectory + "/Information/channelpoints.ini"; MickFXCRCallback = (exists) => { if (exists) { MickFXShowChoice( buttonId, "Reward name 'Squish!' already exists or you reached the max reward limit of 50. Delete the previous reward, or use a different name.", "Go Back", "Let Me Name The Reward", MickFXSquishCRGoBack, MickFXSquishCRShowNameInput, 15000, [30, 70] // Width distribution for buttons ); MickFXHandleButton(buttonId, 'error', { duration: 15000, text: 'Creation Failed' }); } else { SAMMI.saveIni(channelPointsPath, "Squish", "Reward Choice", 1, "number") .then(() => { SAMMI.triggerButton('MickFXSquishCRSave'); MickFXHandleButton(buttonId, 'success', { text: 'Reward Created!' }); MickFXCRCallback = null; }) .catch(error => { console.error('[MickFX Squish] Channel Points Error:', error); SAMMI.alert('Failed to create channel point reward'); MickFXHandleButton(buttonId, 'error', { text: 'Creation Failed' }); }); } }; // First save the Reward Choice, then trigger the extension SAMMI.saveIni(channelPointsPath, "Squish", "Reward Choice", 1, "number") .then(() => { SAMMI.triggerButton('MickFXSquishCRSave'); }) .catch(error => { console.error('[MickFX Squish] Error setting initial Reward Choice:', error); MickFXHandleButton(buttonId, 'error', { text: 'Creation Failed' }); }); } function MickFXSquishCRShowNameInput() { const createSection = document.getElementById('MickFX-Squish-CPoints-Create'); const createButton = document.getElementById('MickFX-Squish-CPoints-CreateButton'); // Remove any existing choice container const choiceId = `${createButton.id}-choice`; const existingChoice = document.getElementById(choiceId); if (existingChoice) { existingChoice.remove(); } // Create custom name input container const inputContainer = document.createElement('div'); inputContainer.id = 'MickFXSquishCRNameContainer'; inputContainer.innerHTML = `