added v1 of demon rulet
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
function qs(id){return document.getElementById(id)}
|
||||
|
||||
const page = document.body.dataset.page;
|
||||
let cachedItems = null;
|
||||
|
||||
// Storage helpers
|
||||
function read(key, fallback){
|
||||
@@ -11,6 +12,62 @@
|
||||
}
|
||||
function write(key, val){localStorage.setItem(key,JSON.stringify(val))}
|
||||
|
||||
function parseData(txt){
|
||||
return txt.split(/\r?\n/).map(l=>l.trim()).filter(Boolean).map(l=>{
|
||||
const parts = l.split('|').map(p=>p.trim());
|
||||
return {level:parts[0]||'Unknown',position:parts[1]||'',title:parts[2]||'Untitled',url:parts[3]||''};
|
||||
});
|
||||
}
|
||||
|
||||
function loadItems(){
|
||||
if(cachedItems) return Promise.resolve(cachedItems);
|
||||
return fetch('data.txt').then(r=>r.text()).then(txt=>{
|
||||
cachedItems = parseData(txt);
|
||||
return cachedItems;
|
||||
});
|
||||
}
|
||||
|
||||
if(page==='roulette'){
|
||||
const spinBtn = qs('roulette-spin');
|
||||
const statusEl = qs('roulette-status');
|
||||
const titleEl = qs('roulette-title');
|
||||
const rankEl = qs('roulette-rank');
|
||||
const openEl = qs('roulette-open');
|
||||
|
||||
function showPick(item){
|
||||
statusEl.textContent = 'Your demon is:';
|
||||
titleEl.textContent = item.title;
|
||||
rankEl.textContent = `Rank: #${item.position}`;
|
||||
if(item.url){
|
||||
openEl.hidden = false;
|
||||
openEl.href = item.url;
|
||||
}else{
|
||||
openEl.hidden = true;
|
||||
}
|
||||
}
|
||||
|
||||
spinBtn.addEventListener('click', ()=>{
|
||||
statusEl.textContent = 'Spinning...';
|
||||
titleEl.textContent = 'Choosing a demon';
|
||||
rankEl.textContent = 'Rank: -';
|
||||
openEl.hidden = true;
|
||||
loadItems().then(items=>{
|
||||
if(!items.length){
|
||||
statusEl.textContent = 'No demons found.';
|
||||
titleEl.textContent = 'Add demons to data.txt';
|
||||
return;
|
||||
}
|
||||
const item = items[Math.floor(Math.random()*items.length)];
|
||||
window.setTimeout(()=>showPick(item), 350);
|
||||
}).catch(err=>{
|
||||
statusEl.textContent = 'Could not load the list.';
|
||||
titleEl.textContent = 'Run the site on a local server';
|
||||
rankEl.textContent = 'Rank: -';
|
||||
console.error(err);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Players page
|
||||
if(page==='players'){
|
||||
const form = qs('player-form'); const nameIn = qs('player-name'); const list = qs('players');
|
||||
@@ -31,12 +88,7 @@
|
||||
const levelsEl = qs('levels'); const listArea = qs('list-area'); const titleEl = qs('list-title');
|
||||
// Load hard-coded data file data.txt (category|position|title|url per line)
|
||||
function loadData(){
|
||||
fetch('data.txt').then(r=>r.text()).then(txt=>{
|
||||
const lines = txt.split(/\r?\n/).map(l=>l.trim()).filter(Boolean);
|
||||
const items = lines.map(l=>{
|
||||
const parts = l.split('|').map(p=>p.trim());
|
||||
return {level:parts[0]||'Unknown',position:parts[1]||'',title:parts[2]||'Untitled',url:parts[3]||''};
|
||||
});
|
||||
loadItems().then(items=>{
|
||||
setupLevels(items);
|
||||
}).catch(err=>{listArea.innerHTML='<p class="muted">Failed to load data.txt — run via a local server.</p>'; console.error(err)});
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
<a href="players.html">Players</a>
|
||||
<a href="lists.html">Lists</a>
|
||||
<a href="rules.html">Rules</a>
|
||||
<a href="roulette.html">Roulette</a>
|
||||
</nav>
|
||||
</header>
|
||||
<main>
|
||||
@@ -26,6 +27,7 @@
|
||||
<a class="btn" href="lists.html">View Lists</a>
|
||||
<a class="btn" href="players.html" style="margin-left:8px">Players</a>
|
||||
<a class="btn" href="rules.html" style="margin-left:8px">Rules</a>
|
||||
<a class="btn" href="roulette.html" style="margin-left:8px">Roulette</a>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
<a href="index.html">Home</a>
|
||||
<a href="players.html">Players</a>
|
||||
<a href="rules.html">Rules</a>
|
||||
<a href="roulette.html">Roulette</a>
|
||||
</nav>
|
||||
</header>
|
||||
<main class="layout">
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
<a href="index.html">Home</a>
|
||||
<a href="lists.html">Lists</a>
|
||||
<a href="rules.html">Rules</a>
|
||||
<a href="roulette.html">Roulette</a>
|
||||
</nav>
|
||||
</header>
|
||||
<main>
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
||||
<title>Demon Roulette - GD fedl</title>
|
||||
<link rel="stylesheet" href="styles.css">
|
||||
</head>
|
||||
<body data-page="roulette">
|
||||
<header>
|
||||
<h1>Demon Roulette</h1>
|
||||
<nav>
|
||||
<a href="index.html">Home</a>
|
||||
<a href="lists.html">Lists</a>
|
||||
<a href="players.html">Players</a>
|
||||
<a href="rules.html">Rules</a>
|
||||
</nav>
|
||||
</header>
|
||||
<main>
|
||||
<section class="panel roulette-panel">
|
||||
<div class="roulette-head">
|
||||
<div>
|
||||
<p class="roulette-kicker">Random Challenge</p>
|
||||
<h2>Demon Roulette</h2>
|
||||
<p class="muted">Spin the list and get a random demon from your current FEDL rankings.</p>
|
||||
</div>
|
||||
<button class="btn roulette-btn" id="roulette-spin" type="button">Spin</button>
|
||||
</div>
|
||||
|
||||
<div class="roulette-card" id="roulette-card">
|
||||
<p class="roulette-status muted" id="roulette-status">Press spin to choose a demon.</p>
|
||||
<h3 id="roulette-title">No demon selected</h3>
|
||||
<p class="roulette-rank" id="roulette-rank">Rank: -</p>
|
||||
<a class="btn roulette-open" id="roulette-open" href="#" target="_blank" rel="noopener noreferrer" hidden>Open Video</a>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
<script src="app.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -13,6 +13,7 @@
|
||||
<a href="index.html">Home</a>
|
||||
<a href="lists.html">Lists</a>
|
||||
<a href="players.html">Players</a>
|
||||
<a href="roulette.html">Roulette</a>
|
||||
</nav>
|
||||
</header>
|
||||
<main>
|
||||
|
||||
+11
-1
@@ -33,6 +33,16 @@ table.levels-table tr:hover td{background:rgba(255,255,255,0.01)}
|
||||
|
||||
/* small helpers reused */
|
||||
.small{font-size:0.9rem}
|
||||
.roulette-panel{margin-top:18px;padding:24px 26px;background:linear-gradient(135deg,rgba(92,197,255,0.12),rgba(7,19,38,0.96));border:1px solid rgba(92,197,255,0.16)}
|
||||
.roulette-head{display:flex;align-items:flex-end;justify-content:space-between;gap:18px;margin-bottom:18px}
|
||||
.roulette-kicker{margin:0 0 8px 0;text-transform:uppercase;letter-spacing:0.14em;font-size:0.72rem;font-weight:700;color:var(--accent)}
|
||||
.roulette-head h2{margin:0 0 8px 0;font-size:1.9rem}
|
||||
.roulette-btn{min-width:110px;font-weight:700}
|
||||
.roulette-card{padding:22px;border-radius:14px;background:rgba(255,255,255,0.04);border:1px solid rgba(255,255,255,0.05)}
|
||||
.roulette-status{margin:0 0 8px 0}
|
||||
.roulette-card h3{margin:0 0 8px 0;font-size:1.5rem}
|
||||
.roulette-rank{margin:0 0 16px 0;font-size:1rem;color:#dce8f5}
|
||||
.roulette-open{color:#042}
|
||||
.discord-panel{display:flex;align-items:center;justify-content:space-between;gap:24px;margin-top:18px;padding:26px 28px;background:linear-gradient(135deg,rgba(88,101,242,0.18),rgba(7,19,38,0.95));border:1px solid rgba(88,101,242,0.22)}
|
||||
.discord-copy{flex:1}
|
||||
.discord-badge{display:flex;align-items:center;gap:16px;margin-bottom:14px}
|
||||
@@ -58,4 +68,4 @@ table.levels-table tr:hover td{background:rgba(255,255,255,0.01)}
|
||||
.rule-section p{margin:0 0 12px 0;line-height:1.7;color:#dce8f5}
|
||||
.rules-list{margin:0;padding-left:22px}
|
||||
.rules-list li{margin:0 0 8px 0;line-height:1.55;color:#dce8f5}
|
||||
@media(max-width:900px){.layout{flex-direction:column}.sidebar{width:100%}.video-modal iframe{height:320px}.discord-panel{flex-direction:column;align-items:flex-start;padding:22px 20px}.discord-panel h2{font-size:1.55rem}.discord-actions{width:100%;justify-content:flex-start}.rules-view header{padding:16px 18px}.rules-view header h1{font-size:1.55rem}.rules-page{padding:24px 20px}.rules-page h2{font-size:1.65rem}}
|
||||
@media(max-width:900px){.layout{flex-direction:column}.sidebar{width:100%}.video-modal iframe{height:320px}.roulette-head{flex-direction:column;align-items:flex-start}.discord-panel{flex-direction:column;align-items:flex-start;padding:22px 20px}.discord-panel h2{font-size:1.55rem}.discord-actions{width:100%;justify-content:flex-start}.rules-view header{padding:16px 18px}.rules-view header h1{font-size:1.55rem}.rules-page{padding:24px 20px}.rules-page h2{font-size:1.65rem}}
|
||||
|
||||
Reference in New Issue
Block a user