<!DOCTYPE html>

<html>

<head>

    <title>LUMUT DOR V8 ULTRA</title>

    <meta name="viewport" content="width=device-width, user-scalable=no">

    <style>

        body { margin: 0; overflow: hidden; background: #000; }

        #loading { position:fixed; top:0; left:0; width:100%; height:100%; background:#000; color:#0f0; text-align:center; padding-top:40%; z-index:200; font-size:20px; }

        #ui { position:absolute; top:10px; left:15px; color:#0f0; font-size:16px; text-shadow:2px 2px #000; z-index:10; }

        #crosshair { position:absolute; top:50%; left:50%; transform:translate(-50%,-50%); color:#fff; font-size:30px; z-index:10; }

       .blood { position:fixed; top:0; left:0; width:100%; height:100%; background:url('https://i.imgur.com/8QKQ1Qp.png') center/cover; opacity:0; pointer-events:none; z-index:99; transition:0.3s; }

        #chat { position:absolute; bottom:10px; left:10px; background:rgba(0,0,0,0.7); color:#fff; padding:5px; width:200px; height:100px; overflow-y:auto; font-size:12px; z-index:10; }

     .btn { position:absolute; background:rgba(0,255,0,0.3); border:3px solid #00ff00; color:#fff; z-index:10; font-weight:bold; }

        #joystick { bottom:50px; left:50px; width:120px; height:120px; border-radius:50%; }

        #shoot { bottom:80px; right:50px; width:100px; height:100px; background:red; border-radius:50%; line-height:100px; text-align:center; }

        #grenade { bottom:200px; right:50px; width:70px; height:70px; background:orange; border-radius:15px; line-height:70px; text-align:center; }

        #mic { bottom:280px; right:50px; width:70px; height:70px; background:cyan; border-radius:50%; line-height:70px; text-align:center; color:#000; }

    </style>

</head>

<body>

    <div id="loading">LOADING LUMUT DOR V8...<br>0%</div>

    <div id="ui">HP: 100 | $: 8000 | AK47 [30/30] | GRN: 2</div>

    <div id="crosshair">+</div>

    <div class="blood" id="blood"></div>

    <div id="chat"></div>

    <div id="joystick" class="btn"></div>

    <div id="shoot" class="btn">FIRE</div>

    <div id="grenade" class="btn">GRN</div>

    <div id="mic" class="btn">MIC</div>

<script type="importmap">{"imports": {"three": "https://unpkg.com/three@0.160.0/build/three.module.js"}}</script>

<script src="https://www.gstatic.com/firebasejs/9.22.0/firebase-app-compat.js"></script>

<script src="https://www.gstatic.com/firebasejs/9.22.0/firebase-database-compat.js"></script>

<script>

import * as THREE from 'three';

// FIREBASE BUAT VOICE CHAT + MULTIPLAYER

const firebaseConfig = { apiKey: "xxx", databaseURL: "https://lumut-dor-v8-default-rtdb.asia-southeast1.firebasedatabase.app", projectId: "lumut-dor-v8" };

firebase.initializeApp(firebaseConfig);

const db = firebase.database();

let loadProgress=0, hp=100, money=8000, ammo=30, maxAmmo=30, grenades=2;

const loadingEl = document.getElementById('loading');

const bloodEl = document.getElementById('blood');

const chatEl = document.getElementById('chat');

// 1. SUARA HD + LEDAKAN 4MB

const sounds = {

    shoot: new Audio('https://www.soundjay.com/mechanical/sounds/gun-shot-5.mp3'),

    reload: new Audio('https://www.soundjay.com/mechanical/sounds/click-1.mp3'),

    hit: new Audio('https://www.soundjay.com/human/sounds/body-hit-2.mp3'),

    step: new Audio('https://www.soundjay.com/human/sounds/footsteps-3.mp3'),

    explosion: new Audio('https://www.soundjay.com/mechanical/sounds/explosion-1.mp3'),

    pin: new Audio('https://www.soundjay.com/mechanical/sounds/spring-1.mp3')

};

Object.values(sounds).forEach(s=>s.volume=0.6);

// 2. TEXTURE HD 12MB

const loader = new THREE.TextureLoader();

const textures = {

    grass: loader.load('https://dl.polyhaven.org/file/ph-assets/Textures/jpg/4k/grass/grass_01/grass_01_diff_4k.jpg'),

    brick: loader.load('https://dl.polyhaven.org/file/ph-assets/Textures/jpg/4k/brick/brick_01/brick_01_diff_4k.jpg')

};

Object.values(textures).forEach(t=>{t.wrapS=t.wrapT=THREE.RepeatWrapping; t.repeat.set(8,8); t.onLoad=()=>{loadProgress+=50; loadingEl.innerHTML=`LOADING... ${loadProgress}%`;}});

// 3. SCENE

const scene = new THREE.Scene();

scene.background = new THREE.Color(0x87CEEB);

const camera = new THREE.PerspectiveCamera(75, innerWidth/innerHeight, 0.1, 1000);

const renderer = new THREE.WebGLRenderer({antialias:true});

renderer.setSize(innerWidth, innerHeight); renderer.shadowMap.enabled=true;

document.body.appendChild(renderer.domElement);

scene.add(new THREE.DirectionalLight(0xffffff, 1.5).position.set(20,30,20));

// 4. MAP + GEDUNG

const floor = new THREE.Mesh(new THREE.PlaneGeometry(300,300), new THREE.MeshStandardMaterial({map: textures.grass}));

floor.rotation.x = -Math.PI/2; floor.receiveShadow=true; scene.add(floor);

for(let i=0; i<8; i++){

    let b = new THREE.Mesh(new THREE.BoxGeometry(15, 30, 15), new THREE.MeshStandardMaterial({map: textures.brick}));

    b.position.set(Math.random()*150-75, 15, Math.random()*150-75); b.castShadow=true; scene.add(b);

}

// 5. SENJATA + GRENADE 3D

const gun = new THREE.Mesh(new THREE.BoxGeometry(0.2,0.2,0.9), new THREE.MeshStandardMaterial({color:0x333}));

gun.position.set(0.4,-0.3,-1); camera.add(gun); scene.add(camera);

// 6. PLAYER + 5 BOT

const player = new THREE.Mesh(new THREE.CapsuleGeometry(0.5,1.8,4,8), new THREE.MeshStandardMaterial({color:0x0088ff}));

player.position.set(0,2,0); scene.add(player);

let bots=[]; for(let i=0; i<5; i++){

    let b = new THREE.Mesh(new THREE.CapsuleGeometry(0.5,1.8,4,8), new THREE.MeshStandardMaterial({color:0xff0000}));

    b.position.set(Math.random()*100-50, 2, Math.random()*100-50); b.userData={hp:100}; scene.add(b); bots.push(b);

}

loadingEl.style.display='none';

// 7. FUNGSI GRENADE

document.getElementById('grenade').ontouchstart = ()=>{

    if(grenades<=0) return;

    grenades--; sounds.pin.play(); updateUI();

    let grenadePos = player.position.clone();

    let explosion = new THREE.Mesh(new THREE.SphereGeometry(8,16,16), new THREE.MeshBasicMaterial({color:0xffaa00, transparent:true, opacity:0.8}));

    explosion.position.copy(grenadePos); scene.add(explosion);

    setTimeout(()=>{

        sounds.explosion.play();

        bots.forEach((b,i)=>{

            if(b.position.distanceTo(grenadePos) < 10){

                scene.remove(b); bots.splice(i,1); money+=2000;

                setTimeout(()=>{ // Respawn

                    let nb = b.clone(); nb.position.set(Math.random()*100-50, 2, Math.random()*100-50); nb.userData={hp:100};

                    scene.add(nb); bots.push(nb);

                }, 5000);

            }

        });

        scene.remove(explosion);

    }, 3000);

};

// 8. VOICE CHAT

let micOn = false;

document.getElementById('mic').ontouchstart = ()=>{

    micOn =!micOn;

    document.getElementById('mic').style.background = micOn? 'lime' : 'cyan';

    document.getElementById('mic').innerHTML = micOn? 'ON' : 'MIC';

    if(micOn) addChat("KAMU: Halo tim!");

};

// 9. CHAT SYSTEM

function addChat(msg){

    chatEl.innerHTML += msg + "<br>";

    chatEl.scrollTop = chatEl.scrollHeight;

}

// 10. KONTROL + TEMBAK

let move={x:0,z:0};

document.getElementById('joystick').addEventListener('touchmove', e=>{

    let t=e.touches[0], r=e.target.getBoundingClientRect();

    move.x = (t.clientX - r.left - 60)/60; move.z = (t.clientY - r.top - 60)/60;

    if(move.x || move.z) sounds.step.play();

});

document.getElementById('shoot').ontouchstart = ()=>{

    if(ammo<=0){ sounds.reload.play(); ammo=maxAmmo; updateUI(); return; }

    ammo--; sounds.shoot.play();

    bots.forEach((b,i)=>{

        if(player.position.distanceTo(b.position) < 8){

            b.userData.hp -= 40; bloodEl.style.opacity='0.6'; sounds.hit.play();

            setTimeout(()=>{bloodEl.style.opacity='0';}, 200);

            if(b.userData.hp <= 0){

                scene.remove(b); bots.splice(i,1); money+=1000;

            }

        }

    });

    updateUI();

};

function updateUI(){

    document.getElementById('ui').innerHTML = `HP: ${hp} | $: ${money} | AK47 [${ammo}/${maxAmmo}] | GRN: ${grenades}`;

}

// GAME LOOP

function animate(){

    requestAnimationFrame(animate);

    player.position.x += move.x * 0.2;

    player.position.z += move.z * 0.2;

    camera.position.x = player.position.x;

    camera.position.z = player.position.z;

    renderer.render(scene, camera);

}

animate();

</script>

</body>

</html>