Files
deepseek 4c7fe1db4c Counter-Strike esports manager: career mode + LIVE tactical top-down simulation
- Full manager sim: 28 orgs / 168 players, calendar, transfers, youth scouting, loans, training, board confidence
- Simulation Mode with real-time micro-engine (live.js): A* pathfinding on map geometry, raycast ballistics (spread/falloff/armor/headshots), smokes/flashes/HE that matter, plant/defuse/retake AI, clutch detection
- Canvas renderer (viz.js): follow/radar cameras, HP bars, CS2-style kill feed, callouts, synthesized Web-Audio SFX, speed x1-x3, AUTO-SPECTATE hands-free series playback
- Round results flow from the firefight back into the career engine (score, economy, box score, MVP)
- Playwright + Node VM test suites included (test/, plus external pwtest harness)
2026-08-23 07:00:47 +00:00

78 lines
2.6 KiB
JavaScript

'use strict';
/* ================= bootstrap ================= */
const Main={
boot(){
const info=this.saveInfo();
if(info){
$('btnContinue').style.display='';
$('btnContinue').innerHTML=`▶ Continue — ${U.esc(info.tag)} · S${info.season} · ${info.date}`;
}
},
saveInfo(){
const ls=Save.store();if(!ls)return null;
try{
const g=JSON.parse(ls.getItem(SAVE_KEY));
if(!g||g.ver!==1)return null;
const t=g.teams[g.playerTeamId];
return {tag:t?t.tag:'?',season:g.season,date:U.fmtDate(g.day)};
}catch(e){return null;}
},
continueGame(){
if(Save.load()){
UI.show();
UI.toast('Career loaded — welcome back, GM.','good');
}else{
alert('Save data was corrupted. Start a new career.');
Save.wipe();
}
},
toTitle(){
Save.save(true);
$('gameShell').style.display='none';
$('simOverlay').style.display='none';
$('titleScreen').style.display='flex';
$('btnContinue').style.display=Save.exists()?'':'none';
SimSession.s=null;
},
exportSave(){
if(!G){alert('No career running.');return;}
const blob=new Blob([Game.serialize()],{type:'application/json'});
const a=document.createElement('a');
a.href=URL.createObjectURL(blob);
a.download=`csm26_${(G.teams[G.playerTeamId]?.tag||'save')}_S${G.season}_d${G.day}.json`;
a.click();URL.revokeObjectURL(a.href);
UI.toast('Save exported.','good');
},
importSave(){
const inp=document.createElement('input');
inp.type='file';inp.accept='.json,application/json';
inp.onchange=()=>{
const f=inp.files[0];if(!f)return;
const rd=new FileReader();
rd.onload=()=>{
try{
Game.staticLoad(String(rd.result));
Save.save(true);
UI.closeModal();
UI.show();
UI.toast('Save imported ✔','good');
}catch(e){alert('Invalid save file.');}
};
rd.readAsText(f);
};
inp.click();
},
};
window.addEventListener('DOMContentLoaded',()=>Main.boot());
window.addEventListener('visibilitychange',()=>{if(document.visibilityState==='hidden'&&G)Save.save(true);});
/* keyboard: Space/Enter = advance week · Esc = close modal */
window.addEventListener('keydown',e=>{
if(e.key==='Escape'){const m=$('modalBg');if(m){m.remove();return;}}
if(!G)return;
if(e.key!==' '&&e.key!=='Enter')return;
if($('modalBg')||$('simOverlay').style.display==='flex'||$('titleScreen').style.display==='flex')return;
if(['INPUT','SELECT','TEXTAREA','BUTTON'].includes(document.activeElement?.tagName))return;
e.preventDefault();
UI.advance();
});