File size: 5,448 Bytes
b51e03a
3597f5a
181ede2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3597f5a
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
;
;
/* ============================================================================
   MOBILE HUD STACK POLICY
   ----------------------------------------------------------------------------
   Combat alerts, economy coaching, intel, production and the command dock were
   all individually correct but had no shared owner. On a phone they could fill
   the entire screen at once. This late takeover gives those existing systems a
   priority order without coupling their simulation code:

     critical alert > direct tap feedback > one primary panel > coach banner

   The permanent Army / Select / Stop / Build row stays reachable. Everything
   else collapses while a primary panel is open and returns when it closes.
   ============================================================================ */
let mfUiCoachPending='',mfUiCoachFlushT=0,mfUiSyncFrame=0;

function mfUiInlineOpen(id){
  const el=document.getElementById(id);
  return !!(el&&el.style.display==='block');
}
function mfUiPanelOpen(){
  return mfUiInlineOpen('buildMenu')||mfUiInlineOpen('prodMenu')||mfUiInlineOpen('bldMenu2');
}
function mfUiIntelOpen(){ return mfUiInlineOpen('unitCard'); }
function mfUiCriticalOpen(){ return mfUiInlineOpen('atkAlert')||mfUiInlineOpen('waveAlert'); }
function mfUiBusy(){ return mfUiPanelOpen()||mfUiIntelOpen()||mfUiCriticalOpen(); }

function mfUiClosePrimary(){
  const intel=document.getElementById('unitCard');
  if(intel){ clearTimeout(intel._t); intel.style.display='none'; }
  if(typeof closeMenus==='function') closeMenus();
  mfUiQueueSync();
}
function mfUiEnsurePanelChrome(id,label){
  const el=document.getElementById(id); if(!el) return;
  let bar=el.querySelector(':scope > .mfPanelChrome');
  if(!bar){
    bar=document.createElement('header');bar.className='mfPanelChrome';
    bar.innerHTML='<span></span><button type="button" aria-label="Close '+label+'">\u00d7</button>';
    bar.querySelector('button').addEventListener('pointerdown',ev=>{
      ev.preventDefault();ev.stopPropagation();mfUiClosePrimary();if(typeof sfx==='function')sfx('ui');
    });
    el.insertAdjacentElement('afterbegin',bar);
  }
  bar.querySelector('span').textContent=label;
}
function mfUiInstallChrome(){
  mfUiEnsurePanelChrome('buildMenu','STRUCTURES');
  mfUiEnsurePanelChrome('prodMenu','PRODUCTION');
  mfUiEnsurePanelChrome('bldMenu2','STRUCTURE CONTROL');
}

function mfUiFlushCoach(){
  clearTimeout(mfUiCoachFlushT);
  if(!mfUiCoachPending||mfUiBusy()) return;
  const msg=mfUiCoachPending;mfUiCoachPending='';
  mfUiCoachFlushT=setTimeout(()=>{
    if(mfUiBusy()){mfUiCoachPending=msg;return;}
    if(typeof mfUiBaseShowCoach==='function')mfUiBaseShowCoach(msg);
  },420);
}
function mfUiSync(){
  mfUiSyncFrame=0;mfUiInstallChrome();
  const body=document.body,panel=mfUiPanelOpen(),intel=mfUiIntelOpen();
  const wave=mfUiInlineOpen('waveAlert'),attack=mfUiInlineOpen('atkAlert');
  body.classList.toggle('uiPanelOpen',panel);
  body.classList.toggle('uiIntelOpen',intel);
  body.classList.toggle('uiPrimaryOpen',panel||intel);
  body.classList.toggle('uiWaveOpen',wave);
  body.classList.toggle('uiAttackOpen',attack);
  for(const id of ['buildMenu','prodMenu','bldMenu2']){
    const el=document.getElementById(id);if(el)el.setAttribute('aria-hidden',intel?'true':'false');
  }
  const coach=document.getElementById('coach');
  if((panel||intel||wave||attack)&&coach&&Number(getComputedStyle(coach).opacity)>.05){
    mfUiCoachPending=coach.textContent||mfUiCoachPending;
    clearTimeout(coachHideT);coach.style.opacity=0;
  }
  if(!(panel||intel||wave||attack))mfUiFlushCoach();
}
function mfUiQueueSync(){
  if(!mfUiSyncFrame)mfUiSyncFrame=requestAnimationFrame(mfUiSync);
}

/* Coach messages explain slow economy problems; they are never more urgent
   than the panel the player deliberately opened or an incoming enemy wave. */
const mfUiBaseShowCoach=showCoach;
showCoach=function(msg){
  if(mfUiBusy()){
    mfUiCoachPending=msg;
    const el=document.getElementById('coach');if(el)el.style.opacity=0;
    return;
  }
  mfUiCoachPending='';mfUiBaseShowCoach(msg);
};

/* Automatic first-seen cards must not become a second primary panel. Explicit
   info-button inspections remain available and temporarily replace the menu. */
const mfUiBaseShowIntelMarkup=showIntelMarkup;
showIntelMarkup=function(markup,pinned){
  if(!pinned&&mfUiPanelOpen()) return;
  mfUiBaseShowIntelMarkup(markup,pinned);mfUiQueueSync();
};

const mfUiBaseCloseMenus=closeMenus;
closeMenus=function(){mfUiBaseCloseMenus();mfUiQueueSync();};
const mfUiBaseOpenBldMenu=openBldMenu;
openBldMenu=function(b){mfUiBaseOpenBldMenu(b);mfUiQueueSync();};
const mfUiBaseRenderBuildMenu=renderBuildMenu;
renderBuildMenu=function(){mfUiBaseRenderBuildMenu();mfUiEnsurePanelChrome('buildMenu','STRUCTURES');mfUiQueueSync();};
const mfUiBaseRenderProdMenu=renderProdMenu;
renderProdMenu=function(){mfUiBaseRenderProdMenu();mfUiEnsurePanelChrome('prodMenu','PRODUCTION');mfUiQueueSync();};
const mfUiBaseRenderBldPanel=renderBldPanel;
renderBldPanel=function(){mfUiBaseRenderBldPanel();mfUiEnsurePanelChrome('bldMenu2','STRUCTURE CONTROL');mfUiQueueSync();};

const mfUiWatch=new MutationObserver(mfUiQueueSync);
for(const id of ['buildMenu','prodMenu','bldMenu2','unitCard','atkAlert','waveAlert']){
  const el=document.getElementById(id);if(el)mfUiWatch.observe(el,{attributes:true,attributeFilter:['style','class']});
}
mfUiInstallChrome();mfUiSync();