Spaces:
Running
Running
Manual changes saved
Browse files- index.html +403 -1
index.html
CHANGED
|
@@ -2507,7 +2507,409 @@
|
|
| 2507 |
feather.replace();
|
| 2508 |
resizeCanvas();
|
| 2509 |
</script>
|
| 2510 |
-
<!-- LOBBY
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2511 |
<style>
|
| 2512 |
/* Simple styles for inline name edit and cheat modal */
|
| 2513 |
#lobbyNameInput {
|
|
|
|
| 2507 |
feather.replace();
|
| 2508 |
resizeCanvas();
|
| 2509 |
</script>
|
| 2510 |
+
<!-- LOBBY APPEND START -->
|
| 2511 |
+
<style>
|
| 2512 |
+
#lobbyInjectBtn {
|
| 2513 |
+
position: fixed;
|
| 2514 |
+
top: 12px;
|
| 2515 |
+
right: 12px;
|
| 2516 |
+
z-index: 9999;
|
| 2517 |
+
background: linear-gradient(180deg,#ffd86b,#f0c84a);
|
| 2518 |
+
color:#071021;
|
| 2519 |
+
border: none;
|
| 2520 |
+
padding:8px 12px;
|
| 2521 |
+
border-radius:10px;
|
| 2522 |
+
font-weight:800;
|
| 2523 |
+
cursor:pointer;
|
| 2524 |
+
box-shadow:0 8px 20px rgba(0,0,0,0.45);
|
| 2525 |
+
}
|
| 2526 |
+
#lobbyScreenInjected {
|
| 2527 |
+
position: fixed;
|
| 2528 |
+
inset: 0;
|
| 2529 |
+
z-index: 9998;
|
| 2530 |
+
display: none;
|
| 2531 |
+
align-items: center;
|
| 2532 |
+
justify-content: center;
|
| 2533 |
+
background: rgba(6,10,18,0.85);
|
| 2534 |
+
padding: 20px;
|
| 2535 |
+
box-sizing: border-box;
|
| 2536 |
+
}
|
| 2537 |
+
#lobbyCardInjected {
|
| 2538 |
+
width: min(960px, 96%);
|
| 2539 |
+
background: rgba(8,12,20,0.96);
|
| 2540 |
+
border-radius: 12px;
|
| 2541 |
+
padding: 18px;
|
| 2542 |
+
border: 1px solid rgba(255,255,255,0.04);
|
| 2543 |
+
color:#eaf6ff;
|
| 2544 |
+
box-shadow: 0 14px 48px rgba(0,0,0,0.7);
|
| 2545 |
+
display:flex;
|
| 2546 |
+
gap:16px;
|
| 2547 |
+
align-items:flex-start;
|
| 2548 |
+
flex-wrap:wrap;
|
| 2549 |
+
}
|
| 2550 |
+
#lobbyLeftInjected { width:220px; display:flex; flex-direction:column; gap:10px; align-items:center; }
|
| 2551 |
+
#lobbyPlayerImgInjected { width:180px; height:180px; border-radius:10px; object-fit:cover; background:#071021; }
|
| 2552 |
+
.lobbyStatInjected { background:rgba(255,255,255,0.03); padding:8px 10px; border-radius:8px; font-weight:700; color:#fff; font-size:14px; }
|
| 2553 |
+
.lobbyBtnInjected {
|
| 2554 |
+
background: linear-gradient(180deg,#ffd86b,#f0c84a);
|
| 2555 |
+
color:#071021;
|
| 2556 |
+
border:none;
|
| 2557 |
+
padding:10px 14px;
|
| 2558 |
+
border-radius:10px;
|
| 2559 |
+
cursor:pointer;
|
| 2560 |
+
font-weight:800;
|
| 2561 |
+
}
|
| 2562 |
+
.lobbyAltBtnInjected {
|
| 2563 |
+
background: rgba(255,255,255,0.03);
|
| 2564 |
+
color:#e2eeff;
|
| 2565 |
+
border:1px solid rgba(255,255,255,0.04);
|
| 2566 |
+
padding:8px 10px;
|
| 2567 |
+
border-radius:8px;
|
| 2568 |
+
cursor:pointer;
|
| 2569 |
+
}
|
| 2570 |
+
.lobbyModalInjected { position:fixed; inset:0; display:none; align-items:center; justify-content:center; z-index:10000; background: rgba(0,0,0,0.45); }
|
| 2571 |
+
.lobbyModalCardInjected { width:min(720px,96%); background: rgba(8,12,20,0.98); padding:14px; border-radius:10px; border:1px solid rgba(255,255,255,0.04); color:#dff4ff; }
|
| 2572 |
+
.lobbyListInjected { display:flex; flex-direction:column; gap:8px; margin-top:8px; }
|
| 2573 |
+
.lobbyItemInjected { display:flex; justify-content:space-between; align-items:center; background:rgba(255,255,255,0.02); padding:10px; border-radius:8px; }
|
| 2574 |
+
.smallMutedInjected { font-size:13px; color:#9fb0c9; }
|
| 2575 |
+
@media (max-width:720px){
|
| 2576 |
+
#lobbyLeftInjected { width:100%; flex-direction:row; gap:10px; }
|
| 2577 |
+
#lobbyPlayerImgInjected { width:84px; height:84px; }
|
| 2578 |
+
}
|
| 2579 |
+
</style>
|
| 2580 |
+
|
| 2581 |
+
<!-- Inject open button (fixed) -->
|
| 2582 |
+
<button id="lobbyInjectBtn" aria-controls="lobbyScreenInjected" title="Open Lobby">Lobby</button>
|
| 2583 |
+
|
| 2584 |
+
<!-- Lobby Overlay -->
|
| 2585 |
+
<div id="lobbyScreenInjected" role="dialog" aria-modal="true" aria-hidden="true">
|
| 2586 |
+
<div id="lobbyCardInjected">
|
| 2587 |
+
<div id="lobbyLeftInjected">
|
| 2588 |
+
<img id="lobbyPlayerImgInjected" src="https://www.vhv.rs/dpng/d/17-179278_fortnite-default-skin-blonde-hair-hd-png-download.png" alt="Player" />
|
| 2589 |
+
<div style="text-align:center;">
|
| 2590 |
+
<div style="font-weight:900; font-size:18px;" id="lobbyPlayerNameInjected">You</div>
|
| 2591 |
+
<div class="smallMutedInjected" id="lobbyPlayerSkinInjected">Skin: Default</div>
|
| 2592 |
+
</div>
|
| 2593 |
+
</div>
|
| 2594 |
+
|
| 2595 |
+
<div style="flex:1; min-width:220px;">
|
| 2596 |
+
<div style="display:flex;justify-content:space-between;align-items:center;gap:12px;">
|
| 2597 |
+
<div>
|
| 2598 |
+
<div style="font-size:20px;font-weight:900;color:#ffd86b">Lobby</div>
|
| 2599 |
+
<div class="smallMutedInjected">Open the shop, change room, or return to the landing screen</div>
|
| 2600 |
+
</div>
|
| 2601 |
+
<div style="display:flex;gap:8px;align-items:center">
|
| 2602 |
+
<div class="lobbyStatInjected">B-Bucks: <span id="lobbyBBucksInjected" style="margin-left:8px;color:#fff">0</span></div>
|
| 2603 |
+
<div class="lobbyStatInjected">Wins: <span id="lobbyWinsInjected" style="margin-left:8px;color:#fff">0</span></div>
|
| 2604 |
+
<div class="lobbyStatInjected">All Kills: <span id="lobbyKillsInjected" style="margin-left:8px;color:#fff">0</span></div>
|
| 2605 |
+
</div>
|
| 2606 |
+
</div>
|
| 2607 |
+
|
| 2608 |
+
<div style="margin-top:12px; display:flex; gap:10px; flex-wrap:wrap;">
|
| 2609 |
+
<button id="lobbyStartInjected" class="lobbyBtnInjected" title="Return to landing screen">Start (choose landing)</button>
|
| 2610 |
+
<button id="lobbyChangeRoomInjected" class="lobbyAltBtnInjected">Changing Room</button>
|
| 2611 |
+
<button id="lobbyShopInjected" class="lobbyAltBtnInjected">Shop</button>
|
| 2612 |
+
<button id="lobbyCloseInjected" class="lobbyAltBtnInjected">Close</button>
|
| 2613 |
+
</div>
|
| 2614 |
+
|
| 2615 |
+
<div style="margin-top:12px;">
|
| 2616 |
+
<div style="font-weight:800">Cosmetics & Skins</div>
|
| 2617 |
+
<div class="smallMutedInjected" id="lobbyOwnedInjected">No cosmetics owned</div>
|
| 2618 |
+
</div>
|
| 2619 |
+
</div>
|
| 2620 |
+
</div>
|
| 2621 |
+
</div>
|
| 2622 |
+
|
| 2623 |
+
<!-- Change Room Modal -->
|
| 2624 |
+
<div class="lobbyModalInjected" id="lobbyChangeRoomModalInjected" aria-hidden="true">
|
| 2625 |
+
<div class="lobbyModalCardInjected" role="dialog" aria-modal="true" aria-label="Changing Room">
|
| 2626 |
+
<div style="display:flex;justify-content:space-between;align-items:center">
|
| 2627 |
+
<div>
|
| 2628 |
+
<div style="font-weight:900">Changing Room</div>
|
| 2629 |
+
<div class="smallMutedInjected">Equip cosmetics or skins</div>
|
| 2630 |
+
</div>
|
| 2631 |
+
<div><button class="lobbyAltBtnInjected" id="lobbyChangeRoomCloseInjected">Close</button></div>
|
| 2632 |
+
</div>
|
| 2633 |
+
<div class="lobbyListInjected" id="lobbyChangeRoomListInjected"></div>
|
| 2634 |
+
</div>
|
| 2635 |
+
</div>
|
| 2636 |
+
|
| 2637 |
+
<!-- Shop Modal -->
|
| 2638 |
+
<div class="lobbyModalInjected" id="lobbyShopModalInjected" aria-hidden="true">
|
| 2639 |
+
<div class="lobbyModalCardInjected" role="dialog" aria-modal="true" aria-label="Shop">
|
| 2640 |
+
<div style="display:flex;justify-content:space-between;align-items:center">
|
| 2641 |
+
<div>
|
| 2642 |
+
<div style="font-weight:900">Shop</div>
|
| 2643 |
+
<div class="smallMutedInjected">Buy cosmetics with B-Bucks (demo items)</div>
|
| 2644 |
+
</div>
|
| 2645 |
+
<div><button class="lobbyAltBtnInjected" id="lobbyShopCloseInjected">Close</button></div>
|
| 2646 |
+
</div>
|
| 2647 |
+
<div class="lobbyListInjected" id="lobbyShopItemListInjected"></div>
|
| 2648 |
+
</div>
|
| 2649 |
+
</div>
|
| 2650 |
+
|
| 2651 |
+
<script>
|
| 2652 |
+
(function(){
|
| 2653 |
+
// Local storage key and default state
|
| 2654 |
+
const LS_KEY = 'battlezone_lobby_v1';
|
| 2655 |
+
const defaultState = { bBucks:0, wins:0, allKills:0, equippedSkin:'Default', cosmetics:[] };
|
| 2656 |
+
|
| 2657 |
+
function loadState(){
|
| 2658 |
+
try {
|
| 2659 |
+
const raw = localStorage.getItem(LS_KEY);
|
| 2660 |
+
if (!raw) return { ...defaultState };
|
| 2661 |
+
return { ...defaultState, ...JSON.parse(raw) };
|
| 2662 |
+
} catch(e){
|
| 2663 |
+
console.error('lobby load error', e);
|
| 2664 |
+
return { ...defaultState };
|
| 2665 |
+
}
|
| 2666 |
+
}
|
| 2667 |
+
function persistState(s){
|
| 2668 |
+
try { localStorage.setItem(LS_KEY, JSON.stringify(s)); } catch(e){ console.error('lobby save error', e); }
|
| 2669 |
+
}
|
| 2670 |
+
|
| 2671 |
+
const state = loadState();
|
| 2672 |
+
|
| 2673 |
+
// Elements
|
| 2674 |
+
const openBtn = document.getElementById('lobbyInjectBtn');
|
| 2675 |
+
const screen = document.getElementById('lobbyScreenInjected');
|
| 2676 |
+
const startBtn = document.getElementById('lobbyStartInjected');
|
| 2677 |
+
const changeRoomBtn = document.getElementById('lobbyChangeRoomInjected');
|
| 2678 |
+
const shopBtn = document.getElementById('lobbyShopInjected');
|
| 2679 |
+
const closeBtn = document.getElementById('lobbyCloseInjected');
|
| 2680 |
+
|
| 2681 |
+
const playerImg = document.getElementById('lobbyPlayerImgInjected');
|
| 2682 |
+
const playerSkinEl = document.getElementById('lobbyPlayerSkinInjected');
|
| 2683 |
+
const bbucksEl = document.getElementById('lobbyBBucksInjected');
|
| 2684 |
+
const winsEl = document.getElementById('lobbyWinsInjected');
|
| 2685 |
+
const killsEl = document.getElementById('lobbyKillsInjected');
|
| 2686 |
+
const ownedEl = document.getElementById('lobbyOwnedInjected');
|
| 2687 |
+
|
| 2688 |
+
const changeModal = document.getElementById('lobbyChangeRoomModalInjected');
|
| 2689 |
+
const changeModalClose = document.getElementById('lobbyChangeRoomCloseInjected');
|
| 2690 |
+
const changeList = document.getElementById('lobbyChangeRoomListInjected');
|
| 2691 |
+
|
| 2692 |
+
const shopModal = document.getElementById('lobbyShopModalInjected');
|
| 2693 |
+
const shopModalClose = document.getElementById('lobbyShopCloseInjected');
|
| 2694 |
+
const shopList = document.getElementById('lobbyShopItemListInjected');
|
| 2695 |
+
|
| 2696 |
+
// Demo shop catalog, edit as desired
|
| 2697 |
+
const catalog = [
|
| 2698 |
+
{ id:'skin_neon', type:'skin', name:'Neon Suit', price:3, desc:'Bright neon suit' },
|
| 2699 |
+
{ id:'skin_stealth', type:'skin', name:'Stealth Camo', price:2, desc:'Dark camo' },
|
| 2700 |
+
{ id:'cos_banner', type:'cosmetic', name:'Victory Banner', price:1, desc:'Small victory banner' }
|
| 2701 |
+
];
|
| 2702 |
+
|
| 2703 |
+
function updateUI(){
|
| 2704 |
+
bbucksEl.textContent = state.bBucks || 0;
|
| 2705 |
+
winsEl.textContent = state.wins || 0;
|
| 2706 |
+
killsEl.textContent = state.allKills || 0;
|
| 2707 |
+
playerSkinEl.textContent = 'Skin: ' + (state.equippedSkin || 'Default');
|
| 2708 |
+
ownedEl.textContent = state.cosmetics && state.cosmetics.length ? 'Owned: ' + state.cosmetics.join(', ') : 'No cosmetics owned';
|
| 2709 |
+
}
|
| 2710 |
+
|
| 2711 |
+
function showLobby(){ screen.style.display = 'flex'; screen.setAttribute('aria-hidden','false'); updateUI(); }
|
| 2712 |
+
function hideLobby(){ screen.style.display = 'none'; screen.setAttribute('aria-hidden','true'); }
|
| 2713 |
+
|
| 2714 |
+
openBtn.addEventListener('click', ()=> { showLobby(); });
|
| 2715 |
+
|
| 2716 |
+
closeBtn.addEventListener('click', ()=> { hideLobby(); });
|
| 2717 |
+
|
| 2718 |
+
// Start: hide lobby and attempt to show existing landing screen if present
|
| 2719 |
+
startBtn.addEventListener('click', ()=>{
|
| 2720 |
+
hideLobby();
|
| 2721 |
+
const landing = document.getElementById('landingScreen');
|
| 2722 |
+
if (landing){
|
| 2723 |
+
// try to show landing (best-effort)
|
| 2724 |
+
landing.classList.remove('hidden');
|
| 2725 |
+
landing.style.display = '';
|
| 2726 |
+
// hide gameScreen if present
|
| 2727 |
+
const gs = document.getElementById('gameScreen');
|
| 2728 |
+
if (gs) gs.classList.add('hidden');
|
| 2729 |
+
} else if (typeof startGame === 'function') {
|
| 2730 |
+
// fallback to calling startGame if it exists
|
| 2731 |
+
try { startGame(); } catch(e){ console.warn('startGame invocation failed', e); }
|
| 2732 |
+
} else {
|
| 2733 |
+
// no landing, inform user
|
| 2734 |
+
alert('Landing screen not found in page — lobby closed.');
|
| 2735 |
+
}
|
| 2736 |
+
});
|
| 2737 |
+
|
| 2738 |
+
// Change Room modal
|
| 2739 |
+
changeRoomBtn.addEventListener('click', ()=>{
|
| 2740 |
+
buildChangeList();
|
| 2741 |
+
changeModal.style.display = 'flex';
|
| 2742 |
+
changeModal.setAttribute('aria-hidden','false');
|
| 2743 |
+
});
|
| 2744 |
+
changeModalClose.addEventListener('click', ()=>{
|
| 2745 |
+
changeModal.style.display = 'none';
|
| 2746 |
+
changeModal.setAttribute('aria-hidden','true');
|
| 2747 |
+
});
|
| 2748 |
+
|
| 2749 |
+
function buildChangeList(){
|
| 2750 |
+
changeList.innerHTML = '';
|
| 2751 |
+
if (!(state.cosmetics && state.cosmetics.length)){
|
| 2752 |
+
const div = document.createElement('div');
|
| 2753 |
+
div.className = 'lobbyItemInjected';
|
| 2754 |
+
div.textContent = 'No cosmetics available. Visit the Shop to purchase.';
|
| 2755 |
+
changeList.appendChild(div);
|
| 2756 |
+
return;
|
| 2757 |
+
}
|
| 2758 |
+
state.cosmetics.forEach(cid => {
|
| 2759 |
+
const item = catalog.find(c=>c.id===cid) || { id:cid, name:cid, type:'cosmetic' };
|
| 2760 |
+
const wrap = document.createElement('div');
|
| 2761 |
+
wrap.className = 'lobbyItemInjected';
|
| 2762 |
+
const left = document.createElement('div');
|
| 2763 |
+
left.innerHTML = `<div style="font-weight:800">${item.name}</div><div class="smallMutedInjected">${item.desc||''}</div>`;
|
| 2764 |
+
const right = document.createElement('div');
|
| 2765 |
+
const equip = document.createElement('button');
|
| 2766 |
+
equip.className = 'lobbyAltBtnInjected';
|
| 2767 |
+
equip.textContent = 'Equip';
|
| 2768 |
+
equip.addEventListener('click', ()=>{
|
| 2769 |
+
if (item.type === 'skin') state.equippedSkin = item.name;
|
| 2770 |
+
persistState(state);
|
| 2771 |
+
updateUI();
|
| 2772 |
+
alert('Equipped: ' + item.name);
|
| 2773 |
+
});
|
| 2774 |
+
right.appendChild(equip);
|
| 2775 |
+
wrap.appendChild(left); wrap.appendChild(right);
|
| 2776 |
+
changeList.appendChild(wrap);
|
| 2777 |
+
});
|
| 2778 |
+
}
|
| 2779 |
+
|
| 2780 |
+
// Shop modal build
|
| 2781 |
+
shopBtn.addEventListener('click', ()=> {
|
| 2782 |
+
buildShopList();
|
| 2783 |
+
shopModal.style.display = 'flex';
|
| 2784 |
+
shopModal.setAttribute('aria-hidden','false');
|
| 2785 |
+
});
|
| 2786 |
+
shopModalClose.addEventListener('click', ()=> {
|
| 2787 |
+
shopModal.style.display = 'none';
|
| 2788 |
+
shopModal.setAttribute('aria-hidden','true');
|
| 2789 |
+
});
|
| 2790 |
+
|
| 2791 |
+
function buildShopList(){
|
| 2792 |
+
shopList.innerHTML = '';
|
| 2793 |
+
catalog.forEach(item => {
|
| 2794 |
+
const wrap = document.createElement('div');
|
| 2795 |
+
wrap.className = 'lobbyItemInjected';
|
| 2796 |
+
const left = document.createElement('div');
|
| 2797 |
+
left.innerHTML = `<div style="font-weight:800">${item.name}</div><div class="smallMutedInjected">${item.desc}</div>`;
|
| 2798 |
+
const right = document.createElement('div');
|
| 2799 |
+
right.style.display = 'flex';
|
| 2800 |
+
right.style.gap = '8px';
|
| 2801 |
+
const price = document.createElement('div');
|
| 2802 |
+
price.className = 'smallMutedInjected';
|
| 2803 |
+
price.textContent = item.price + ' B-Bucks';
|
| 2804 |
+
const buy = document.createElement('button');
|
| 2805 |
+
buy.className = 'lobbyAltBtnInjected';
|
| 2806 |
+
buy.textContent = 'Buy';
|
| 2807 |
+
buy.addEventListener('click', ()=> {
|
| 2808 |
+
if (state.bBucks >= item.price){
|
| 2809 |
+
state.bBucks -= item.price;
|
| 2810 |
+
state.cosmetics = state.cosmetics || [];
|
| 2811 |
+
state.cosmetics.push(item.id);
|
| 2812 |
+
if (item.type === 'skin') state.equippedSkin = item.name;
|
| 2813 |
+
persistState(state);
|
| 2814 |
+
updateUI();
|
| 2815 |
+
alert('Purchased: ' + item.name);
|
| 2816 |
+
} else {
|
| 2817 |
+
alert('Not enough B-Bucks. Earn them by winning (1 B-Buck per win).');
|
| 2818 |
+
}
|
| 2819 |
+
});
|
| 2820 |
+
right.appendChild(price);
|
| 2821 |
+
right.appendChild(buy);
|
| 2822 |
+
wrap.appendChild(left);
|
| 2823 |
+
wrap.appendChild(right);
|
| 2824 |
+
shopList.appendChild(wrap);
|
| 2825 |
+
});
|
| 2826 |
+
}
|
| 2827 |
+
|
| 2828 |
+
// Function to credit a win (idempotent guard per invocation optionally)
|
| 2829 |
+
let lastWinTimestamp = 0;
|
| 2830 |
+
function creditWin(fromPlayerKills){
|
| 2831 |
+
const now = Date.now();
|
| 2832 |
+
if (now - lastWinTimestamp < 1500) return; // simple debounce
|
| 2833 |
+
lastWinTimestamp = now;
|
| 2834 |
+
state.wins = (state.wins || 0) + 1;
|
| 2835 |
+
state.bBucks = (state.bBucks || 0) + 1; // 1 B-Buck per win
|
| 2836 |
+
if (typeof fromPlayerKills === 'number') state.allKills = (state.allKills || 0) + fromPlayerKills;
|
| 2837 |
+
persistState(state);
|
| 2838 |
+
updateUI();
|
| 2839 |
+
}
|
| 2840 |
+
|
| 2841 |
+
// Observe victory screen presence (if exists). Will attempt to detect show events and credit a win.
|
| 2842 |
+
(function hookVictoryDetection(){
|
| 2843 |
+
const victoryEl = document.getElementById('victoryScreen');
|
| 2844 |
+
if (victoryEl){
|
| 2845 |
+
const observer = new MutationObserver((mutations)=>{
|
| 2846 |
+
for (const m of mutations){
|
| 2847 |
+
if (m.type === 'attributes'){
|
| 2848 |
+
// visible detection: not hidden, display not 'none', opacity > 0
|
| 2849 |
+
const comp = window.getComputedStyle(victoryEl);
|
| 2850 |
+
const visible = comp && comp.display !== 'none' && comp.visibility !== 'hidden' && parseFloat(comp.opacity||'1') > 0;
|
| 2851 |
+
if (visible) {
|
| 2852 |
+
// attempt to get player.kills if present
|
| 2853 |
+
let kills = undefined;
|
| 2854 |
+
try { if (typeof player !== 'undefined' && player && typeof player.kills === 'number') kills = player.kills; } catch(e){}
|
| 2855 |
+
creditWin(kills);
|
| 2856 |
+
}
|
| 2857 |
+
}
|
| 2858 |
+
}
|
| 2859 |
+
});
|
| 2860 |
+
observer.observe(victoryEl, { attributes:true, attributeFilter:['class','style','aria-hidden'] });
|
| 2861 |
+
} else {
|
| 2862 |
+
// fallback: if continueBtn exists, hook click
|
| 2863 |
+
const cont = document.getElementById('continueBtn');
|
| 2864 |
+
if (cont){
|
| 2865 |
+
cont.addEventListener('click', ()=> {
|
| 2866 |
+
let kills = undefined;
|
| 2867 |
+
try { if (typeof player !== 'undefined' && player && typeof player.kills === 'number') kills = player.kills; } catch(e){}
|
| 2868 |
+
creditWin(kills);
|
| 2869 |
+
});
|
| 2870 |
+
}
|
| 2871 |
+
}
|
| 2872 |
+
})();
|
| 2873 |
+
|
| 2874 |
+
// Hook goHomeBtn if exists to auto-open lobby (optional behavior)
|
| 2875 |
+
const goHome = document.getElementById('goHomeBtn');
|
| 2876 |
+
if (goHome){
|
| 2877 |
+
goHome.addEventListener('click', ()=> {
|
| 2878 |
+
persistState(state);
|
| 2879 |
+
// show lobby so user sees updated B-Bucks
|
| 2880 |
+
showLobby();
|
| 2881 |
+
});
|
| 2882 |
+
}
|
| 2883 |
+
|
| 2884 |
+
// Expose show/hide in case you want to call them externally
|
| 2885 |
+
window.showLobbyInjected = showLobby;
|
| 2886 |
+
window.hideLobbyInjected = hideLobby;
|
| 2887 |
+
|
| 2888 |
+
// Update UI initial
|
| 2889 |
+
updateUI();
|
| 2890 |
+
|
| 2891 |
+
// Keep UI in-sync if localStorage changed in another tab
|
| 2892 |
+
window.addEventListener('storage', (ev)=>{
|
| 2893 |
+
if (ev.key === LS_KEY){
|
| 2894 |
+
Object.assign(state, loadState());
|
| 2895 |
+
updateUI();
|
| 2896 |
+
}
|
| 2897 |
+
});
|
| 2898 |
+
|
| 2899 |
+
// Make sure that if your page dynamically replaces DOM, our open button still available
|
| 2900 |
+
const topLevelObserver = new MutationObserver(()=> {
|
| 2901 |
+
if (!document.getElementById('lobbyInjectBtn')) {
|
| 2902 |
+
document.body.appendChild(openBtn);
|
| 2903 |
+
}
|
| 2904 |
+
});
|
| 2905 |
+
topLevelObserver.observe(document.documentElement, { childList:true, subtree:true });
|
| 2906 |
+
|
| 2907 |
+
// Helpful console info
|
| 2908 |
+
console.log('Lobby injection loaded. Use the yellow "Lobby" button at top-right to open.');
|
| 2909 |
+
})();
|
| 2910 |
+
</script>
|
| 2911 |
+
<!-- LOBBY APPEND END -->
|
| 2912 |
+
<!-- LOBBY NAME EDIT + CHEAT CODE APPEND START -->
|
| 2913 |
<style>
|
| 2914 |
/* Simple styles for inline name edit and cheat modal */
|
| 2915 |
#lobbyNameInput {
|