anycoder-af3b30b3 / index.html
towmasjan's picture
Upload folder using huggingface_hub
0677016 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>SIN CITY 3000 - RPG</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@400;700;900&family=Share+Tech+Mono&display=swap"
rel="stylesheet">
<style>
:root {
--neon-pink: #ff2a6d;
--neon-blue: #05d9e8;
--neon-green: #00ff9d;
--neon-yellow: #f9c80e;
--bg-dark: #01012b;
--bg-panel: #020238;
--text-main: #d1f7ff;
--glass: rgba(5, 217, 232, 0.1);
--border-glow: 0 0 10px var(--neon-blue);
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
scrollbar-width: thin;
scrollbar-color: var(--neon-blue) var(--bg-dark);
}
body {
background-color: #000;
background-image:
radial-gradient(circle at 50% 50%, #1a1a40 0%, #000 100%),
linear-gradient(0deg, rgba(0, 0, 0, 0.9) 0%, rgba(0, 0, 0, 0) 50%, rgba(0, 0, 0, 0.9) 100%);
color: var(--text-main);
font-family: 'Share Tech Mono', monospace;
height: 100vh;
overflow: hidden;
display: flex;
flex-direction: column;
position: relative;
}
/* CRT Overlay Effect */
body::after {
content: " ";
display: block;
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
background: linear-gradient(rgba(18, 16, 16, 0) 50%, rgba(0, 0, 0, 0.25) 50%), linear-gradient(90deg, rgba(255, 0, 0, 0.06), rgba(0, 255, 0, 0.02), rgba(0, 0, 255, 0.06));
z-index: 100;
background-size: 100% 2px, 3px 100%;
pointer-events: none;
}
/* Header */
header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem 2rem;
border-bottom: 2px solid var(--neon-pink);
background: rgba(0, 0, 0, 0.8);
z-index: 10;
box-shadow: 0 0 20px rgba(255, 42, 109, 0.3);
}
.brand {
font-family: 'Orbitron', sans-serif;
font-size: 1.8rem;
font-weight: 900;
color: var(--neon-pink);
text-transform: uppercase;
letter-spacing: 3px;
text-shadow: 2px 2px 0px var(--neon-blue);
animation: glitch 3s infinite;
}
.anycoder-link {
font-family: 'Orbitron', sans-serif;
color: var(--neon-green);
text-decoration: none;
font-size: 0.9rem;
border: 1px solid var(--neon-green);
padding: 0.5rem 1rem;
transition: all 0.3s ease;
text-transform: uppercase;
}
.anycoder-link:hover {
background: var(--neon-green);
color: #000;
box-shadow: 0 0 15px var(--neon-green);
}
/* Main Layout */
main {
flex: 1;
display: grid;
grid-template-columns: 300px 1fr 300px;
gap: 1rem;
padding: 1rem;
max-width: 1600px;
margin: 0 auto;
width: 100%;
position: relative;
z-index: 5;
}
/* Panels */
.panel {
background: var(--bg-panel);
border: 1px solid var(--neon-blue);
padding: 1rem;
position: relative;
box-shadow: inset 0 0 20px rgba(5, 217, 232, 0.1);
display: flex;
flex-direction: column;
}
.panel::before {
content: '';
position: absolute;
top: -2px;
left: -2px;
right: -2px;
bottom: -2px;
background: linear-gradient(45deg, var(--neon-pink), transparent, var(--neon-blue));
z-index: -1;
opacity: 0.3;
}
.panel-header {
font-family: 'Orbitron', sans-serif;
color: var(--neon-blue);
border-bottom: 1px solid var(--neon-blue);
padding-bottom: 0.5rem;
margin-bottom: 1rem;
text-transform: uppercase;
font-size: 1.2rem;
display: flex;
justify-content: space-between;
align-items: center;
}
/* Left Panel: Stats */
.stat-row {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 1rem;
font-size: 1.1rem;
}
.stat-label {
color: var(--neon-green);
}
.stat-value {
color: #fff;
font-weight: bold;
}
.health-bar-container {
width: 100%;
height: 10px;
background: #333;
margin-top: 5px;
border: 1px solid #555;
}
.health-bar-fill {
height: 100%;
background: var(--neon-pink);
width: 100%;
transition: width 0.3s ease;
box-shadow: 0 0 10px var(--neon-pink);
}
.inventory-list {
list-style: none;
margin-top: 1rem;
flex: 1;
overflow-y: auto;
}
.inventory-item {
padding: 0.5rem;
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
display: flex;
align-items: center;
gap: 10px;
}
.inventory-item i {
color: var(--neon-yellow);
}
/* Center Panel: Game Log / Scene */
.scene-display {
flex: 1;
overflow-y: auto;
margin-bottom: 1rem;
padding-right: 10px;
font-size: 1.1rem;
line-height: 1.6;
}
.log-entry {
margin-bottom: 1.5rem;
animation: fadeIn 0.5s ease;
}
.log-entry.system {
color: var(--neon-green);
font-style: italic;
border-left: 3px solid var(--neon-green);
padding-left: 10px;
}
.log-entry.danger {
color: var(--neon-pink);
border-left: 3px solid var(--neon-pink);
padding-left: 10px;
}
.log-entry.narrative {
color: var(--text-main);
}
.typing-cursor::after {
content: '█';
animation: blink 1s infinite;
color: var(--neon-blue);
margin-left: 5px;
}
/* Action Area */
.actions-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 1rem;
margin-top: auto;
}
.action-btn {
background: transparent;
border: 1px solid var(--neon-blue);
color: var(--neon-blue);
padding: 1rem;
font-family: 'Orbitron', sans-serif;
font-size: 1rem;
cursor: pointer;
transition: all 0.2s;
text-transform: uppercase;
position: relative;
overflow: hidden;
}
.action-btn:hover {
background: var(--neon-blue);
color: #000;
box-shadow: 0 0 20px var(--neon-blue);
}
.action-btn:disabled {
border-color: #555;
color: #555;
cursor: not-allowed;
box-shadow: none;
}
/* Right Panel: Visuals/Data */
.visual-feed {
height: 200px;
border: 1px solid var(--neon-pink);
margin-bottom: 1rem;
background: #000;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
position: relative;
}
.visual-icon {
font-size: 5rem;
color: var(--neon-pink);
animation: pulse 2s infinite;
z-index: 2;
}
.grid-bg {
position: absolute;
width: 200%;
height: 200%;
background-image:
linear-gradient(var(--glass) 1px, transparent 1px),
linear-gradient(90deg, var(--glass) 1px, transparent 1px);
background-size: 20px 20px;
transform: perspective(500px) rotateX(60deg) translateY(-100px) translateZ(-200px);
animation: gridMove 20s linear infinite;
}
.status-log {
font-size: 0.8rem;
color: #888;
font-family: monospace;
}
.status-line {
margin-bottom: 4px;
}
/* Animations */
@keyframes glitch {
0% {
text-shadow: 2px 2px 0px var(--neon-blue);
transform: translate(0);
}
20% {
text-shadow: -2px -2px 0px var(--neon-pink);
transform: translate(-2px, 2px);
}
40% {
text-shadow: 2px -2px 0px var(--neon-green);
transform: translate(2px, -2px);
}
60% {
text-shadow: -2px 2px 0px var(--neon-blue);
transform: translate(-2px, 2px);
}
80% {
text-shadow: 2px 2px 0px var(--neon-pink);
transform: translate(2px, -2px);
}
100% {
text-shadow: 2px 2px 0px var(--neon-blue);
transform: translate(0);
}
}
@keyframes blink {
0%,
100% {
opacity: 1;
}
50% {
opacity: 0;
}
}
@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes pulse {
0% {
transform: scale(1);
text-shadow: 0 0 10px var(--neon-pink);
}
50% {
transform: scale(1.1);
text-shadow: 0 0 30px var(--neon-pink);
}
100% {
transform: scale(1);
text-shadow: 0 0 10px var(--neon-pink);
}
}
@keyframes gridMove {
0% {
transform: perspective(500px) rotateX(60deg) translateY(0) translateZ(-200px);
}
100% {
transform: perspective(500px) rotateX(60deg) translateY(100px) translateZ(-200px);
}
}
/* Responsive */
@media (max-width: 1024px) {
main {
grid-template-columns: 1fr;
grid-template-rows: auto 1fr auto;
height: auto;
overflow-y: auto;
}
body {
overflow: auto;
height: auto;
}
.visual-feed {
display: none;
}
/* Hide visual on mobile to save space */
.panel {
min-height: 300px;
}
.panel:first-child {
order: 2;
}
.panel:nth-child(2) {
order: 1;
min-height: 50vh;
}
.panel:last-child {
order: 3;
}
}
</style>
</head>
<body>
<header>
<div class="brand"><i class="fa-solid fa-city"></i> Sin City 3000</div>
<a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" class="anycoder-link">Built with
anycoder</a>
</header>
<main>
<!-- Left Panel: Character Stats -->
<aside class="panel">
<div class="panel-header">
<span><i class="fa-solid fa-user-astronaut"></i> Status</span>
<span id="player-class">Mercenary</span>
</div>
<div class="stat-row">
<span class="stat-label">HP</span>
<div style="flex:1; margin-left: 10px; text-align: right;">
<span id="hp-val" class="stat-value">100/100</span>
<div class="health-bar-container">
<div id="hp-bar" class="health-bar-fill"></div>
</div>
</div>
</div>
<div class="stat-row">
<span class="stat-label">Credits</span>
<span class="stat-value" style="color: var(--neon-yellow);">¥ <span id="credits-val">50</span></span>
</div>
<div class="stat-row">
<span class="stat-label">Street Cred</span>
<span class="stat-value" style="color: var(--neon-pink);"><span id="rep-val">0</span></span>
</div>
<div class="panel-header" style="margin-top: 1rem;">
<span><i class="fa-solid fa-microchip"></i> Inventory</span>
</div>
<ul class="inventory-list" id="inventory-list">
<!-- Items injected here -->
</ul>
</aside>
<!-- Center Panel: Narrative -->
<section class="panel">
<div class="panel-header">
<span><i class="fa-solid fa-terminal"></i> Neural Link</span>
<span style="font-size: 0.8rem; opacity: 0.7;">V.3.0.1 connected</span>
</div>
<div class="scene-display" id="game-log">
<!-- Game text goes here -->
</div>
<div class="actions-grid" id="actions-container">
<!-- Buttons injected here -->
</div>
</section>
<!-- Right Panel: World Data -->
<aside class="panel">
<div class="panel-header">
<span><i class="fa-solid fa-satellite-dish"></i> Environment</span>
</div>
<div class="visual-feed">
<div class="grid-bg"></div>
<i id="scene-icon" class="fa-solid fa-biohazard visual-icon"></i>
</div>
<div class="panel-header" style="font-size: 1rem;">System Log</div>
<div class="status-log" id="system-log">
<div class="status-line">> Initializing biosystems... OK</div>
<div class="status-line">> Connecting to CityNet... OK</div>
<div class="status-line">> Location detected: Sector 7 Slums</div>
<div class="status-line">> Weather: Acid Rain</div>
</div>
</aside>
</main>
<script>
// --- Game State ---
const gameState = {
hp: 100,
maxHp: 100,
credits: 100,
rep: 10,
inventory: ['Data Deck', 'Stimpak'],
flags: {}, // For story tracking
currentScene: 'start'
};
// --- Story Data ---
const scenes = {
'start': {
text: "You wake up face down in a puddle of neon-reflecting sludge. Your head is throbbing—a side effect of the cheap neural implant you installed last night. The alleyway smells of ozone and rotting synth-meat. Sirens wail in the distance, growing louder. You need to move.",
icon: "fa-skull",
choices: [
{ text: "Check pockets & run", action: 'flee_alley' },
{ text: "Hide in the dumpster", action: 'hide_dumpster' },
{ text: "Scan for network signals", action: 'scan_network', req: { item: 'Data Deck' } }
]
},
'flee_alley': {
text: "You scramble to your feet and sprint towards the main street. A flying patrol drone sweeps a red laser across the spot you just left. Close call. You emerge into the neon chaos of Sector 7 Market. Hawkers are selling everything from illegal memory chips to synthetic organs.",
icon: "fa-person-running",
choices: [
{ text: "Visit the Ripperdoc", action: 'ripperdoc' },
{ text: "Enter the 'Binary Bar'", action: 'bar' },
{ text: "Look for a job board", action: 'job_board' }
]
},
'hide_dumpster': {
text: "You dive into the trash. It's gross, but effective. Two NCPD officers run past, weapons drawn. Once they're gone, you climb out. You find a discarded energy cell in the trash.",
icon: "fa-trash-can",
effect: () => { addItem('Energy Cell'); },
choices: [
{ text: "Go to the Market", action: 'flee_alley' }
]
},
'scan_network': {
text: "You jack into a loose cable hanging from the wall. Your vision floods with green code. You intercept a police dispatch: 'Suspect heading to Sector 7'. You also manage to siphon a few credits from an unsecured vending machine nearby.",
icon: "fa-wifi",
effect: () => { addCredits(50); addRep(5); },
choices: [
{ text: "Disconnect & Run", action: 'flee_alley' }
]
},
'ripperdoc': {
text: "Dr. Chrome's clinic is a blood-stained basement. He looks at you with cybernetic eyes that zoom in and out. 'You look like slag, kid. Need a tune-up? Or maybe something... lethal?'",
icon: "fa-user-doctor",
choices: [
{ text: "Heal (50 Credits)", action: 'heal', cost: 50 },
{ text: "Buy Combat Chip (200 Credits)", action: 'buy_chip', cost: 200 },
{ text: "Leave", action: 'hub_return' }
]
},
'bar': {
text: "The Binary Bar is loud. Bass thumps in your chest. A holographic dancer flickers on the stage. A shady fixer in the corner signals you over.",
icon: "fa-martini-glass-citrus",
choices: [
{ text: "Talk to the Fixer", action: 'talk_fixer' },
{ text: "Buy a drink (10 Credits)", action: 'buy_drink', cost: 10 },
{ text: "Leave", action: 'hub_return' }
]
},
'talk_fixer': {
text: "'Name's Vex. I got a job. A corpo courier is passing through the lower levels. Intercept him, get the package. Pays 500. Interested?'",
icon: "fa-user-secret",
choices: [
{ text: "Accept Job", action: 'mission_courier' },
{ text: "Refuse", action: 'hub_return' }
]
},
'mission_courier': {
text: "You ambush the courier in a transit tunnel. He draws a pistol. Combat initiated!",
icon: "fa-gun",
type: 'combat',
enemy: { name: 'Corpo Courier', hp: 30, damage: 10 },
choices: [
{ text: "Attack with Fists", action: 'combat_attack' },
{ text: "Use Stimpak", action: 'combat_heal', req: { item: 'Stimpak' } },
{ text: "Hack his gun", action: 'combat_hack', req: { item: 'Data Deck' } }
]
},
'job_board': {
text: "The digital board flickers. Most jobs are trash collection or organ harvesting. One stands out: 'Beta Tester needed for experimental reflex booster. High risk.'",
icon: "fa-clipboard-list",
choices: [
{ text: "Take the risk", action: 'experiment' },
{ text: "Back to Market", action: 'hub_return' }
]
},
'experiment': {
text: "You plug into the test terminal. A surge of electricity fries your nerves but rewires your reflexes. You take 20 damage but gain Street Cred.",
icon: "fa-bolt",
effect: () => { takeDamage(20); addRep(20); },
choices: [
{ text: "Stumble away", action: 'hub_return' }
]
},
'hub_return': {
text: "You are back in the center of Sector 7 Market. The neon lights buzz overhead.",
icon: "fa-store",
choices: [
{ text: "Visit Ripperdoc", action: 'ripperdoc' },
{ text: "Visit Bar", action: 'bar' },
{ text: "Job Board", action: 'job_board' }
]
},
'game_over': {
text: "CRITICAL SYSTEM FAILURE. Your vitals have ceased. Your story ends here in the gutter of Sin City 3000.",
icon: "fa-skull-crossbones",
choices: [
{ text: "Reboot System", action: 'restart' }
]
},
'combat_win': {
text: "The courier drops. You grab the package. It's heavy. Inside is a prototype chip. You wire Vex, and the credits transfer instantly.",
icon: "fa-trophy",
effect: () => { addCredits(500); addRep(50); addItem('Proto-Chip'); },
choices: [
{ text: "Return to Market", action: 'hub_return' }
]
}
};
// --- Engine Functions ---
function initGame() {
updateHUD();
renderScene('start');
logSystem("System initialized. User: Guest.");
}
function updateHUD() {
// Stats
document.getElementById('hp-val').innerText = `${gameState.hp}/${gameState.maxHp}`;
document.getElementById('hp-bar').style.width = `${(gameState.hp / gameState.maxHp) * 100}%`;
document.getElementById('credits-val').innerText = gameState.credits;
document.getElementById('rep-val').innerText = gameState.rep;
// Inventory
const invList = document.getElementById('inventory-list');
invList.innerHTML = '';
if(gameState.inventory.length === 0) {
invList.innerHTML = '<li class="inventory-item" style="opacity:0.5">Empty</li>';
} else {
gameState.inventory.forEach(item => {
const li = document.createElement('li');
li.className = 'inventory-item';
let icon = 'fa-box';
if(item === 'Data Deck') icon = 'fa-laptop-code';
if(item === 'Stimpak') icon = 'fa-syringe';
if(item === 'Energy Cell') icon = 'fa-battery-full';
li.innerHTML = `<i class="fa-solid ${icon}"></i> ${item}`;
invList.appendChild(li);
});
}
}
function logSystem(msg) {
const log = document.getElementById('system-log');
const div = document.createElement('div');
div.className = 'status-line';
div.innerText = `> ${msg}`;
log.prepend(div);
if(log.children.length > 6) log.lastChild.remove();
}
function addItem(item) {
if(!gameState.inventory.includes(item)) {
gameState.inventory.push(item);
logText(`System: Acquired [${item}]`, 'system');
updateHUD();
}
}
function removeItem(item) {
const index = gameState.inventory.indexOf(item);
if (index > -1) {
gameState.inventory.splice(index, 1);
updateHUD();
}
}
function addCredits(amount) {
gameState.credits += amount;
logText(`System: Transfer received ¥${amount}`, 'system');
updateHUD();
}
function addRep(amount) {
gameState.rep += amount;
logText(`System: Street Cred increased +${amount}`, 'system');
updateHUD();
}
function takeDamage(amount) {
gameState.hp -= amount;
if(gameState.hp <= 0) {
gameState.hp = 0;
renderScene('game_over');
}
updateHUD();
// Flash red
document.body.style.boxShadow = "inset 0 0 50px red";
setTimeout(() => document.body.style.boxShadow = "none", 200);
}
function heal(amount) {
gameState.hp = Math.min(gameState.maxHp, gameState.hp + amount);
updateHUD();
}
// --- Rendering ---
function logText(text, type = 'narrative') {
const display = document.getElementById('game-log');
const div = document.createElement('div');
div.className = `log-entry ${type}`;
if(type === 'narrative') {
div.classList.add('typing-cursor');
// Typewriter effect
let i = 0;
const speed = 20;
function typeWriter() {
if (i < text.length) {
div.textContent += text.charAt(i);
i++;
display.scrollTop = display.scrollHeight; // Auto scroll
setTimeout(typeWriter, speed);
} else {
div.classList.remove('typing-cursor');
}
}
display.appendChild(div);
typeWriter();
} else {
div.textContent = text;
display.appendChild(div);
display.scrollTop = display.scrollHeight;
}
}
function renderScene(sceneKey) {
const scene = scenes[sceneKey];
gameState.currentScene = sceneKey;
// Update visual
const iconElement = document.getElementById('scene-icon');
iconElement.className = `fa-solid ${scene.icon || 'fa-circle-question'} visual-icon`;
// Execute effects if any
if(scene.effect) {
scene.effect();
// If effect killed player, stop here
if(gameState.hp <= 0) return;
}
// Log text
logText(scene.text);
// Render Buttons
const actionsContainer = document.getElementById('actions-container');
actionsContainer.innerHTML = '';
if (scene.type === 'combat') {
handleCombat(scene);
return;
}
scene.choices.forEach(choice => {
const btn = document.createElement('button');
btn.className = 'action-btn';
let label = choice.text;
let disabled = false;
// Check requirements
if(choice.req) {
if(choice.req.item && !gameState.inventory.includes(choice.req.item)) {
disabled = true;
label += ` [Req: ${choice.req.item}]`;
}
}
// Check costs
if(choice.cost) {
if(gameState.credits < choice.cost) {
disabled = true;
}
}
btn.innerText = label;
btn.disabled = disabled;
btn.onclick = () => {
if(choice.cost) addCredits(-choice.cost);
if(choice.action === 'restart') {
location.reload();
} else {
renderScene(choice.action);
}
};
actionsContainer.appendChild(btn);
});
}
// Simple Combat Logic
let currentEnemy = null;
function handleCombat(scene) {
currentEnemy = { ...scene.enemy }; // Clone enemy
const actionsContainer = document.getElementById('actions-container');
// Create attack buttons dynamically based on loop
renderCombatButtons(scene);
}
function renderCombatButtons(scene) {
const actionsContainer = document.getElementById('actions-container');
actionsContainer.innerHTML = '';
scene.choices.forEach(choice => {
const btn = document.createElement('button');
btn.className = 'action-btn';
let label = choice.text;
let disabled = false;
if(choice.req && choice.req.item && !gameState.inventory.includes(choice.req.item)) {
disabled = true;
label += ` [Missing: ${choice.req.item}]`;
}
btn.innerText = label;
btn.disabled = disabled;
btn.onclick = () => {
combatRound(choice.action, scene);
};
actionsContainer.appendChild(btn);
});
}
function combatRound(action, scene) {
// Player Turn
let playerDmg = 0;
let logMsg = "";
if(action === 'combat_attack') {
playerDmg = Math.floor(Math.random() * 10) + 5;
logMsg = `You punch the enemy for ${playerDmg} damage!`;
} else if (action === 'combat_heal') {
heal(30);
removeItem('Stimpak');
logMsg = "You injected a Stimpak. +30 HP.";
} else if (action === 'combat_hack') {
playerDmg = 20;
logMsg = "Hack successful! Weapon backfire caused 20 damage.";
}
if(playerDmg > 0) {
currentEnemy.hp -= playerDmg;
logText(logMsg, 'danger');
} else {
logText(logMsg, 'system');
}
// Check Enemy Death
if(currentEnemy.hp <= 0) {
logText("Enemy defeated!", 'system');
setTimeout(() => renderScene('combat_win'), 1000);
return;
}
// Enemy Turn
setTimeout(() => {
const enemyDmg = Math.floor(Math.random() * currentEnemy.damage);
takeDamage(enemyDmg);
logText(`${currentEnemy.name} hits you for ${enemyDmg} damage!`, 'danger');
if(gameState.hp > 0) {
renderCombatButtons(scene); // Refresh buttons
}
}, 800);
}
// Boot
window.onload = initGame;
</script>
</body>
</html>