Calculate the CyberDeviance for character
// ==UserScript==
// @name CyberScript
// @namespace http://tampermonkey.net/
// @version 2026-04-31
// @description Calculate the CyberDeviance for character
// @author Cryptic
// @match https://www.dreadcast.net/Main
// @icon https://www.google.com/s2/favicons?sz=64&domain=dreadcast.net
// @grant none
// @license MIT
// ==/UserScript==
(function() {
'use strict';
function show(){
if (box.style.display === "none" || !box.style.display) {
box.style.display = "block";
} else {
box.style.display = "none";
}
}
function make(x,t){
let b = []
for(let i=0;i<x;i++){
b.push(document.createElement(t))
}
return b
}
function calculate(roll,cyb,info){
return roll*0.12+(roll*(cyb/100/0.88))*(1-(info/297)*0.15)
}
function estimate(x){
if(x<12){
return "Aucun trouble"
}
else if(x<31){
return "Dégradation légère"
}
else if(x<48){
return "Dégradation modérée"
}
else if(x<84){
return "Dégradation grave"
}
else{
return "Dégradation extrême"
}
}
// Conception du menu
let band = document.querySelector(".menus")
let box = document.createElement("div");
// Paramétrage de la Box
box.id = "cyber"
box.style.display = "none";
const br = ()=>document.createElement("br")
let p = make(1,"p")
// Paramétrage du Msg
p[0].style.color = "red"
p[0].style.fontWeight = "bolder"
let ipt = make(3,"input")
let labels = make(3, "label");
// Paramétrage des inputs
let r = ipt[0]
let c = ipt[1]
let i = ipt[2]
ipt.forEach(e=>{
e.type = "number"
e.max="100"
e.min="0"
e.value = "0"
e.style.width = "90%"
})
// Paramétrage labels
const labelTexts = [
"🎲 Roll / Pourcentage de base",
"⚙️ % Cyberware installé",
"💻 Indice Info"
];
labels.forEach((lab, idx) => {
lab.innerText = labelTexts[idx];
lab.style.display = "block";
lab.style.color = "#88ddff";
lab.style.fontSize = "13px";
lab.style.marginTop = "8px";
lab.style.marginBottom = "2px";
// Association correcte input <-> label
lab.htmlFor = ipt[idx].id = "cyber_" + ["roll","cyb","info"][idx];
});
let btn = make(2,"button")
// Paramétrage des boutons
let autoroll = btn[0]
autoroll.innerText = "Roll"
autoroll.addEventListener("click",()=>{r.value = Math.random()*100})
let es = btn[1]
es.innerText = "Estimer"
es.addEventListener("click",()=>{
if(r.value !="" || c.value !="" || i.value !=""){
let db = calculate(r.value,c.value,i.value)
let res = estimate(db)
p[0].innerText = parseInt(db)+"db - "+res
}
else{p[0].innerText="Les champs sont incomplets !"}
})
// Loading des assets du Components
box.append(labels[0],ipt[0], btn[0], br(),labels[1], ipt[1], br(),labels[2], ipt[2], p[0], br(), btn[1]);
document.querySelector("#zone_carte").appendChild(box)
// Loading dans bandeau
let ev = document.createElement("li")
ev.id = "CyberCount"
ev.classList = "link couleur2"
ev.style = "white-space: nowrap;"
ev.innerText = "CyberScan"
ev.addEventListener("click",show)
band.appendChild(ev)
// Extrait d'un button bandeau <li class="link couleur2" style="white-space: nowrap;" onclick
// Zone d'injection <ul class="menus">
/* Stress test
% Cyber,Min dB,Max dB,Moyenne dB,Distribution des niveaux (sur 50 rolls)
0%,0,12.0,6.5,100% Classique
10%,0,21.6,11.5,50% Classique / 50% Légère
20%,1,30.9,15.8,38% Classique / 62% Légère
30%,1.2,41.4,24.9,22% Classique / 38% Légère / 40% Modérée
40%,0,50.6,25.5,26% Classique / 34% Légère / 36% Modérée / 4% Grave
50%,0.6,59.1,29.1,22% Classique / 26% Légère / 36% Modérée / 16% Grave
60%,2.1,70.7,36.8,14% Classique / 26% Légère / 24% Modérée / 36% Grave
70%,2.4,80.5,40.9,18% Classique / 18% Légère / 16% Modérée / 48% Grave
80%,0,90.3,50.1,10% Classique / 18% Légère / 20% Modérée / 46% Grave / 6% Extrême
90%,1,96.1,53.4,6% Classique / 16% Légère / 24% Modérée / 34% Grave / 20% Extrême
100%,0,99,55.7,10% Classique / 20% Légère / 8% Modérée / 36% Grave / 26% Extrême
*/
// Chargement du style
const style = document.createElement('style');
style.textContent = `
#cyber {
display: none;
position: fixed;
left: 5%;
top: 5%;
width: 260px;
background: linear-gradient(#007aff, #0055cc);
border: 3px solid #00ccff;
border-radius: 8px;
box-shadow: 0 0 15px #00ccff, inset 0 0 10px rgba(255,255,255,0.3);
padding: 12px;
color: white;
font-family: "Courier New", monospace;
z-index: 50000;
isolation: isolate;
}
#cyber input {
width: 100%;
background: #002c5c;
color: #eeeeee;
border: 2px solid #00ccff;
border-radius: 4px;
padding: 6px 8px;
margin: 6px 0;
font-weight: bold;
font-size: 15px;
position:relative;
}
#cyber input:focus {
outline: none;
border-color: #00ffcc;
box-shadow: 0 0 8px #00ffcc;
}
#cyber button {
width: 100%;
background: #00cc66;
color: #000;
border: none;
border-radius: 4px;
padding: 8px;
margin: 6px 0;
font-weight: bold;
cursor: pointer;
transition: all 0.2s;
}
#cyber button:hover {
background: #00ff88;
transform: scale(1.03);
}
#cyber p {
color: #ff4444;
font-weight: bold;
text-align: center;
margin: 10px 0 4px;
min-height: 1.3em;
}
#CyberCount {
cursor: pointer;
transition: color 0.2s;
}
#CyberCount:hover {
color: #00ffcc !important;
}
`;
document.head.appendChild(style);
})();