您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
it looks better this way. >:(
// ==UserScript== // @name flowr.fun - un-grey custom petals // @namespace http://tampermonkey.net/ // @version 2024-03-03 // @description it looks better this way. >:( // @author Ly // @license MIT // @match https://flowr.fun/ // @icon https://www.google.com/s2/favicons?sz=64&domain=flowr.fun // @grant none // ==/UserScript== PetalContainer = class PetalContainer { constructor(petals, {x,y,w,h,originalX,originalY,radius,toOscillate,isDragging,lastSlot,toRenderText,petalStats,customBiome}, id, amount, attempt){ this.petals = petals; this.petalStats = petalStats; for(let i = 0; i < this.petals.length; i++){ this.petals[i].insidePetalContainer = true; } this.rarity = (this.petals[0] ?? {rarity: 0}).rarity; this.type = (this.petals[0] ?? {type: 'Basic'}).type; if(this.type === "Custom" || this.type === "CustomProjectile"){ this.type = this.petals[0].customType; } this.randomAngle = Math.random() * Math.PI * 2; this.x = x; this.y = y; this.w = w; this.h = h; this.radius = radius; this.render = {x: originalX ?? this.x, y: originalY ?? this.y, w: this.w/*w should be the same as height, idk why i wrote it this way*/}; this.amount = amount;// when dragged and dropped, amount will be 1. Amount 1 (x1) doesn't render the x[number] (x2, x3, etc.) in the corner but the same class does if amount != 1; this.attempt = attempt; this.id = id; this.spawnAnimation = 0; this.lastAmountChangedTime = -1000; this.collectTime = null; this.toOscillate = toOscillate !== false; if(this.toOscillate === true){ this.angleOffset = Math.PI * .05 * (Math.random() * 2 - 1); } this.creationTime = performance.now(); this.isDraggingPetalContainer = isDragging ?? false; if(this.isDraggingPetalContainer === true){ this.lastPetalSlot = lastSlot ?? {index: -1, top: true}; } if(toRenderText !== undefined){ this.toRenderText = false; } this.isHovered = false; this.statsBoxAlpha = 0; this.statsBox = null; if(customBiome !== undefined){ this.customBiome = customBiome; this.greyed = false; } } updateInterpolate(){ this.render.x = interpolate(this.render.x, this.x, 0.00672 * dt); this.render.y = interpolate(this.render.y, this.y, 0.00672 * dt); this.render.w = interpolate(this.render.w, this.w, 0.00672 * dt); if(this.collectTime) { this.spawnAnimation = interpolate(this.spawnAnimation, 0, 0.00672 * dt); } else { this.spawnAnimation = interpolate(this.spawnAnimation, 1, 0.00672 * dt); } } drawStatsBox(drawBelow=false){ if(window.statBoxes === false){ return; } if(this.isHovered === true){ if(this.statsBox === null){ let lastOscillating = this.toOscillate; let lastDimensions = {w: this.w, h: this.h}; this.w = 58; this.h = 58; this.toOscillate = false; this.statsBox = generateStatsBox(this, true, { x: this.x, y: this.y } ) this.w = lastDimensions.w; this.h = lastDimensions.h; this.toOscillate = lastOscillating; } this.statsBoxAlpha += 0.15 * dt / 18; if(this.statsBoxAlpha > 1){ this.statsBoxAlpha = 1; } ctx.globalAlpha = this.statsBoxAlpha; } else { this.statsBoxAlpha -= 0.15 * dt / 18; if(this.statsBoxAlpha < 0){ this.statsBoxAlpha = 0; } } if(this.statsBoxAlpha !== 0){ this.statsBox.x = this.render.x - this.statsBox.w / 2 this.statsBox.y = drawBelow ? this.render.y + this.h / 2 + 11.5 : this.render.y - this.statsBox.h - this.h / 2 - 11.5; ctx.globalAlpha = this.statsBoxAlpha; this.statsBox.pc.amount = this.amount; this.statsBox.draw(); ctx.globalAlpha = 1; } this.isHovered = false; } draw(inGame, number){ this.updateInterpolate(); if(this.toOscillate === true && toRender({x: this.render.x, y: this.render.y, radius: this.radius}, window.camera) === false && this.toSkipCulling !== true){ return; } const renderAnimationTimer = smoothstep(this.spawnAnimation); let scale = 1; let rotation = 0; ctx.lastTransform = ctx.getTransform(); // ctx.save(); ctx.translate(this.render.x, this.render.y); scale *= renderAnimationTimer * this.render.w / 50; // ctx.scale(renderAnimationTimer * this.render.w / 50, renderAnimationTimer * this.render.w / 50); // ctx.rotate(-(1 - renderAnimationTimer) * Math.PI * 3); rotation -= (1 - renderAnimationTimer) * Math.PI * 3; if(this.isDraggingPetalContainer === true){ if(this.draggingTimer === undefined)this.draggingTimer = 0; this.draggingTimer += 1000 / 30 * dt/16.66; // ctx.rotate(Math.sin(this.draggingTimer / 280) * 0.28); rotation += Math.sin(this.draggingTimer / 280) * 0.28; if(this !== draggingPetalContainer){ this.isDraggingPetalContainer = false; this.undraggingPetalContainerTimer = 30; // this.lastDraggingTimer = this.draggingTimer; this.lastDraggingAngle = Math.sin(this.draggingTimer / 280) * 0.28; // this.draggingTimer = Math.sin(this.draggingTimer / 300) * 0.3; } } else if(this.undraggingPetalContainerTimer !== undefined){ if(this.interval === undefined){ // this.lastDraggingTimer += 1000 / 30; // if(Math.abs(Math.sin(this.lastDraggingTimer / 300) * 0.3) < Math.abs(this.draggingTimer)){ // this.draggingTimer = Math.sin(this.lastDraggingTimer / 300) * 0.3; // } this.lastDraggingAngle = interpolate(this.lastDraggingAngle, 0, 0.15); // ctx.rotate(this.lastDraggingAngle); rotation += this.lastDraggingAngle; this.undraggingPetalContainerTimer--; if(this.undraggingPetalContainerTimer < 0){ delete this.undraggingPetalContainerTimer; // delete this.lastDraggingTimer; delete this.lastDraggingAngle; delete this.draggingTimer; } // this.undraggingPetalContainerTimer = 30; // // this.draggingTimer /= 300; // // this.draggingTimer = this.draggingTimer % (Math.PI * 2); // // this.draggingTimer *= 300; // this.draggingTimer = Math.sin(this.draggingTimer / 300) * 0.3;// it becomes an angle now // this.interval = setInterval(() => { // this.draggingTimer = interpolateDirection(this.draggingTimer, Math.PI / 2, 0.1); // this.undraggingPetalContainerTimer--; // if(this.undraggingPetalContainerTimer < 0){ // clearInterval(this.interval); // delete this.undraggingPetalContainerTimer; // } // }, 1000 / 30); } } if(this.toOscillate === true){ scale *= 1+Math.sin(performance.now()/ 1000 / .076)/52; // ctx.scale(1+Math.sin(performance.now()/ 1000 / .076)/52,1+Math.sin(performance.now()/ 1000 / .076)/52); // ctx.rotate(this.angleOffset); rotation += this.angleOffset; } // if(Math.abs(scale * 60 - this.renderImageSize) > 10){ // this.generateRenderImage(scale * 60 * canvas.zoom); // } // ctx.drawImage(this.renderImage, -this.renderImageSize/2/canvas.zoom, -this.renderImageSize/2/canvas.zoom, this.renderImageSize/canvas.zoom, this.renderImageSize/canvas.zoom/*, -30 * scale, -30 * scale, 60 * scale, 60 * scale*/); // ctx.scale(8,8); // ___ start ___ if(rotation !== 0)ctx.rotate(rotation); if(scale !== 1)ctx.scale(scale, scale); if(this.toOscillate === true && this.isDisplayPetalContainer !== true){ // bigger grey border ctx.globalAlpha = 0.3; ctx.fillStyle = 'black'; ctx.beginPath(); ctx.roundRect(-30, -30, 60, 60, 5); ctx.fill(); ctx.closePath(); ctx.globalAlpha = 1; } // draw rect ctx.lineWidth = 4.5; // greyed if and only if its a custom petal in an official biome // this.greyed = false; this.greyed = (this.customBiome !== undefined && window.officialBiomes.includes(biomeManager.getCurrentBiome()) === true); if(this.type === 'soccer petal' && biomeManager.getCurrentBiome() !== 'Soccer!') this.greyed = true; this.greyed = false if(this.greyed){ ctx.globalAlpha = 0.3; ctx.fillStyle = "#525252"; ctx.strokeStyle = "#404040"; } else { ctx.fillStyle = Colors.rarities[this.rarity].color; ctx.strokeStyle = Colors.rarities[this.rarity].border; } // if (this.rarity == 8){ // ctx.fillStyle = `hsl(${Math.cos(Date.now()/1200)*20 + 35}, 68%, 60%)` // ctx.strokeStyle = `hsl(${Math.cos(Date.now()/1200)*20 + 35}, 68%, 45%)` // } if (this.rarity == 12){ const gradientFill = ctx.createLinearGradient(-30, -30, 30, 30); gradientFill.addColorStop(0, `hsl(${Math.cos(Date.now()/400)*35 + 285}, 100%, 20%)`); gradientFill.addColorStop(0.25, `hsl(${Math.cos(Date.now()/400 + 1.5)*35 + 285}, 100%, 20%)`); gradientFill.addColorStop(0.5, `hsl(${Math.cos(Date.now()/400 + 3)*35 + 285}, 100%, 20%)`) gradientFill.addColorStop(0.75, `hsl(${Math.cos(Date.now()/400 + 4.5)*35 + 285}, 100%, 20%)`) gradientFill.addColorStop(1, `hsl(${Math.cos(Date.now()/400 + 6)*35 + 285}, 100%, 20%)`) //ctx.fillStyle = `hsl(${Math.cos(Date.now()/400)*35 + 285}, 100%, 15%)` ctx.fillStyle = gradientFill; ctx.strokeStyle = "black"; } ctx.beginPath(); ctx.roundRect(-25, -25, 50, 50, .25); ctx.fill(); ctx.stroke(); ctx.closePath(); if(this.rarity == 12){ ctx.save(); //shiny stars & stuff if(!this.stars){ this.stars = []; for(let starnum = 0; starnum < 2; starnum++){ this.stars.push({x: Math.random()*50 - 25, y: Math.random()*50 - 25}) } } ctx.shadowBlur = 20; ctx.shadowColor = "white"; ctx.fillStyle = "#ffffff"; for(let star of this.stars){ star.x+=0.1; star.y+=0.1; if(star.x >30 || star.y >30){ star.x = Math.random()*800 - 20 - 30; star.y = -30; } if(star.x < -30 || star.x > 30 || star.y < -30 || star.y > 30){ //don't draw; continue; } ctx.beginPath(); var grad = ctx.createRadialGradient(star.x, star.y,15,star.x, star.y,0); grad.addColorStop(0,"transparent"); grad.addColorStop(0.8,`rgba(255,255,255,${(Math.cos(Date.now()/600+ star.x/30 + star.y/30) + 1)*0.8})`); grad.addColorStop(1,"white"); ctx.fillStyle = grad; ctx.globalAlpha = 0.3; ctx.fillRect(-20.5, -20.5, 41,41); ctx.globalAlpha = 1; if(star.x < 20.5 && star.x > -20.5 && star.y < 20.5 && star.y > -20.5){ ctx.fillStyle = "#fff"; ctx.arc(star.x, star.y, 1, 0, 2*Math.PI); ctx.fill(); } ctx.closePath(); } ctx.restore(); } //draw reload stuff if (inGame){ if (petalReloadData[number]){ if (petalReloadData[number].reload > 0.001 && petalReloadData[number].reload < 0.999){ ctx.save(); ctx.beginPath(); ctx.roundRect(-25, -25, 50, 50, .25); ctx.clip(); ctx.globalAlpha = 0.3; ctx.lineCap = "butt"; let offset = (1-Math.pow(petalReloadData[number].reload, 0.7))*Math.PI*6 + this.randomAngle; ctx.strokeStyle = "#000000"; ctx.lineWidth = 50; ctx.beginPath(); ctx.arc(0, 0, 25, offset - Math.PI * 2 * smoothstep(petalReloadData[number].reload), offset); ctx.stroke(); ctx.closePath(); ctx.restore(); } } } if(this.greyed)ctx.globalAlpha = 1; if(this.toRenderText === false){ ctx.translate(0, 3.5); } if(this.type === 'Wing'){ ctx.translate(0, -1.8); } // // no need for an arc, just draw the petal if(this.petals.length === 1){ this.petals[0].render.x = 0//this.x; this.petals[0].render.y = 0//this.y - this.h / 10; let scaleMult = .8; if(this.petals[0].radius * .8 > 13.25/2){ scaleMult = 13.25/(this.petals[0].radius*.8)/2; } if(petalContainerRenderSizeMultsMap[this.petals[0].type] !== undefined){ if (typeof petalContainerRenderSizeMultsMap[this.petals[0].type] == "object"){ if (petalContainerRenderSizeMultsMap[this.petals[0].type][this.petals[0].rarity]){ scaleMult *= petalContainerRenderSizeMultsMap[this.petals[0].type][this.petals[0].rarity]; } } else{ scaleMult *= petalContainerRenderSizeMultsMap[this.petals[0].type]; } } let individualRotate = false; if(petalContainerIndividualRotate[this.petals[0].type] !== undefined){ if (typeof petalContainerIndividualRotate[this.petals[0].type] == "object"){ if (petalContainerIndividualRotate[this.petals[0].type][this.petals[0].rarity]){ individualRotate = petalContainerIndividualRotate[this.petals[0].type][this.petals[0].rarity]; } } else{ individualRotate = petalContainerIndividualRotate[this.petals[0].type]; } } // ctx.translate(0, -4); // ctx.scale(scaleMult, scaleMult); // if (individualRotate !== false)ctx.rotate(individualRotate) let last = {y: this.petals[0].render.y, selfAngle: this.petals[0].selfAngle}; this.petals[0].render.y -= 4; this.petals[0].scaleMult = scaleMult; if(individualRotate !== false)this.petals[0].selfAngle += individualRotate; if(this.greyed === true)window.alphaMult = 0.4; this.petals[0].draw(); // if (individualRotate !== false)ctx.rotate(-individualRotate) // ctx.scale(1/scaleMult,1/scaleMult); // ctx.translate(0, 4); this.petals[0].render.y = last.y; delete this.petals[0].scaleMult; this.petals[0].selfAngle = last.selfAngle; // console.log(this.petals[0], ctx.getTransform()); } else { // todo: generate positions in init instead of recalcing every frame, its not like we're gonna be adding more petals to an existing petal slot let petalRadius = (this.petals[0] ?? {radius: 0}).radius; if((this.petals[0] ?? {type: 'not peas'}).type === 'Peas'){ petalRadius -= 0.2; } let radius = Math.min(petalRadius * 1.16, 25 - petalRadius); // if(this.petals.length === 3){ // // odd // ctx.translate(-1, 0); // } let greaterThanMargin = petalRadius * .8 + radius - 13.25; if(greaterThanMargin > 0){ radius -= greaterThanMargin; if(radius < 8){ greaterThanMargin = 8-radius; radius = 8; // radius *= 1 / (greaterThanMargin/(13.25)+1); petalRadius *= 1 / (greaterThanMargin/13.25+1); // petalRadius = Math.max(8, petalRadius); for(let i = 0; i < this.petals.length; i++){ this.petals[i].radius = petalRadius; } } } if (petalContainerMultPetalRadiusMap[this.petals[0].type] !== undefined){ if (typeof petalContainerMultPetalRadiusMap[this.petals[0].type] == "object"){ if (petalContainerMultPetalRadiusMap[this.petals[0].type][this.petals[0].rarity]){ radius *= petalContainerMultPetalRadiusMap[this.petals[0].type][this.petals[0].rarity]; } } else{ radius *= petalContainerMultPetalRadiusMap[this.petals[0].type]; } } let toPointToCenter = ['Stinger'].includes((this.petals[0] ?? {type: "Basic"}).type) && (this.petals[0] ?? {rarity: 0}).rarity > 5; if (toPointToCenter == true){ toPointToCenter = 0; } if (pointToCenterPetals[this.petals[0].type] !== undefined){ if (typeof pointToCenterPetals[this.petals[0].type] == "object"){ if (pointToCenterPetals[this.petals[0].type][this.petals[0].rarity]){ toPointToCenter = pointToCenterPetals[this.petals[0].type][this.petals[0].rarity]; } } else{ toPointToCenter = pointToCenterPetals[this.petals[0].type]; } } for(let i = 0; i < this.petals.length; i++){ let rotateOffset = 0; if (petalContainerRotateMap[this.petals[0].type]){ rotateOffset = petalContainerRotateMap[this.petals[0].type]; } const angle = Math.PI * 2 * i / this.petals.length + rotateOffset; this.petals[i].render.x = 0//this.x + Math.cos(angle) * radius; this.petals[i].render.y = 0//this.y + Math.sin(angle) * radius - this.h / 10; let scaleMult = .8; if(petalContainerRenderSizeMultsMap[this.petals[0].type] !== undefined){ if (typeof petalContainerRenderSizeMultsMap[this.petals[0].type] == "object"){ if (petalContainerRenderSizeMultsMap[this.petals[0].type][this.petals[0].rarity]){ scaleMult *= petalContainerRenderSizeMultsMap[this.petals[0].type][this.petals[0].rarity]; } } else{ scaleMult *= petalContainerRenderSizeMultsMap[this.petals[0].type]; } } let last = {x: this.petals[i].render.x, y: this.petals[i].render.y, selfAngle: this.petals[i].selfAngle}; this.petals[i].render.x += Math.cos(angle) * radius * scaleMult/.8; this.petals[i].render.y += Math.sin(angle) * radius * scaleMult/.8 - 4; this.petals[i].scaleMult = scaleMult; if(toPointToCenter !== false)this.petals[i].selfAngle += angle+Math.PI+toPointToCenter; // ctx.translate(Math.cos(angle) * radius * scaleMult/.8, Math.sin(angle) * radius * scaleMult/.8 - 4); // ctx.scale(scaleMult, scaleMult); // if(toPointToCenter !== false)ctx.rotate(angle+Math.PI+toPointToCenter); if(this.greyed === true)window.alphaMult = 0.4; this.petals[i].draw(); this.petals[i].render.x = last.x; this.petals[i].render.y = last.y; delete this.petals[i].scaleMult; this.petals[i].selfAngle = last.selfAngle; // if(toPointToCenter !== false)ctx.rotate(-angle-Math.PI-toPointToCenter); // ctx.scale(1/scaleMult, 1/scaleMult); // ctx.translate(-Math.cos(angle) * radius * scaleMult/.8, -Math.sin(angle) * radius * scaleMult/.8 + 4); } // if(this.petals.length === 3){ // // odd // ctx.translate(1, 0); // } } if(this.type === 'Wing'){ ctx.translate(0, 1.8); } if(this.toRenderText === false){ ctx.translate(0, -3.5); } if(this.toRenderText === undefined){ if(this.type === "Dandelion"){ ctx.font = '900 8.5px Ubuntu'; ctx.letterSpacing = "-.1px"; } else if(this.type === "Lightning" || this.type === "Pentagon"){ ctx.font = '900 9.5px Ubuntu'; ctx.letterSpacing = "-.1px"; } else { ctx.font = '900 11px Ubuntu'; ctx.letterSpacing = "-.05px"; } ctx.textBaseline = 'middle'; ctx.textAlign = 'center'; ctx.fillStyle = 'white'; ctx.strokeStyle = 'black'; // const canvasScale = ctx.getTransform().m11; ctx.lineWidth = 1.35;//5//Math.ceil(1.25 / canvasScale); ctx.fontKerning = "none"; let type = this.type; if (type == "Fire Missile"){ type = "Missile"; } if(this.greyed) ctx.globalAlpha = 0.3; ctx.strokeText(type, 0, 13.25); ctx.fillText(type, 0, 13.25); ctx.globalAlpha = 1; } if(scale !== 1)ctx.scale(1/scale, 1/scale); if(rotation !== 0)ctx.rotate(-rotation); // ___ end ___ if(this.amount !== 1 || (performance.now() - this.lastAmountChangedTime < 240)){ if(performance.now() - this.lastAmountChangedTime < 240){ ctx.globalAlpha = smoothstep((performance.now() - this.lastAmountChangedTime) / 240); } if(this.amount === 1){ ctx.globalAlpha = 1 - ctx.globalAlpha; } ctx.font = `600 ${13 * scale}px Ubuntu`; ctx.letterSpacing = "1px"; ctx.textBaseline = 'middle'; ctx.textAlign = 'right'; ctx.fillStyle = 'white'; ctx.strokeStyle = 'black'; ctx.lineWidth = 2; ctx.translate((70/(2.5) + .5) * scale, (-42/(2.5) + .5) * scale); ctx.rotate(Math.PI / 9.1); if(this.greyed) ctx.globalAlpha *= 0.3; ctx.strokeText('x' + (this.amount === 1 ? 2 : formatAmount(this.amount)), 0, 0); ctx.fillText('x' + (this.amount === 1 ? 2 : formatAmount(this.amount)), 0, 0); ctx.globalAlpha = 1; } ctx.setTransform(ctx.lastTransform); delete ctx.lastTransform; } }