// ==UserScript==
// @name Sploop.io Enhanced Visuals
// @version 1.7
// @description Hitbox markers + adjustable transparency for objects (Improved UI)
// @namespace EHD
// @match *://sploop.io/
// @grant none
// ==/UserScript==
// ===== Configuration =====
let hitboxesVisible = true;
let controlsVisible = true;
// Transparency settings
let FARM_OPACITY = 0.4;
let TS_OPACITY = 1;
let HAT_OPACITY = 1;
// Hitbox settings
const item_radius = {
// Placed objects
trap: 40,
spike: 45,
hard_spike: 45,
big_spike: 42,
boost: 40,
wall: 45,
wood_farm: 80,
wood_farm_cherry: 80,
stone_farm: 60,
bush: 50,
// Held items
trap_item: 40,
spike_item: 45,
hard_spike_item: 45,
big_spike_item: 42,
boost_item: 40,
wall_item: 45,
wood_farm_item: 80,
wood_farm_cherry_item: 80,
stone_farm_item: 60,
berry_farm: 50
};
const hitboxColor = '#50C878';
// ===== UI Elements =====
// Create main controls container
const controlsContainer = document.createElement('div');
controlsContainer.style.position = 'fixed';
controlsContainer.style.top = '10px';
controlsContainer.style.left = '10px';
controlsContainer.style.zIndex = '9999';
controlsContainer.style.backgroundColor = 'rgba(0, 0, 0, 0.85)';
controlsContainer.style.padding = '12px 15px';
controlsContainer.style.borderRadius = '8px';
controlsContainer.style.color = 'white';
controlsContainer.style.fontFamily = 'Arial, sans-serif';
controlsContainer.style.transition = 'opacity 0.3s ease';
controlsContainer.style.boxShadow = '0 2px 10px rgba(0,0,0,0.3)';
controlsContainer.style.width = '220px';
// Header
const header = document.createElement('div');
header.innerHTML = 'Sploop.io Visual Tools';
header.style.fontWeight = 'bold';
header.style.fontSize = '14px';
header.style.marginBottom = '12px';
header.style.borderBottom = '1px solid rgba(255,255,255,0.2)';
header.style.paddingBottom = '8px';
// Hitbox toggle button
const hitboxToggle = document.createElement('button');
hitboxToggle.innerHTML = 'Hitboxes: ON';
hitboxToggle.style.cursor = 'pointer';
hitboxToggle.style.backgroundColor = '#50C878';
hitboxToggle.style.border = 'none';
hitboxToggle.style.padding = '8px 12px';
hitboxToggle.style.borderRadius = '6px';
hitboxToggle.style.color = 'white';
hitboxToggle.style.marginBottom = '15px';
hitboxToggle.style.width = '100%';
hitboxToggle.style.fontWeight = 'bold';
hitboxToggle.style.transition = 'all 0.2s ease';
// Transparency controls header
const transparencyHeader = document.createElement('div');
transparencyHeader.innerHTML = 'Transparency Settings:';
transparencyHeader.style.marginBottom = '10px';
transparencyHeader.style.fontWeight = 'bold';
transparencyHeader.style.fontSize = '13px';
transparencyHeader.style.opacity = '0.9';
// Function to create slider
function createSlider(labelText, value, id) {
const container = document.createElement('div');
container.style.marginBottom = '12px';
const label = document.createElement('div');
label.innerHTML = labelText;
label.style.marginBottom = '5px';
label.style.fontSize = '12px';
label.style.display = 'flex';
label.style.justifyContent = 'space-between';
const valueDisplay = document.createElement('span');
valueDisplay.innerHTML = value;
valueDisplay.style.fontWeight = 'bold';
valueDisplay.id = id + '-value';
label.appendChild(valueDisplay);
const slider = document.createElement('input');
slider.type = 'range';
slider.min = '0';
slider.max = '1';
slider.step = '0.01';
slider.value = value;
slider.style.width = '100%';
slider.style.height = '6px';
slider.style.borderRadius = '3px';
slider.style.background = 'rgba(255,255,255,0.2)';
slider.style.outline = 'none';
slider.style.webkitAppearance = 'none';
slider.id = id;
// Custom slider styling
slider.style.background = `linear-gradient(to right, #50C878 0%, #50C878 $
{value * 100}%, rgba(255,255,255,0.2) ${value * 100}%, rgba(255,255,255,0.2)
100%)`;
slider.addEventListener('input', (e) => {
valueDisplay.innerHTML = parseFloat(e.target.value).toFixed(2);
slider.style.background = `linear-gradient(to right, #50C878 0%, #50C878 $
{e.target.value * 100}%, rgba(255,255,255,0.2) ${e.target.value * 100}%,
rgba(255,255,255,0.2) 100%)`;
});
container.appendChild(label);
container.appendChild(slider);
return { container, slider };
}
// Create sliders
const farmSlider = createSlider('Farms/Bushes:', FARM_OPACITY, 'farm-opacity');
const tsSlider = createSlider('Spikes/Traps:', TS_OPACITY, 'ts-opacity');
const hatSlider = createSlider('Hats:', HAT_OPACITY, 'hat-opacity');
// Assemble UI
controlsContainer.appendChild(header);
controlsContainer.appendChild(hitboxToggle);
controlsContainer.appendChild(transparencyHeader);
controlsContainer.appendChild(farmSlider.container);
controlsContainer.appendChild(tsSlider.container);
controlsContainer.appendChild(hatSlider.container);
document.body.appendChild(controlsContainer);
// ===== Functions =====
function toggleHitboxes() {
hitboxesVisible = !hitboxesVisible;
hitboxToggle.innerHTML = `Hitboxes: ${hitboxesVisible ? 'ON' : 'OFF'}`;
hitboxToggle.style.backgroundColor = hitboxesVisible ? '#50C878' : '#FF4444';
}
function toggleControlsVisibility() {
controlsVisible = !controlsVisible;
controlsContainer.style.opacity = controlsVisible ? '1' : '0';
controlsContainer.style.pointerEvents = controlsVisible ? 'all' : 'none';
}
// ===== Event Listeners =====
hitboxToggle.addEventListener('click', toggleHitboxes);
document.addEventListener('keydown', (e) => {
if (e.key.toLowerCase() === '`') {
toggleControlsVisibility();
}
});
// Update opacities when sliders change
farmSlider.slider.addEventListener('input', (e) => {
FARM_OPACITY = parseFloat(e.target.value);
});
tsSlider.slider.addEventListener('input', (e) => {
TS_OPACITY = parseFloat(e.target.value);
});
hatSlider.slider.addEventListener('input', (e) => {
HAT_OPACITY = parseFloat(e.target.value);
});
// ===== Modified drawImage =====
const originalDrawImage = CanvasRenderingContext2D.prototype.drawImage;
CanvasRenderingContext2D.prototype.drawImage = function(image, x, y, width, height)
{
let isFarm = false;
let isTS = false;
let isHat = false;
// First handle transparency
try {
if (image.src) {
const path = new URL(image.src).pathname;
isFarm = path.includes('wood_farm') ||
path.includes('stone_farm') ||
path.includes('bush') ||
path.includes('berry_farm');
isTS = path.includes('spike') ||
path.includes('trap') ||
path.includes('turret') ||
path.includes('bullet');
isHat = path.includes('hat');
}
} catch(e) {}
if (isFarm || isTS || isHat) {
this.save();
if (isFarm) this.globalAlpha = FARM_OPACITY;
if (isTS) this.globalAlpha = TS_OPACITY;
if (isHat) this.globalAlpha = HAT_OPACITY;
originalDrawImage.call(this, image, x, y, width, height);
this.restore();
} else {
originalDrawImage.apply(this, arguments);
}
// Then handle hitboxes if enabled
if (!hitboxesVisible) return;
if (image.src) {
try {
const path = new URL(image.src).pathname;
const isHeldItem = path.includes('/item/');
const object = path.split('/').pop().split('.')[0];
const radius = item_radius[object];
if (radius) {
this.save();
this.beginPath();
this.strokeStyle = hitboxColor;
this.globalAlpha = isHeldItem ? 0.4 : 0.6;
this.lineWidth = 2;
const centerX = x + (width/2);
const centerY = y + (height/2);
this.arc(centerX, centerY, radius, 0, Math.PI * 2);
this.stroke();
this.restore();
}
} catch(e) {
console.error('Error processing image:', e);
}
}
};