// 국가 외교·전쟁 시뮬레이션 — GDevelop "JavaScript 코드 실행" 액션용 (단일 스크립트)
// 사용법: 이벤트 시트 → 조건 "씬 시작 시" → 액션 "Execute a JavaScript code" 에 이 파일 전체를 붙여넣기
(function(){
if(window.NS)return;
const rnd=Math.random,n=x=>Math.round(x),cl=(x,a,b)=>Math.max(a,Math.min(b,x));
const RN=['🌾밀','⛏️철','🐟수산','🛢️석유','🪵목재','🍎과일'],RP=[4,8,5,12,3,6],RC=['#e8c547','#c5ced8','#5ad0e0','#222','#7a4a24','#ff5d6c'];
const NM=['아르카','벨로','카엘','도른','에스타','펠라','그레이','히로'],CL=['#e5484d','#3e8bff','#d98e1c','#a96bff','#2fbf71','#e0649c','#27a3a3','#9aab2a'];
const TY=['공격적','평화적','무역중심','자원중심','군사중심','외교중심','고립주의'];
// [전쟁, 군비, 동맹, 선물, 무역협정, 판매]
const PR=[[.07,.4,.03,0,.02,.05],[0,.1,.05,.06,.04,.05],[.005,.2,.04,.04,.12,.15],[.01,.2,.03,.02,.06,.3],[.05,.6,.03,0,.02,.05],[.005,.2,.09,.12,.06,.08],[.01,.2,0,0,0,.02]];
const MK={trade:'교역',help:'요청 승인',refuse:'요청 거절',gift:'선물',firststrike:'선제공격',brk:'조약 위반',aid:'전후 지원',nuke:'핵 사용',pact:'무역협정'};
const GW=40,GH=26,NC=8,CS=11,SK='nationsim-v1';
let own,reg,RG,coast,C,rel,mem,wars,pend,logs,chat,hist,pacts,turn,aid,H,me,tab='e',spd=0,acc=0,mute=false,showChat=false,cen,fx=[],frame=0,sp=[];
const sel={r:0,q:25,d:150,g:-1};
const wf=(a,b)=>wars.find(w=>(w.a==a&&w.b==b)||(w.a==b&&w.b==a));
const L=(t,m)=>{logs.unshift(`[${t}] T${turn} ${m}`);if(logs.length>80)logs.pop()};
const CH=m=>{chat.unshift(`T${turn} ${m}`);if(chat.length>80)chat.pop()};
const rem=(a,b,k,v)=>{mem[a][b].push({T:turn,k,v});if(mem[a][b].length>14)mem[a][b].shift();rel[a][b]=cl(rel[a][b]+v,-100,100)};
// ---------- 소리 ----------
let AC;function snd(k){if(mute)return;try{AC=AC||new(window.AudioContext||window.webkitAudioContext)();
const f={ok:[660,880],no:[300,200],war:[180,120,90],nuke:[60,40,30,25],click:[500],turn:[440,550]}[k];
f.forEach((fr,i)=>{const o=AC.createOscillator(),g=AC.createGain();o.type=(k=='nuke'||k=='war')?'sawtooth':'square';o.frequency.value=fr;g.gain.value=.05;
o.connect(g);g.connect(AC.destination);const t=AC.currentTime+i*.09;o.start(t);g.gain.exponentialRampToValueAtTime(.001,t+.14);o.stop(t+.15)})}catch(e){}}
// ---------- UI 뼈대 ----------
const root=document.createElement('div');root.id='ns';
root.innerHTML=`
지도를 탭하면 지역 정보가 보여요
`;
document.body.appendChild(root);
const $=i=>root.querySelector('#'+i),cv=$('nc'),ctx=cv.getContext('2d');
// ---------- 세계 생성 ----------
function mkCoast(){coast=own.map((o,i)=>{if(o<0)return false;const x=i%GW,y=i/GW|0;return(x>0&&own[i-1]<0)||(x0&&own[i-GW]<0)||(y>2)*13+6.5;[[-3,-3],[3,-2],[0,4]].forEach(o=>sd.push({x:cx+o[0]+rnd()*2-1,y:cy+o[1]+rnd()*2-1,o:i}))}
const a=rnd()*6,b=rnd()*6;own=[];reg=[];
for(let y=0;y=GW-1||y>=GH-1||(Math.abs(y-12.5+Math.sin(x*.45+a)*1.4)<.8&&Math.sin(x*.9+b)>-.3)||Math.sin(x*.5+a)*Math.sin(y*.6+b)>.85;
if(sea){own.push(-1);reg.push(-1);continue}
let bi=0,bd=1e9;sd.forEach((s,i)=>{const d=Math.hypot(s.x-x,s.y-y);if(d({id:i,o:s.o,res:0,dmg:0,n:NM[s.o]+' '+['북','동','남'][i%3]+'부'}));mkCoast()}
function newGame(){gen();
C=NM.map((nm,i)=>({i,n:nm,c:CL[i],st:Array(6).fill(40),D:i?800:1000,tp:50,mil:60,df:0,sh:2,bm:1,ms:2,al:-1,ty:i?rnd()*7|0:-1,pop:0,blk:0,ind:0,si:0,di:0,wc:0}));
C.forEach(c=>{const pl=[0,1,2,3,4,5].sort(()=>rnd()-.5);for(let j=0;j<3;j++)RG[c.i*3+j].res=pl[j]});
rel=C.map(()=>C.map(()=>n(rnd()*30-8)));mem=C.map(()=>C.map(()=>[]));wars=[];pend=[];logs=[];chat=[];hist=[];pacts=[];turn=1;aid=0;
H=C.map((c,i)=>i==0);me=0;stats();C.forEach(c=>c.pop=c.k*1000);fx=[];
L('시스템','당신은 아르카를 이끕니다. 지역마다 특산품이 달라 자원이 부족해요 — 이웃과 교역하세요.');render()}
function stats(){C.forEach(c=>{c.k=0;c.p=[0,0,0,0,0,0]});const sx=Array(NC).fill(0),sy=Array(NC).fill(0);
own.forEach((o,i)=>{if(o<0)return;const c=C[o];c.k++;sx[o]+=i%GW;sy[o]+=i/GW|0;if(!RG[reg[i]].dmg)c.p[RG[reg[i]].res]++});
cen=C.map(c=>c.k?[(sx[c.i]/c.k+.5)*CS,(sy[c.i]/c.k+.5)*CS]:[0,0]);
sp=C.map(c=>{const l=[];own.forEach((o,i)=>{if(o==c.i&&coast[i])l.push(i)});return l.length?[l[0],l[l.length>>1],l[l.length-1]]:[]})}
function cand(a,b,am){const r=[];for(let i=0;i0&&own[i-1]==a)||(x0&&own[i-GW]==a)||(y0?i-1:-1,x0?i-GW:-1,y{if(j>=0&&own[j]>=0&&own[j]!=a)s.add(own[j])})}return[...s]}
function regsOf(e){const m={};own.forEach((o,i)=>{if(o==e)m[reg[i]]=(m[reg[i]]||0)+1});return Object.keys(m).map(Number).sort((a,b)=>m[b]-m[a])}
const rpos=g=>{const i=reg.findIndex((r,j)=>r==g&&own[j]==RG[g].o);const k=i<0?reg.indexOf(g):i;return[(k%GW+.5)*CS,((k/GW|0)+.5)*CS]};
const fxa=(k,p,q)=>fx.push({k,x0:p[0],y0:p[1],x1:q[0],y1:q[1],t:0,d:k=='nuke'?30:18});
// ---------- 경제·외교 ----------
const acc_=(p,f,ratio)=>C[p].blk>0||C[f].blk>0?0:cl(.3+rel[p][f]/150+C[p].tp/250+(ratio-1)*.8-(C[p].ty==6?.25:0),.05,.95);
function trade(b,s,r,q,d){C[s].st[r]-=q;C[b].st[r]+=q;C[b].D-=d;C[s].D+=d;rem(b,s,'trade',3);rem(s,b,'trade',3);C[b].tp+=.5;C[s].tp+=.5}
function ally(a,b){const A=C[a],B=C[b];if(A.al>=0&&B.al>=0)return 0;if(A.al<0&&B.al<0)A.al=B.al=aid++;else if(A.al<0)A.al=B.al;else B.al=A.al;
L('연합',`${A.n} · ${B.n} 연합 결성/가입`);return 1}
function declare(a,b,force,skip){if(wf(a,b)||!C[a].k||!C[b].k)return;const A=C[a];
if(!force&&!skip){const ids=A.al>=0?C.filter(v=>v.al==A.al&&v.i!=a&&v.i!=b&&v.k).map(v=>v.i):[...new Set([...adj(a),...adj(b)])].filter(v=>v!=a&&v!=b&&C[v].k);
const vo=v=>rel[v][b]=0&&A.al==C[me].al&&H[me]&&a!=me&&ids.includes(me)){pend.push({t:'wv',to:me,a,b,ids,y0:ids.filter(v=>v!=me&&vo(v)).length});return}
const yes=ids.filter(vo).length,ok=!ids.length||yes*2>=ids.length;
if(a==me||b==me||H[a]||H[b])L('승인',`${A.al>=0?'연합':'주변국'} 투표 ${yes}:${ids.length-yes} → ${ok?'승인':'부결'}`);
if(!ok){if(H[a]||!(A.ty==0&&rnd()<.3))return;force=true}}
pacts=pacts.filter(p=>{if((p.a==a&&p.b==b)||(p.a==b&&p.b==a)){A.tp=Math.max(0,A.tp-8);rem(b,a,'brk',-30);L('조약',`${A.n}이(가) 무역협정을 파기(약속 위반)`);return false}return true});
const mk=(x,y)=>({a:x,b:y,agg:a,s:0,pu:{},k:[C[x].k,C[y].k],pre:!!force,T:turn});wars.push(mk(a,b));
if(force){A.tp=Math.max(0,A.tp-25);C.forEach(v=>{if(v.i!=a)rel[v.i][a]-=15});rem(b,a,'firststrike',-30);
const t=`${A.n} → ${C[b].n} 선제공격`;hist.unshift(`T${turn} ${t}`);L('국제',`🚨 ${t}! (방어국은 승인 없이 즉시 방어 가능)`)}
else{hist.unshift(`T${turn} ${A.n} → ${C[b].n} 승인 전쟁`);L('국제',`${A.n}이(가) 승인을 받아 ${C[b].n}과(와) 개전`)}
snd('war');
C.forEach(v=>{if(!v.k||v.i==a||v.i==b||v.al<0)return;
if(v.al==C[b].al&&!wf(a,v.i)&&(H[v.i]||rel[v.i][a]<25)){wars.push(mk(a,v.i));L('연합',`${v.n}이(가) 연합국 ${C[b].n}을(를) 위해 참전`)}
else if(!force&&v.al==A.al&&v.al!=C[b].al&&!wf(v.i,b)&&rel[v.i][b]<10){wars.push(mk(v.i,b));L('연합',`${v.n}이(가) 연합국 ${A.n}을(를) 지원해 참전`)}})}
function endWar(w,win){wars=wars.filter(x=>x!=w);
if(win<0){L('전쟁',`${C[w.a].n}-${C[w.b].n} 전쟁이 무승부로 종결`);return}
const lo=win==w.a?w.b:w.a,W=C[win],Lo=C[lo],d=n(Lo.D*.4);Lo.D-=d;W.D+=d;
for(let r=0;r<6;r++){const q=Math.floor(Lo.st[r]*.4);Lo.st[r]-=q;W.st[r]+=q}
Lo.mil*=.8;Lo.sh=Math.floor(Lo.sh*.7);hist.unshift(`T${turn} ${W.n} 승 / ${Lo.n} 패`);
L('전쟁',`${W.n} 승리 — ${Lo.n}에게서 D ${d}와 자원 40% 획득`);snd('ok');
if(lo==w.agg){Lo.tp=Math.max(0,Lo.tp-20);L('국제',`선제공격국 ${Lo.n}의 외교 온도가 크게 하락`)}
else{L('국제',`${Lo.n}은(는) 선제공격 피해국으로 외교 페널티가 없습니다.`);
C.forEach(v=>{if(v.i==win||v.i==lo||!v.k)return;const al=v.al>=0&&v.al==Lo.al;
if(al||(v.tp>55&&rel[v.i][lo]>=0)){if(H[v.i]){if(al)pend.push({t:'aid',to:v.i,lo});return}
const g=al?200:100;if(v.Ddp){const g=take(c.i,e.i,0,1+(rnd()*3|0));c.mil*=.93;e.mil*=.95;w.s+=sg*g;m=`${c.n}의 돌격 성공: ${e.n}의 ${g}구역 점령`;fxa('boom',P0,P1)}else{c.mil*=.88;m=`${c.n}의 돌격이 ${e.n}의 방어에 막힘`}}
else if(t=='n'){const ap=c.sh*(.6+rnd()*.8),dp=e.sh*(.6+rnd()*.8);
if(ap>dp){e.sh=Math.floor(e.sh*.6);w.s+=sg;m=`${c.n} 함대가 ${e.n} 함대를 격파 (해상 통제)`}else{c.sh=Math.floor(c.sh*.7);m=`${c.n} 함대가 ${e.n} 함대에 패퇴`}fxa('ship',P0,P1)}
else if(t=='k'){e.blk=4;m=`${c.n}이(가) ${e.n}을(를) 해상 봉쇄 — 교역·외교 수입 감소`;fxa('ship',P0,P1)}
else if(t=='v'){const ap=c.mil*.8+c.sh*6,dp=e.mil*(1+e.df*.15)*(.6+rnd()*.8)*(e.sh>c.sh?1.3:1);
if(ap>dp){const g=take(c.i,e.i,1,1+(rnd()*2|0));c.sh--;w.s+=sg*g;m=`${c.n}의 상륙작전 성공: ${e.n}의 ${g}구역 점령`;fxa('ship',P0,P1)}else{c.sh=Math.max(0,c.sh-2);m=`${c.n}의 상륙작전이 ${e.n}에 격퇴됨`}}
else if(t=='b'){e.mil*=.82-rnd()*.05;m=`${c.n} 폭격기가 ${e.n}의 군사시설 폭격`;w.s+=sg;fxa('plane',P0,P1)}
else if(t=='B'){e.ind=3;e.D=Math.max(0,e.D-80);m=`${c.n} 폭격기가 ${e.n}의 산업시설 폭격 — 수입 감소`;fxa('plane',P0,P1)}
else if(t=='m'){c.ms--;const rs=regsOf(e.i);let g=sel.g;if(c.i!=me||!rs.includes(g))g=rs[c.i==me?0:rnd()*rs.length|0];
if(g==null){c.ms++;c.D+=COST[t];return -1}RG[g].dmg=3;e.mil*=.93;w.s+=sg;m=`${c.n} 미사일이 ${RG[g].n} 지역 타격 — 3턴간 생산 정지`;fxa('miss',P0,rpos(g))}
else{e.mil*=.6;const g=take(c.i,e.i,0,6)||take(c.i,e.i,1,6);w.s+=sg*g;C.forEach(v=>{if(v.i!=c.i)rem(v.i,c.i,'nuke',-40)});c.tp=Math.max(0,c.tp-30);
m=`☢️ ${c.n}이(가) ${e.n}에 수소폭탄 사용! 국제사회가 경악합니다`;fxa('nuke',P0,P1);snd('nuke')}
if(V||t=='h'){L('전쟁',m);if(V&&t!='h')snd('war')}else CH(m);stats();
const k0=w.a==e.i?w.k[0]:w.k[1];if(wars.includes(w)&&(e.k0;
if(land)o.push('a','a');if(c.sh>=1)o.push('n');if(c.sh>=3&&!land)o.push('v','v');if(c.sh>=2&&rnd()<.3)o.push('k');if(c.bm>0)o.push('b','B');if(c.ms>0)o.push('m');
if(c.ty==0&&c.mil>e.mil*3&&c.D>3000&&rnd()<.1)o.push('h');
if(!o.length||c.D<150){if(c.D>100){c.D-=100;c.df=Math.min(5,c.df+1)}return}
const t=o[rnd()*o.length|0];strike(c,e,t)}
// ---------- AI ----------
function aiTrade(c,pr){let r=0;c.st.forEach((s,i)=>{if(sp.k&&p.i!=c.i&&p.st[r]>q+20&&!wf(c.i,p.i)).sort((a,b)=>rel[c.i][b.i]-rel[c.i][a.i])[0];
if(cd){const d=n(q*RP[r]*(.8+rnd()*.5));
if(H[cd.i]){if(pend.length<6)pend.push({t:'req',to:cd.i,f:c.i,r,q,d})}
else{const ok=rnd(){if(s>c.st[r2])r2=i});
if(c.st[r2]>70){const cd=C.filter(p=>p.k&&p.i!=c.i&&p.st[r2]<30&&p.D>150&&!wf(c.i,p.i))[0];
if(cd){const q=25,d=n(q*RP[r2]*1.1);if(H[cd.i]){if(pend.length<6)pend.push({t:'offer',to:cd.i,f:c.i,r:r2,q,d})}
else if(rnd()x.a==c.i||x.b==c.i);
if(w){const e=C[w.a==c.i?w.b:w.a],sc=(w.a==c.i?1:-1)*w.s;aiStrike(c,e);
if(wars.includes(w)&&sc<-2&&rnd()<.35){if(H[e.i]){if(pend.length<6)pend.push({t:'peace',to:e.i,w})}else endWar(w,w.s>0?w.a:w.s<0?w.b:-1)}return}
if(c.D>400&&rnd()H[v.i]&&v.k&&rel[v.i][c.i]>0);if(f&&pend.length<6)pend.push({t:'dreq',to:f.i,f:c.i})}
if(rnd()v.k&&v.i!=c.i&&rel[c.i][v.i]>15&&!pacts.some(q=>(q.a==c.i&&q.b==v.i)||(q.a==v.i&&q.b==c.i))&&!wf(c.i,v.i));
if(p){if(H[p.i]){if(pend.length<6)pend.push({t:'pact',to:p.i,f:c.i})}else{pacts.push({a:c.i,b:p.i,exp:turn+10});CH(`${c.n}-${p.n} 무역협정 체결`)}}}
if(rnd()v.k&&v.i!=c.i&&rel[c.i][v.i]>0&&v.D<500).sort((a,b)=>a.D-b.D)[0];
if(p&&c.D>400){c.D-=100;p.D+=100;rem(p.i,c.i,'gift',8);if(H[p.i])L('국제',`${c.n}이(가) 당신에게 D 100을 지원했습니다`);else CH(`${c.n} → ${p.n} 지원금 D 100`)}}
if(rnd()3){const gr=v=>mem[c.i][v].filter(m=>m.k=='firststrike').length;
const ts=C.filter(v=>v.k&&v.i!=c.i&&!wf(c.i,v.i)&&(c.sh>=3||adj(c.i).includes(v.i))&&v.mil(a.mil-gr(a.i)*30)-(b.mil-gr(b.i)*30));
if(ts.length)declare(c.i,ts[0].i,false)}
if(rnd()v.k&&v.i!=c.i&&!H[v.i]&&PR[v.ty<0?1:v.ty][2]>0&&rel[c.i][v.i]>20&&rel[v.i][c.i]>20);if(p)ally(c.i,p.i)}}
function next(){turn++;pend=[];wars.forEach(w=>w.pu={});stats();
C.forEach(c=>{if(!c.k)return;const f=c.k/104;c.si=n((20+c.tp*.3)*f*(c.ind>0?.6:1));
c.di=n(c.tp*1.5*f*(c.blk>0?.4:1))+pacts.filter(p=>p.a==c.i||p.b==c.i).length*8;c.wc=wars.filter(w=>w.a==c.i||w.b==c.i).length*40;
c.D+=c.si+c.di-c.wc;let sh=0;
for(let r=0;r<6;r++){c.st[r]+=c.p[r]-c.k*.17;if(c.st[r]<0){c.D-=n(-c.st[r]*RP[r]*.6);c.st[r]=0;sh=1}}
c.pop=n(c.pop*(sh?.99:1.01));c.mil+=c.k*.04;c.tp+=(50-c.tp)*.02;c.D=Math.max(0,c.D);if(c.blk>0)c.blk--;if(c.ind>0)c.ind--});
RG.forEach(g=>{if(g.dmg>0)g.dmg--});
pacts=pacts.filter(p=>{if(p.exp>turn)return true;L('조약',`${C[p.a].n}-${C[p.b].n} 무역협정 만료`);return false});
C.forEach(ai);
for(let i=0;ic.tp=cl(c.tp,0,100));stats();if(!C[me].k&&H[me]){L('시스템','국가가 멸망했습니다. 관찰 모드로 전환하세요.')}snd('turn');render()}
// ---------- 저장/불러오기 ----------
function save(){const s=JSON.stringify({own,reg,RG,C,rel,mem,wars,pend,logs,chat,hist,pacts,turn,aid,H,me});
try{localStorage.setItem(SK,s)}catch(e){window.__nsSave=s}L('시스템','저장되었습니다')}
function load(){let s;try{s=localStorage.getItem(SK)}catch(e){}s=s||window.__nsSave;if(!s){L('시스템','저장 데이터가 없습니다');return}
const d=JSON.parse(s);({own,reg,RG,C,rel,mem,wars,pend,logs,chat,hist,pacts,turn,aid,H,me}=d);mkCoast();stats();L('시스템','불러왔습니다')}
// ---------- 플레이어 행동 ----------
const can=()=>{if(!H[me]){L('시스템','관찰 중인 국가는 조작할 수 없어요 (국가 탭에서 조종 전환)');render();return false}return true};
const act={
nx(){if(!pend.length||true){next()}},
cyc(d){me=(me+d+NC)%NC;render()},spd(s){spd=s;acc=0;render()},mute(){mute=!mute;render()},save(){save();render()},load(){load();render()},
tog(){H[me]=!H[me];render()},obs(){H=H.map(()=>false);spd=1;L('시스템','관찰 모드: 모든 국가를 AI가 운영합니다');render()},
chat(){showChat=!showChat;render()},ng(){newGame()},
req(b){if(!can())return;const B=C[b],P=C[me],{r,q,d}=sel;
if(P.D400&&rnd()15&&C[me].tp>40&&C[b].ty!=6&&ally(me,b))snd('ok');else{L('연합',`${C[b].n}이(가) 연합 제안을 거절`);snd('no')}render()},
pact(b){if(!can())return;if(rel[b][me]>5&&!pacts.some(p=>(p.a==me&&p.b==b)||(p.a==b&&p.b==me))&&C[b].blk<1){pacts.push({a:me,b,exp:turn+10});rem(b,me,'pact',5);L('조약',`${C[b].n}과(와) 10턴 무역협정 체결 (매턴 D+8)`);snd('ok')}else{L('조약',`${C[b].n}이(가) 무역협정을 거절/이미 체결`);snd('no')}render()},
leave(){if(!can())return;C[me].al=-1;C[me].tp-=3;L('연합','연합에서 탈퇴했습니다');render()},
help(b){if(!can())return;const P=C[me];if(P.D<150)return;P.D-=150;C[b].D+=150;P.tp+=2;rem(b,me,'aid',10);L('연합',`${C[b].n}에 지원안 시행: D 150`);render()},
war(b,f){if(!can())return;declare(me,b,f);render()},
buy(k){if(!can())return;const P=C[me],T={m:[200,'mil',12],s:[300,'sh',2],b:[250,'bm',2],x:[300,'ms',3],d:[100,'df',1]}[k];if(P.D=5))return;P.D-=T[0];P[T[1]]+=T[2];snd('click');render()},
hit(e,t){if(!can())return;const w=wf(me,e);if(!w)return;if(w.pu[me]){L('군사','이번 턴 이미 행동했습니다');return render()}
w.pu[me]=1;const r=strike(C[me],C[e],t);if(r<1){w.pu[me]=0;L('군사',r<0?'수행 불가: 조건 미충족(국경·함선·폭격기·미사일)':'D가 부족합니다')}render()},
peace(e){if(!can())return;const w=wf(me,e);if(!w)return;const sa=(w.a==e?1:-1)*w.s;
if(rnd()<(sa<=0?.8:.3))endWar(w,w.s>0?w.a:w.s<0?w.b:-1);else{L('외교',`${C[e].n}이(가) 평화 협정을 거절`);snd('no')}render()},
ans(i,y){const p=pend.splice(i,1)[0];if(!p)return;const P=C[p.to];
if(p.t=='req'){if(y&&P.st[p.r]>=p.q){trade(p.f,p.to,p.r,p.q,p.d);P.tp+=2;rem(p.f,p.to,'help',6);L('외교',`${C[p.f].n}의 요청 승인`)}else{rem(p.f,p.to,'refuse',-3);P.tp-=1;L('외교',`${C[p.f].n}의 요청 거절`)}}
else if(p.t=='offer'){if(y&&P.D>=p.d){trade(p.to,p.f,p.r,p.q,p.d);L('외교',`${C[p.f].n}에게서 ${RN[p.r]} ${p.q}개 구매`)}}
else if(p.t=='dreq'){if(y&&P.D>=150){P.D-=150;C[p.f].D+=150;P.tp+=2;rem(p.f,p.to,'help',8);L('외교',`${C[p.f].n}에 D 150 지원`)}}
else if(p.t=='pact'){if(y){pacts.push({a:p.f,b:p.to,exp:turn+10});L('조약',`${C[p.f].n}과(와) 무역협정 체결`)}}
else if(p.t=='peace'){if(y&&wars.includes(p.w))endWar(p.w,p.w.s>0?p.w.a:p.w.s<0?p.w.b:-1)}
else if(p.t=='aid'){if(y&&P.D>=150){P.D-=150;C[p.lo].D+=150;P.tp+=3;rem(p.lo,p.to,'aid',10);L('연합',`${C[p.lo].n} 지원안 찬성: D 150`)}}
else if(p.t=='wv'){const ok=(p.y0+(y?1:0))*2>=p.ids.length;L('승인',`연합 투표 ${p.y0+(y?1:0)}:${p.ids.length-p.y0-(y?1:0)} → ${ok?'승인':'부결'}`);if(ok)declare(p.a,p.b,false,true)}
render()}};
const PT=p=>{const f=C[p.f]||{},T={
req:()=>`[외교 나레이션] ${f.n}에서 ${RN[p.r]} ${p.q}개를 요청했습니다. (제공 D ${p.d})`,
offer:()=>`[외교 나레이션] ${f.n}이(가) ${RN[p.r]} ${p.q}개를 D ${p.d}에 팔겠다고 제안했습니다.`,
dreq:()=>`[외교 나레이션] ${f.n}이(가) D 150 지원을 요청했습니다.`,
pact:()=>`[조약 나레이션] ${f.n}이(가) 10턴 무역협정을 제안했습니다.`,
peace:()=>`[외교 나레이션] ${C[p.w.a==p.to?p.w.b:p.w.a].n}이(가) 평화 협정을 제안했습니다.`,
aid:()=>`[연합 나레이션] ${C[p.lo].n} 전후 복구 지원안(D 150)이 제출되었습니다.`,
wv:()=>`[연합 나레이션] ${C[p.a].n}의 ${C[p.b].n} 전쟁 안건 투표 (현재 찬성 ${p.y0}/${p.ids.length})`};return T[p.t]()};
// ---------- 화면 ----------
const al=c=>c.al>=0?`🤝연합${c.al+1}`:'';
function render(){const P=C[me];
$('nh').innerHTML=`${P.n}${H[me]?'':'(관찰)'} T${turn} 💰${n(P.D)} 🌡️${n(P.tp)} ⚔️${n(P.mil)} `+
[[0,'⏸'],[1,'1x'],[2,'2x'],[4,'4x']].map(s=>``).join('')+``;
$('np').innerHTML=pend.map((p,i)=>p.to!=me?'':`
${PT(p)}
`).join('');
$('nt').innerHTML=[['e','경제'],['d','외교'],['m','군사'],['a','연합'],['i','국가'],['l','소식']].map(t=>``).join('');
let h='';
if(tab=='e')h=`
💰 D ${n(P.D)} · 자체 +${P.si} · 외교 +${P.di} · 전쟁유지 -${P.wc} 🌡️ 온도 ${n(P.tp)} · 👥 인구 ${P.pop.toLocaleString()} · 영토 ${P.k}${P.blk>0?' ⚓ 봉쇄당함 '+P.blk+'턴':''}${P.ind>0?' 🏭 산업시설 피해 '+P.ind+'턴':''}
`+
[0,1,2,3,4,5].map(r=>`
${RN[r]} 재고 ${n(P.st[r])} · 생산 ${P.p[r]} · 소비 ${n(P.k*.17)} ${P.p[r]`).join('')+`