mirror of
https://github.com/migatu/vtt_work.git
synced 2026-07-14 13:34:42 +00:00
9 lines
10 KiB
Plaintext
9 lines
10 KiB
Plaintext
{"_id":"a68969a2ac5a2855","name":"Import Voidships","type":"script","img":"icons/svg/sword.svg","scope":"global","author":null,"ownership":{"default":2},"command":"try{game.wgVoidshipsMacros.importVoidships();}catch(e){console.error(e);ui.notifications.error('ImportVoidships error — check console');}"}
|
|
{"_id":"72e2ff46870f2723","name":"Create Voidship Crit Table (d66)","type":"script","img":"icons/svg/d20-black.svg","scope":"global","author":null,"ownership":{"default":2},"command":"try{game.wgVoidshipsMacros.createCritTable();}catch(e){console.error(e);ui.notifications.error('CreateCritTable error — check console');}"}
|
|
{"_id":"9c4931885b529b9c","name":"Apply Voidship Hit","type":"script","img":"icons/svg/splash.svg","scope":"global","author":null,"ownership":{"default":2},"command":"try{game.wgVoidshipsMacros.applyHit();}catch(e){console.error(e);ui.notifications.error('ApplyHit error — check console');}"}
|
|
{"_id":"473e9b2b97086116","name":"Recharge Void Shields","type":"script","img":"icons/svg/regen.svg","scope":"global","author":null,"ownership":{"default":2},"command":"try{game.wgVoidshipsMacros.rechargeShields();}catch(e){console.error(e);ui.notifications.error('RechargeShields error — check console');}"}
|
|
{"_id":"dfd9ef292fb3774f","name":"Set Void Shields","type":"script","img":"icons/svg/aura.svg","scope":"global","author":null,"ownership":{"default":2},"command":"try{game.wgVoidshipsMacros.setShields();}catch(e){console.error(e);ui.notifications.error('SetShields error — check console');}"}
|
|
{"_id":"5079989f359a3c3d","name":"Toggle Geller (Primary/Reserve)","type":"script","img":"icons/svg/aura.svg","scope":"global","author":null,"ownership":{"default":2},"command":"(async()=>{try{const a=canvas.tokens.controlled[0]?.actor; if(!a) return ui.notifications.warn('Select a voidship token.'); const g=a.getFlag('wg-voidships','geller')||{primaryActive:false,reserveActive:false}; const content=`<p>Primary: <input type=checkbox id=p ${g.primaryActive?'checked':''}></p><p>Reserve: <input type=checkbox id=r ${g.reserveActive?'checked':''}></p>`; new Dialog({title:'Geller Fields',content,buttons:{ok:{label:'Set',callback:async html=>{const p=html[0].querySelector('#p').checked; const r=html[0].querySelector('#r').checked; await a.setFlag('wg-voidships','geller',{primaryActive:p,reserveActive:r}); ChatMessage.create({content:`${a.name}: Geller Primary ${p?'ON':'OFF'} / Reserve ${r?'ON':'OFF'}`});}}}}).render(true);}catch(e){console.error(e);ui.notifications.error('Toggle Geller error — check console');}})();"}
|
|
{"_id":"6f2a9b8c7d6e5f40","name":"Payload → Apply/Revert","type":"script","img":"icons/commodities/tech/cog-brass.webp","scope":"global","author":null,"ownership":{"default":2},"command":"(async()=>{const FLAG='wg-voidships-builder';const dbg=(...m)=>console.log('[WG Payload]',...m);function T(s){const t=String(s??'').split(':');return{name:t[0].trim(),rating:(t[1]||'-').trim()}};try{const actor=canvas.tokens?.controlled[0]?.actor??game.user?.character; if(!actor){ui.notifications.warn('Select a token or open an actor sheet.');return;} const weapons=actor.items.filter(i=>i.type==='weapon'&&(((i.system?.traits?.list)||[]).some(t=>((t.name||'').toLowerCase()).includes('payload'))||['torpedo tubes','launch bay'].includes((i.name||'').toLowerCase())||i.getFlag?.(FLAG,'mount'))); if(!weapons.length){ui.notifications.warn('No payload-capable weapons on actor.');return;} const packsWanted=new Set(['wg-voidships-builder.wg-voidship-items','wg-voidships-builder.wg-voidship-archeotech','wg-voidships-builder.wg-voidship-xenos']); const packs=game.packs.filter(p=>p.documentName==='Item'&&(packsWanted.has(p.collection)||/^wg-voidship-/.test(p.metadata?.name||p.metadata?.id||''))); const PL=[]; const clean=(s)=>String(s||'').replace(/\\s*\\(owned.*\\)$/i,'').trim(); const getPl=(d)=>{try{const byFlag=d.getFlag?.(FLAG,'payload'); if(byFlag) return byFlag;}catch(e){} // backwards-compat\n try{const old=d.getFlag?.('wgvoid','payload'); if(old) return old;}catch(e){} return d.system?.payload}; const add=(d,tag='')=>{const pl=getPl(d); if(pl) PL.push({name:`${d.name}${tag}`, id:d.uuid, mount:pl.mount, data:d})}; // z kompendiów\nfor(const p of packs){try{const docs=await p.getDocuments(); for(const d of docs) add(d,'');}catch(e){console.warn(e)}} // z aktora\nfor(const it of actor.items.filter(i=>i.type==='gear')){const has=getPl(it); if(has) add(it,' (owned)')} // fallback: po nazwie\nfor(const it of actor.items.filter(i=>i.type==='gear'&&!getPl(i))){const nm=clean(it.name); const m= nm.startsWith('Wing Loadout')? 'launch-bay' : (nm.startsWith('Torpedo Warhead')? 'torpedo' : null); const fromPack=PL.find(p=>clean(p.name)===nm); if(fromPack) PL.push({name:`${nm} (owned→pack)`, id:fromPack.id, mount:fromPack.mount, data:fromPack.data}); else if(m) PL.push({name:`${nm} (owned—name only)`, id:it.uuid, mount:m, data:it, nameOnly:true})} const wOpts=weapons.map(w=>`<option value='${w.id}'>${w.name}</option>`).join(''); function payloadOpts(m){const o=PL.filter(p=>p.mount===m).map(p=>`<option value='${p.id}'>${p.name}</option>`).join('');return o||`<option value=''>— none for ${m} —</option>`} let mount='torpedo'; const dlg=new Dialog({title:'Apply Payload to Weapon',content:`<form><div class='form-group'><label>Weapon</label><select name='weapon'>${wOpts}</select></div><div class='form-group'><label>Payload (auto)</label><select name='payload'></select></div><div class='form-group'><label>Or paste Payload UUID / .Item.id / name</label><input type='text' name='uuid' placeholder='Compendium/World UUID, .Item.XXXX, 16-char id, or exact name'/></div><p style='font-size:11px;opacity:.8'>Makro czyta payload z <code>flags.${FLAG}.payload</code> (fallback: <code>system.payload</code>).</p></form>`,render:html=>{const $w=html.find(\"select[name='weapon']\"); const setList=()=>{const wid=$w.val(); const w=actor.items.get(wid); const nm=(w?.name||'').toLowerCase(); const byFlag=w.getFlag?.(FLAG,'mount'); mount=byFlag|| (nm.includes('torpedo')? 'torpedo' : (nm.includes('launch bay')? 'launch-bay' : (((w?.system?.traits?.list)||[]).some(t=>((t.name||'').toLowerCase()).includes('torpedo'))? 'torpedo' : 'launch-bay'))); html.find(\"select[name='payload']\").html(payloadOpts(mount))}; $w.on('change',setList); setList()},buttons:{apply:{label:'Apply',callback:async html=>{try{const wid=html.find(\"select[name='weapon']\").val(); let val=(html.find(\"input[name='uuid']\").val()||'').trim(); if(!val) val=html.find(\"select[name='payload']\").val(); const resolveAny=async(v)=>{try{if(!v) return null; if(v.startsWith('.Item.')){const r=foundry.utils.parseUuid(v,{relative:actor}); if(r?.uuid) return await fromUuid(r.uuid);} if(/^[A-Za-z0-9]{16}$/.test(v)){const owned=actor.items.get(v); if(owned) return owned;} if(!v.includes('.')&&v.length){const m=PL.find(p=>clean(p.name)===v); if(m) return await fromUuid(m.id);} return await fromUuid(v)}catch(e){return null}}; let doc=await resolveAny(val); if(!doc){ui.notifications.error('No valid payload selected.');return;} if(!(doc instanceof Item)){try{const d=await fromUuid(doc?.uuid||''); if(d) doc=d;}catch(e){}} const pl=getPl(doc); if(!pl){const m=PL.find(p=>clean(p.name)===clean(doc.name)&&getPl(p.data)); if(m){doc=await fromUuid(m.id);} } const payload=getPl(doc); if(!payload){ui.notifications.warn('Selected item has no payload data (flags/system). Run the migration macro to add flags.'); return;} if(!['torpedo','launch-bay'].includes(payload.mount)){ui.notifications.error('Payload mount not compatible (expected torpedo/launch-bay).');return;} const w=actor.items.get(wid); const backup={name:w.name,damage:w.system?.damage,traits:w.system?.traits,keywords:w.system?.keywords,description:w.system?.description}; await w.update({[`flags.${FLAG}.payloadBackup`]:backup,[`flags.${FLAG}.payloadRef`]:doc.uuid}); const base=Array.isArray(w.system?.traits?.list)?w.system.traits.list:[]; const kept=base.filter(t=>((t.name||'').toLowerCase()).indexOf('payload')==-1); const newTraits=[...kept,...(payload.traits||[]).map(T),{name:'payload-applied',rating:doc.name}]; const dm=payload.damage||{}; const note=`<hr/><b>Payload:</b> ${doc.name}<br/><i>${doc.system?.description||''}</i>${payload.special? `<br/><b>Special:</b> ${payload.special}`:''}${payload.attack?.notes? `<br/><b>Attack:</b> ${payload.attack.notes}`:''}`; await w.update({\"system.damage.base\":(dm.base??0),\"system.damage.ed.base\":(dm.ed??0),\"system.damage.ap.base\":(dm.ap??0),\"system.traits.list\":newTraits,\"system.description\":`${w.system?.description||''}\\n\\n${note}`,\"system.keywords\":`${w.system?.keywords||''}, PAYLOAD-APPLIED`}); ui.notifications.info(`Applied ${doc.name} to ${w.name}.`);}catch(e){console.error(e);ui.notifications.error('Apply failed — see console.');}}},revert:{label:'Revert',callback:async html=>{try{const wid=html.find(\"select[name='weapon']\").val(); const w=actor.items.get(wid); const b=w.getFlag?.(FLAG,'payloadBackup'); if(!b){ui.notifications.warn('No backup on this weapon.');return;} await w.update({\"system.damage\":b.damage,\"system.traits\":b.traits,\"system.description\":b.description,\"system.keywords\":b.keywords,[`flags.${FLAG}`]:null}); ui.notifications.info(`Reverted ${w.name} to pre-payload state.`);}catch(e){console.error(e);ui.notifications.error('Revert failed — see console.');}}},cancel:{label:'Cancel'}},default:'apply'}).render(true);}catch(e){console.error(e);ui.notifications.error('Payload macro error — see console.');}})();"}
|
|
{"_id":"b7a1a9c0d2ef3344","name":"Migrate Payloads → Flags","type":"script","img":"icons/tools/smithing/anvil.webp","scope":"global","author":null,"ownership":{"default":2},"command":"(async()=>{const FLAG='wg-voidships-builder';let fixed=0;const moveToFlag=async(it,pl,ctx={})=>{if(!pl) return; await it.update({[`flags.${FLAG}.payload`]:pl},ctx); fixed++;};const readAny=(it)=>{try{const f=it.getFlag?.(FLAG,'payload'); if(f) return f;}catch(e){} try{const old=it.getFlag?.('wgvoid','payload'); if(old) return old;}catch(e){} return it.system?.payload}; // 1) Actor items\nfor(const a of game.actors){for(const it of a.items){const pl=readAny(it); if(pl) await moveToFlag(it,pl);}} // 2) Compendium items (unlock+context)\nconst packIds=['wg-voidships-builder.wg-voidship-items','wg-voidships-builder.wg-voidship-archeotech','wg-voidships-builder.wg-voidship-xenos']; for(const pid of packIds){const p=game.packs.get(pid); if(!p) continue; try{await p.configure({locked:false});}catch(e){} const docs=await p.getDocuments(); for(const d of docs){const pl=readAny(d); if(pl) await moveToFlag(d,pl,{pack:p.collection});} try{await p.configure({locked:true});}catch(e){}} ui.notifications.info(`Payload migration done. Updated: ${fixed} items.`);})();"}
|