<!-- SOLID-PLAYTIME · part 179 -->
h.random()-0.5)*900);
  cl.userData.vx=1.2+Math.random()*2.4;
  Kt.scene.add(cl); clouds.push(cl);
}

/* ============ floating embers ============ */
var embN=140, embGeo=new T.BufferGeometry(), embPos=new Float32Array(embN*3), embVel=[];
for(var ei=0;ei<embN;ei++){
  embPos[ei*3]=(Math.random()-0.5)*70;
  embPos[ei*3+1]=Math.random()*22;
  embPos[ei*3+2]=(Math.random()-0.5)*70;
  embVel.push(0.6+Math.random()*1.6);
}
embGeo.setAttribute('position',new T.BufferAttribute(embPos,3));
var embers=new T.Points(embGeo,new T.PointsMaterial({color:0xffb340,size:3.4,transparent:true,opacity:0.85,depthWrite:false}));
embers.frustumCulled=false;
Kt.scene.add(embers);

/* ============ lightning ============ */
var boltMat=new T.LineBasicMaterial({color:0xcfe8ff,transparent:true,opacity:0});
var boltGeo=new T.BufferGeometry().setFromPoints([new T.Vector3(),new T.Vector3(0,1,0)]);
var bolt=new T.Line(boltGeo,boltMat);
bolt.frustumCulled=false; bolt.visible=false;
Kt.scene.add(bolt);
var flashLight=new T.PointLight(0xbfd4ff,0,600,1);
Kt.scene.add(flashLight);
var nextBolt=9+Math.random()*9, boltT=0;
function strike(cx,cz,nightF){
  var bx=cx+(Math.random()-0.5)*280, bz=cz+(Math.random()-0.5)*280, py=430, px=bx, pz=bz;
  var pts=[new T.Vector3(px,py,pz)];
  for(var s=0;s<9;s++){ py-=48; px+=(Math.random()-0.5)*38; pz+=(Math.random()-0.5)*38; pts.push(new T.Vector3(px,py,pz)); }
  boltGeo.setFromPoints(pts);
  bolt.visible=true; boltT=0.3;
  flashLight.position.set(bx,220,bz);
  flashLight.intensity=2+6*nightF;
}

/* ============ shockwave rings ============ */
var rings=[];
function shockwave(x,y,z,color,maxR){
  var m=new T.Mesh(new T.RingGeometry(0.55,0.95,48),
    new T.MeshBasicMaterial({color:color,transparent:true,opacity:0.9,side:T.DoubleSide,depthWrite:false}));
  m.position.set(x,Math.max(0.35,y),z);
  m.rotation.x=-Math.PI/2;
  Kt.scene.add(m);
  rings.push({m:m,t:0,maxR:maxR||16,dur:0.7});
}
window.shockwave=function(x,y,z,c){ shockwave(x,y,z,c||0xffd700,16); };

/* ============ firing (muzzle flash + tracers + sparks) ============ */
var lastFire=0;
function fireWeapon(){
  var now=performance.now();
  if(now-lastFire<240) return;
  lastFire=now;
  var hp=Kt.hero.position, facing=Kt.facing||0;
  var dx=Math.sin(facing), dz=Math.cos(facing);
  var ox=hp.x+dx*1.6, oy=hp.y+1.25, oz=hp.z+dz*1.6;
  var isSG=cur==='shotgun', isL=cur==='laser';
  var pellets=isSG?5:1, range=isL?70:(isSG?26:48);
  var col=isL?0x00ffff:(isSG?0xff6600:0xffe14d);
  var fl=new T.Mesh(new T.SphereGeometry(0.42,10,10),
    new T.MeshBasicMaterial({color:0xfff6c8,transparent:true,opacity:0.95,depthWrite:false}));
  fl.position.set(ox+dx*1.4,oy,oz+dz*1.4);
  Kt.scene.add(fl);
  setTimeout(function(){ Kt.scene.remove(fl); fl.geometry.dispose(); fl.material.dispose(); },90);
  weaponLight.intensity=4.2;
  setTimeout(function(){ weaponLight.intensity=1.6; },110);
  for(var p=0;p<pellets;p++){
    var px=dx, py=0, pz=dz;
    if(isSG){ px+=(Math.random()-0.5)*0.22; py+=(Math.random()-0.5)*0.12; pz+=(Math.random()-0.5)*0.22;
      var il=1/Math.max(0.001,Math.sqrt(px*px+py*py+pz*pz)); px*=il; py*=il; pz*=il; }
    var hx=ox+px*range, hy=oy+py*range, hz=oz+pz*range;
    var tg=new T.BufferGeometry().setFromPoints([new T.Vector3(ox,oy,oz),new T.Vector3(hx,hy,hz)]);
    var tm=new T.LineBasicMaterial({color:col,transparent:true,opacity:0.95});
    var tr=new T.Line(tg,tm);
    Kt.scene.add(tr);
    (function(TR,TM,TG,life){ setTimeout(function(){ try{Kt.scene.remove(TR);}catch(e){} TG.dispose(); TM.dispose(); },life); })(tr,tm,tg,isL?220:130);
    if(!isSG||p===2){ try{ Kt.burst(hx,hy,hz,col); }catch(e){} }
    if(isL) shockwave(hx,Math.max(0.4,hy-3),hz,col,10);
  }
  if(isSG) shockwave(ox,oy-0.9,oz,0xff6600,7);
}
window.fireWeapon=fireWeapon;
document.addEventListener('click',function(e){
  var b=e.target&&e.target.closest?e.target.closest('button.attack'):null;
  if(b) fireWeapon();
},true);

/* ============ day cycle + animation loop ============ */
var cNoonT=new T.Color(0x7a5200), cNoonM=new T.Color(0xffd700), cNoonB=new T.Color(0x2e1e04);
var cDuskT=new T.Color(0x2a1040), cDuskM=new T.Color(0xff5a1e), cDuskB=new T.Color(0x1a0a08);
var cNightT=new T.Color(0x03040c), cNightM=new T.Color(0x0b1238), cNightB=new T.Color(0x000000);
var fogNoon=new T.Color(0xc9982a), fogDusk=new T.Color(0x8a3416), fogNight=new T.Color(0x0a0a1c);
var cloudDay=new T.Color(0xffffff), cloudNight=new T.Color(0x2a3560);
var _a=new T.Color(), _b=new T.Color();
var dayLen=240000, t0=performance.now(), lastT=t0;

function mix3(day,dusk,night,duskF,nightF,out){
  _a.copy(day).lerp(dusk,duskF);
  out.copy(_a).lerp(night,nightF);
  return out;
}

function tick(){
  requestAnimationFrame(tick);
  var now=performance.now();
  var dt=Math.min(0.05,(now-lastT)/1000); lastT=now;
  var hx=Kt.hero.position.x, hz=Kt.hero.position.z;

  /* day phase */
  var dayT=((now-t0)%dayLen)/dayLen;
  var ang=dayT*Math.PI*2;
  var elev=Math.sin(ang);
  var nightF=M