Upload files to "html"
This commit is contained in:
parent
27445f1778
commit
e570e5cf36
112
html/apperance.css
Normal file
112
html/apperance.css
Normal file
|
|
@ -0,0 +1,112 @@
|
||||||
|
html, body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: transparent;
|
||||||
|
overflow: hidden;
|
||||||
|
font-family: Arial, Helvetica, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* block game clicks by default */
|
||||||
|
body { pointer-events: none; }
|
||||||
|
#wrap, #wrap * { pointer-events: auto; }
|
||||||
|
|
||||||
|
.hidden { display: none !important; }
|
||||||
|
|
||||||
|
#wrap {
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#wrap::before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
inset: 0;
|
||||||
|
background: radial-gradient(circle at 50% 40%, rgba(0,0,0,0.15), rgba(0,0,0,0.60));
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel {
|
||||||
|
position: relative;
|
||||||
|
z-index: 2;
|
||||||
|
width: 420px;
|
||||||
|
border-radius: 14px;
|
||||||
|
background: rgba(18,18,22,0.90);
|
||||||
|
box-shadow: 0 12px 40px rgba(0,0,0,0.45);
|
||||||
|
padding: 18px;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: 22px;
|
||||||
|
font-weight: 700;
|
||||||
|
margin-bottom: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.row {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 10px 0;
|
||||||
|
border-top: 1px solid rgba(255,255,255,0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
font-size: 14px;
|
||||||
|
opacity: 0.9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.controls {
|
||||||
|
display: flex;
|
||||||
|
gap: 8px;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.value {
|
||||||
|
min-width: 48px;
|
||||||
|
text-align: center;
|
||||||
|
font-weight: 700;
|
||||||
|
opacity: 0.95;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
border: 0;
|
||||||
|
padding: 8px 10px;
|
||||||
|
border-radius: 10px;
|
||||||
|
background: rgba(255,255,255,0.12);
|
||||||
|
color: #fff;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:hover {
|
||||||
|
background: rgba(255,255,255,0.18);
|
||||||
|
}
|
||||||
|
|
||||||
|
button.primary {
|
||||||
|
background: rgba(80,160,255,0.85);
|
||||||
|
}
|
||||||
|
|
||||||
|
button.primary:hover {
|
||||||
|
background: rgba(80,160,255,1);
|
||||||
|
}
|
||||||
|
|
||||||
|
button.active {
|
||||||
|
outline: 2px solid rgba(80,160,255,0.9);
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
padding-top: 12px;
|
||||||
|
border-top: 1px solid rgba(255,255,255,0.08);
|
||||||
|
margin-top: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hint {
|
||||||
|
margin-top: 10px;
|
||||||
|
font-size: 12px;
|
||||||
|
opacity: 0.65;
|
||||||
|
}
|
||||||
384
html/apperance.js
Normal file
384
html/apperance.js
Normal file
|
|
@ -0,0 +1,384 @@
|
||||||
|
console.log("[ATM UI] atm.js loaded");
|
||||||
|
console.log("[NUI] loaded");
|
||||||
|
|
||||||
|
// =====================
|
||||||
|
// DOM refs
|
||||||
|
// =====================
|
||||||
|
const wrap = document.getElementById("wrap");
|
||||||
|
const cashEl = document.getElementById("cash");
|
||||||
|
const bankEl = document.getElementById("bank");
|
||||||
|
const amountEl = document.getElementById("amount");
|
||||||
|
|
||||||
|
const btnDeposit = document.getElementById("btnDeposit");
|
||||||
|
const btnWithdraw = document.getElementById("btnWithdraw");
|
||||||
|
const btnClose = document.getElementById("btnClose");
|
||||||
|
|
||||||
|
// Gang Bank HUD
|
||||||
|
const gbHud = document.getElementById("gangbankHud");
|
||||||
|
const gbAmount = document.getElementById("gbAmount");
|
||||||
|
const gbLabel = document.getElementById("gbLabel");
|
||||||
|
|
||||||
|
// Capture HUD
|
||||||
|
const capHud = document.getElementById("captureHud");
|
||||||
|
const capTitle = document.getElementById("capTitle");
|
||||||
|
const capFill = document.getElementById("capFill");
|
||||||
|
const capSub = document.getElementById("capSub");
|
||||||
|
const capBar = document.getElementById("capBar");
|
||||||
|
|
||||||
|
// Leaderboard HUD
|
||||||
|
const lbHud = document.getElementById("leaderboardHud");
|
||||||
|
const lbTitle = document.getElementById("lbTitle");
|
||||||
|
const lbRows = document.getElementById("lbRows");
|
||||||
|
const lbError = document.getElementById("lbError");
|
||||||
|
|
||||||
|
// =====================
|
||||||
|
// State
|
||||||
|
// =====================
|
||||||
|
let lastGangBank = null;
|
||||||
|
|
||||||
|
// =====================
|
||||||
|
// Helpers
|
||||||
|
// =====================
|
||||||
|
function fmt(n) {
|
||||||
|
n = Number(n || 0);
|
||||||
|
if (!Number.isFinite(n)) n = 0;
|
||||||
|
return "$" + Math.floor(n).toLocaleString();
|
||||||
|
}
|
||||||
|
|
||||||
|
function post(name, data = {}) {
|
||||||
|
try {
|
||||||
|
fetch(`https://${GetParentResourceName()}/${name}`, {
|
||||||
|
method: "POST",
|
||||||
|
headers: { "Content-Type": "application/json; charset=UTF-8" },
|
||||||
|
body: JSON.stringify(data)
|
||||||
|
}).catch(() => {});
|
||||||
|
} catch (e) {
|
||||||
|
console.log("[ATM UI] post failed:", name, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getAmount() {
|
||||||
|
const v = Number(amountEl?.value || 0);
|
||||||
|
if (!Number.isFinite(v)) return 0;
|
||||||
|
return Math.floor(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
// =====================
|
||||||
|
// ATM UI
|
||||||
|
// =====================
|
||||||
|
function hideATM() {
|
||||||
|
wrap?.classList.add("hidden");
|
||||||
|
}
|
||||||
|
|
||||||
|
function showATM() {
|
||||||
|
wrap?.classList.remove("hidden");
|
||||||
|
setTimeout(() => amountEl?.focus(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========================
|
||||||
|
// Turf Capture HUD (fixed)
|
||||||
|
// ========================
|
||||||
|
function capShow() {
|
||||||
|
capHud?.classList.remove("cap-hidden");
|
||||||
|
}
|
||||||
|
|
||||||
|
function capHide() {
|
||||||
|
capHud?.classList.add("cap-hidden");
|
||||||
|
if (capFill) capFill.style.width = "0%";
|
||||||
|
if (capSub) capSub.textContent = "0%";
|
||||||
|
}
|
||||||
|
|
||||||
|
function capStart(titleText) {
|
||||||
|
capShow();
|
||||||
|
if (capTitle) capTitle.textContent = titleText || "Capturing…";
|
||||||
|
capSet(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function capSet(t) {
|
||||||
|
t = Math.max(0, Math.min(1, Number(t || 0)));
|
||||||
|
const pct = Math.round(t * 100);
|
||||||
|
if (capFill) capFill.style.width = pct + "%";
|
||||||
|
if (capSub) capSub.textContent = pct + "%";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Capture styling:
|
||||||
|
* - fillCss = contesting/capturing gang
|
||||||
|
* - bgCss = outgoing/current owner gang
|
||||||
|
*/
|
||||||
|
function capStyle(fillCss, bgCss) {
|
||||||
|
if (capFill && fillCss) capFill.style.background = fillCss;
|
||||||
|
if (capBar && bgCss) capBar.style.background = bgCss;
|
||||||
|
}
|
||||||
|
|
||||||
|
function capPaused(isPaused) {
|
||||||
|
if (!capSub) return;
|
||||||
|
if (isPaused) capSub.textContent = "PAUSED";
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========================
|
||||||
|
// Leaderboard HUD
|
||||||
|
// ========================
|
||||||
|
function lbShow() {
|
||||||
|
lbHud?.classList.remove("lb-hidden");
|
||||||
|
}
|
||||||
|
|
||||||
|
function lbHide() {
|
||||||
|
lbHud?.classList.add("lb-hidden");
|
||||||
|
}
|
||||||
|
|
||||||
|
function lbRender(payload) {
|
||||||
|
if (!payload) return;
|
||||||
|
|
||||||
|
lbShow();
|
||||||
|
|
||||||
|
if (lbTitle) lbTitle.textContent = String(payload.title || "Most influence");
|
||||||
|
|
||||||
|
// Error display (optional)
|
||||||
|
if (payload.error) {
|
||||||
|
if (lbError) {
|
||||||
|
lbError.textContent = String(payload.error);
|
||||||
|
lbError.classList.remove("lb-hidden");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
lbError?.classList.add("lb-hidden");
|
||||||
|
if (lbError) lbError.textContent = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!lbRows) return;
|
||||||
|
lbRows.innerHTML = "";
|
||||||
|
|
||||||
|
const rows = Array.isArray(payload.rows) ? payload.rows : [];
|
||||||
|
|
||||||
|
rows.forEach((r) => {
|
||||||
|
const gangId = Number(r.gangId);
|
||||||
|
const name = String(r.name ?? "Unknown");
|
||||||
|
const val = Number(r.value ?? 0);
|
||||||
|
|
||||||
|
// 🚫 Skip Police
|
||||||
|
if (gangId === 3) return;
|
||||||
|
|
||||||
|
// --- Color handling ---
|
||||||
|
const rgb = Array.isArray(r.rgb) ? r.rgb : [255, 255, 255];
|
||||||
|
|
||||||
|
let R = Number(rgb[0]);
|
||||||
|
let G = Number(rgb[1]);
|
||||||
|
let B = Number(rgb[2]);
|
||||||
|
|
||||||
|
// Fallback safety
|
||||||
|
if (!Number.isFinite(R)) R = 255;
|
||||||
|
if (!Number.isFinite(G)) G = 255;
|
||||||
|
if (!Number.isFinite(B)) B = 255;
|
||||||
|
|
||||||
|
// Brighten very dark colors only (Lost Gang)
|
||||||
|
if (R < 80 && G < 80 && B < 80) {
|
||||||
|
R = Math.min(255, R + 80);
|
||||||
|
G = Math.min(255, G + 80);
|
||||||
|
B = Math.min(255, B + 80);
|
||||||
|
}
|
||||||
|
|
||||||
|
const div = document.createElement("div");
|
||||||
|
div.className = "lb-row";
|
||||||
|
|
||||||
|
div.innerHTML = `
|
||||||
|
<span class="lb-name" style="color: rgb(${R}, ${G}, ${B});">
|
||||||
|
${escapeHtml(name)}
|
||||||
|
</span>
|
||||||
|
<span class="lb-val">${Number.isFinite(val) ? val : 0}</span>
|
||||||
|
`;
|
||||||
|
|
||||||
|
lbRows.appendChild(div);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function escapeHtml(s) {
|
||||||
|
return String(s)
|
||||||
|
.replaceAll("&", "&")
|
||||||
|
.replaceAll("<", "<")
|
||||||
|
.replaceAll(">", ">")
|
||||||
|
.replaceAll('"', """)
|
||||||
|
.replaceAll("'", "'");
|
||||||
|
}
|
||||||
|
|
||||||
|
function setGangBankColor(rgb) {
|
||||||
|
if (!gbLabel) return;
|
||||||
|
|
||||||
|
const arr = Array.isArray(rgb) ? rgb : [255, 255, 255];
|
||||||
|
|
||||||
|
let R = Number(arr[0]);
|
||||||
|
let G = Number(arr[1]);
|
||||||
|
let B = Number(arr[2]);
|
||||||
|
|
||||||
|
if (!Number.isFinite(R)) R = 255;
|
||||||
|
if (!Number.isFinite(G)) G = 255;
|
||||||
|
if (!Number.isFinite(B)) B = 255;
|
||||||
|
|
||||||
|
// Brighten very dark colors (e.g. Lost Gang)
|
||||||
|
if (R < 80 && G < 80 && B < 80) {
|
||||||
|
R = Math.min(255, R + 80);
|
||||||
|
G = Math.min(255, G + 80);
|
||||||
|
B = Math.min(255, B + 80);
|
||||||
|
}
|
||||||
|
|
||||||
|
const css = `rgb(${R}, ${G}, ${B})`;
|
||||||
|
|
||||||
|
// Apply to label (and optionally amount if you want later)
|
||||||
|
gbLabel.style.setProperty("--gang-color", css);
|
||||||
|
gbLabel.style.color = "var(--gang-color)"; // ensures it shows even if CSS missing
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// =====================
|
||||||
|
// Boot
|
||||||
|
// =====================
|
||||||
|
document.addEventListener("DOMContentLoaded", () => {
|
||||||
|
hideATM();
|
||||||
|
capHide(); // ✅ was capStop() in your file (but didn’t exist)
|
||||||
|
lbHide(); // start hidden until first update
|
||||||
|
|
||||||
|
console.log("[ATM UI] DOMContentLoaded -> posting atm:ready");
|
||||||
|
post("atm:ready");
|
||||||
|
});
|
||||||
|
|
||||||
|
// =====================
|
||||||
|
// Button wiring
|
||||||
|
// =====================
|
||||||
|
btnDeposit?.addEventListener("click", () => {
|
||||||
|
const amount = getAmount();
|
||||||
|
if (amount > 0) post("atm:deposit", { amount });
|
||||||
|
});
|
||||||
|
|
||||||
|
btnWithdraw?.addEventListener("click", () => {
|
||||||
|
const amount = getAmount();
|
||||||
|
if (amount > 0) post("atm:withdraw", { amount });
|
||||||
|
});
|
||||||
|
|
||||||
|
btnClose?.addEventListener("click", () => post("atm:close"));
|
||||||
|
|
||||||
|
document.addEventListener("keydown", (e) => {
|
||||||
|
if (e.key === "Escape") post("atm:close");
|
||||||
|
});
|
||||||
|
|
||||||
|
// =====================
|
||||||
|
// NUI messages (single listener)
|
||||||
|
// =====================
|
||||||
|
window.addEventListener("message", (event) => {
|
||||||
|
const data = event.data || {};
|
||||||
|
const type = data.type;
|
||||||
|
if (!type) return;
|
||||||
|
|
||||||
|
// Capture debug (optional)
|
||||||
|
if (type.startsWith("capture:")) {
|
||||||
|
// console.log("[NUI] capture msg", data);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
// -------- ATM --------
|
||||||
|
case "atm:open":
|
||||||
|
showATM();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "atm:close":
|
||||||
|
hideATM();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "atm:balances":
|
||||||
|
if (cashEl) cashEl.textContent = fmt(data.cash);
|
||||||
|
if (bankEl) bankEl.textContent = fmt(data.bank);
|
||||||
|
break;
|
||||||
|
|
||||||
|
// ---- Gang Bank HUD ----
|
||||||
|
case "gangbank:show":
|
||||||
|
gbHud?.classList.remove("gb-hidden");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "gangbank:hide":
|
||||||
|
gbHud?.classList.add("gb-hidden");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "gangbank:label": {
|
||||||
|
if (gbLabel) gbLabel.textContent = String(data.label || "Gang Bank");
|
||||||
|
|
||||||
|
// ✅ set color if provided
|
||||||
|
if (data.rgb) setGangBankColor(data.rgb);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case "gangbank:update": {
|
||||||
|
if (!gbAmount) break;
|
||||||
|
|
||||||
|
const amt = Number(data.balance ?? data.amount ?? 0);
|
||||||
|
gbAmount.textContent = fmt(amt);
|
||||||
|
|
||||||
|
// ✅ also accept rgb here (in case update is the only message carrying it)
|
||||||
|
if (data.rgb) setGangBankColor(data.rgb);
|
||||||
|
|
||||||
|
// pulse only if changed
|
||||||
|
if (lastGangBank !== null && amt !== lastGangBank) {
|
||||||
|
gbAmount.classList.remove("gb-pulse");
|
||||||
|
void gbAmount.offsetWidth; // restart animation
|
||||||
|
gbAmount.classList.add("gb-pulse");
|
||||||
|
}
|
||||||
|
lastGangBank = amt;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---- Turf Capture HUD ----
|
||||||
|
case "capture:start":
|
||||||
|
capStart(data.turfName || data.title || "Capturing…");
|
||||||
|
if (data.t !== undefined) capSet(data.t);
|
||||||
|
if (data.fill || data.bg) capStyle(data.fill, data.bg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "capture:set":
|
||||||
|
capShow();
|
||||||
|
capSet(data.t);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "capture:style":
|
||||||
|
capStyle(data.fill, data.bg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "capture:paused":
|
||||||
|
capPaused(!!data.paused);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "capture:hint":
|
||||||
|
if (capSub && data.text) {
|
||||||
|
capSub.textContent = String(data.text);
|
||||||
|
setTimeout(() => {
|
||||||
|
// only clear if still showing the same hint-like text
|
||||||
|
if (capSub && capSub.textContent === String(data.text)) {
|
||||||
|
capSub.textContent = "";
|
||||||
|
}
|
||||||
|
}, 1500);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "capture:stop":
|
||||||
|
capHide();
|
||||||
|
break;
|
||||||
|
|
||||||
|
// ---- ✅ Leaderboard ----
|
||||||
|
// We accept either name:
|
||||||
|
// - "leaderboard:update" (client might send this)
|
||||||
|
// - "turfwar:leaderboard:update" (recommended)
|
||||||
|
case "leaderboard:update":
|
||||||
|
case "turfwar:leaderboard:update":
|
||||||
|
lbRender(data.payload || data);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "leaderboard:hide":
|
||||||
|
lbHide();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "leaderboard:show":
|
||||||
|
lbShow();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
Loading…
Reference in New Issue
Block a user