PageSourceSearch

https://georgluif.at/assets/hero-repair.js?v=a82cc92a

js georgluif.at collected 2026-10-09 21:25:26 UTC 9,998 bytes, 2 lines download raw bytes

1/*! © 2011–2026 Georg Luif · georgluif.at · All rights reserved. */
2import*as E from"./three.module.min.js";import{createEffect as X}from"./particles.js";import{FX as I}from"./fx-recipes.js";import{fixedLookNode as oe,repairToolOf as te,toolAllows as ne}from"./repair-look.js";import{getGameStats as w}from"./hero-gamestats.js";import{clampCardAnchor as ie,cardMargins as se,anchorInView as le}from"./hero-camera.js";const j=.35,ae=7,v=20,V=30,de=2600,G=.28,c=1800,re=1e3;export function createHeroRepair(r){const F=r.root,A=r.camera,l=r.runtime,x=r.scene,L=r.toast||null,T=r.avatarPosition||null,N=r.onFixed||null,O=r.pay||null,D=r.payShare||null,U=r.capOpen||null,H=r.onWork||null,B=r.toolOf||null,a=new Map,g=new Map;function k(e){return a.get(e)||a.get(g.get(e))||null}const d=new E.Vector3,m=new E.Box3;let y=!1;function J(e){return(e.node.components||[]).find(function(o){return o&&o.type==="repairable"})||null}function Z(e){if(m.setFromObject(e.object3d),m.isEmpty()){e.object3d.getWorldPosition(d),e.x=d.x,e.y=d.y+1,e.z=d.z,e.cy=d.y+.5,e.ground=d.y,e.r=.5;return}const o=m.getCenter(d);e.x=o.x,e.z=o.z,e.cy=o.y,e.y=m.max.y+j,e.ground=m.min.y,e.r=Math.max(m.max.x-m.min.x,m.max.z-m.min.z)/2}function K(e){const o=document.createElement("div");o.className="hero-repair";const t=document.createElement("span");t.className="hero-repair-text";const s=document.createElement("div");s.className="hero-hpbar hero-repair-bar";const i=document.createElement("i");s.appendChild(i),o.appendChild(t),o.appendChild(s),F.appendChild(o),e.el=o,e.text=t,e.bar=s,e.fill=i,p(e)}function P(e,o,t){e.text.textContent!==o&&(e.text.textContent=o,e.sizeAt=null),e.bar.style.display!==t&&(e.bar.style.display=t,e.sizeAt=null)}function p(e){if(!e.el)return;if(e.fixed){P(e,e.fixedText,e.bar.style.display),e.el.classList.add("is-fixed"),e.fill.style.width="100%";return}e.el.classList.remove("is-fixed");const o=performance.now(),t=e.wrongUntil>o,s=!t&&e.deniedUntil>o,i=!t&&!s&&e.cappedUntil>o;e.el.classList.toggle("is-denied",s||t||i),P(e,t?"Only the "+e.toolName+" mends this":s?"Needs "+e.cost+" XP — find feathers":i?e.capText:(e.progress>0?e.workingText+" "+e.progress+"/"+e.work:e.label||(e.tool?"Broken — needs the "+e.toolName:"Broken — needs a tool"))+(e.cost?" · "+e.cost+" XP per hit":e.share&&e.progress===0?" · mending costs XP":""),e.progress>0?"":"none"),e.fill.style.width=Math.round(e.progress/e.work*100)+"%"}function _(e){if(e.smoke||!x||!e.smokes)return;const o=X(I.smoke(),{seed:11+a.size});o.points.position.set(e.x,e.cy+.15,e.z),x.add(o.points),e.smoke=o}function Q(e){e.smoke&&(typeof e.smoke.stop=="function"&&e.smoke.stop(),e.smokeFade=2.5)}function b(e){e.smoke&&(x.remove(e.smoke.points),e.smoke.dispose(),e.smoke=null)}function C(e,o,t,s){if(!x)return;const i=X(e,{seed:(performance.now()|0)%997});i.points.position.set(o,t,s),x.add(i.points),i.burst(),h.push({e:i,t:0})}const h=[];function Y(e,o){const t=te(o),s=t&&B?B(t):null,i={nodeId:e.node.id,object3d:e.object3d,baseScale:e.object3d.scale.clone(),baseScale0:e.object3d.scale.clone(),work:Math.max(1,Math.min(500,Math.round(o.work!=null?o.work:30))),label:typeof o.label=="string"&&o.label.trim()?o.label.trim():"",workingText:typeof o.workingText=="string"&&o.workingText.trim()?o.workingText.trim().slice(0,40):"Fixing…",fixedText:typeof o.fixedText=="string"&&o.fixedText.trim()?o.fixedText.trim().slice(0,60):"Fixed!",smokes:o.smoke!==!1,rebreakS:typeof o.rebreakS=="number"&&o.rebreakS>0?o.rebreakS:0,cost:Math.max(0,Math.min(100,Math.round(+o.xpPerStrike||0))),perHit:Math.max(0,Math.min(500,Math.round(+o.perHit||0))),share:Math.max(0,Math.min(1,+o.xpShare||0)),capBy:Array.isArray(o.capBy)?o.capBy.filter(function(n){return typeof n=="string"&&n}).slice(0,8):null,perPart:Math.max(1,Math.round(+o.perPart||10)),capText:typeof o.capText=="string"&&o.capText.trim()?o.capText.trim().slice(0,80):"It needs a part first",cappedUntil:0,deniedUntil:0,deniedTimer:0,tool:t,toolName:s&&s.name?s.name:t||"",toolSkills:s&&Array.isArray(s.skillIds)?s.skillIds.slice():null,wrongUntil:0,lookDoc:oe(e.node.id,o.fixed),preloaded:!1,progress:0,fixed:!1,fixedFor:0,jolt:0,helped:!1,x:0,y:0,z:0,cy:0,ground:0,r:.5,el:null,text:null,bar:null,fill:null,smoke:null,smokeFade:0,hideTimer:0};Z(i),K(i),_(i),a.set(i.nodeId,i),(function n(f){for(const u of f||[])u&&u.id&&g.set(u.id,i.nodeId),n(u&&u.children)})(e.node.children)}function W(e){clearTimeout(e.hideTimer),clearTimeout(e.deniedTimer),e.el&&e.el.remove(),b(e),e.object3d.scale.copy(e.baseScale0),l.clearAltLook&&l.clearAltLook(e.nodeId),a.delete(e.nodeId),g.forEach(function(o,t){o===e.nodeId&&g.delete(t)})}function $(e){!e.lookDoc||!l.showAltLook||l.showAltLook(e.nodeId,e.lookDoc)||console.warn('[repair] "'+e.nodeId+'": the fixed look could not be built (a deleted prefab?)')}function ee(){if(y)return;const e=new Set;
2l.byId.forEach(function(o){if(l.altLookOwner&&l.altLookOwner(o.node.id))return;const t=J(o);t&&(e.add(o.node.id),a.has(o.node.id)||Y(o,t))}),a.forEach(function(o,t){e.has(t)||W(o)})}function q(e,o,t,s){const i=t==="quiet";e.fixed=!0,e.fixedFor=s||0,p(e),i?b(e):Q(e),e.jolt=0,e.object3d.scale.copy(e.baseScale),$(e),clearTimeout(e.hideTimer),i?e.el&&e.el.classList.add("is-gone"):(C(I.featherCollect(),e.x,e.cy+.2,e.z),C(I.confetti(),e.x,e.y-j,e.z),l.playEventDefault("unlock")||l.playEventDefault("levelup"),L&&L(e.fixedText,e.x,e.y+.2,e.z),e.hideTimer=setTimeout(function(){e.el&&e.el.classList.add("is-gone")},de));const n=e.helped;e.helped=!1,!i&&n&&w().event("mended",{id:e.nodeId,work:e.work,last:!!o}),N&&N(e.nodeId,!!o,{helped:n,quiet:i,live:t==="live",x:e.x,z:e.z,ground:e.ground,cy:e.cy,top:e.y-j,r:e.r,work:e.work})}function R(e){e.fixed=!1,e.progress=0,e.helped=!1,l.clearAltLook&&l.clearAltLook(e.nodeId),clearTimeout(e.hideTimer),e.el&&e.el.classList.remove("is-gone"),p(e),b(e),_(e)}function S(e){if(!e.capBy||!e.capBy.length)return e.work;let o=0;for(const t of e.capBy)U&&U(t)&&o++;return Math.min(e.work,o*e.perPart)}return{refresh:ee,perHitOf:function(e){const o=k(e);return o&&o.perHit>0?o.perHit:null},progressOf:function(e){const o=k(e);return o?{progress:o.progress,work:o.work,fixed:o.fixed,cap:S(o)}:null},setScaleMul:function(e,o){const t=a.get(e);return t?(t.baseScale.copy(t.baseScale0).multiplyScalar(o>0?o:1),t.jolt>0||t.object3d.scale.copy(t.baseScale),!0):!1},isBroken:function(e){const o=k(e);return!!o&&!o.fixed},setFixed:function(e,o){const t=a.get(e);if(!t||t.fixed||y)return!1;const s=o&&o.ageMs>0?o.ageMs/1e3:0;return t.rebreakS>0&&s>=t.rebreakS?!1:(q(t,!1,o&&o.quiet?"quiet":"live",s),!0)},rebreak:function(e){const o=a.get(e);return!o||!o.fixed||y?!1:(R(o),!0)},toolFor:function(e){const o=k(e);return o&&o.tool?{id:o.tool,name:o.toolName}:null},brokenNear:function(e,o,t){const s=[];return a.forEach(function(i){if(i.fixed||!i.object3d)return;const n=i.object3d.getWorldPosition(new E.Vector3),f=Math.hypot(n.x-e,n.z-o);f<=t&&s.push({nodeId:i.nodeId,x:n.x,y:n.y,z:n.z,cost:i.cost||0,label:i.label||"",d:f})}),s.sort(function(i,n){return i.d-n.d}),s},work:function(e,o,t,s,i){const n=k(e);if(!n||n.fixed||!(o>0)||y)return!1;const f=!!(i&&i.anyTool),u=i&&i.payMul>0?i.payMul:1;if(n.tool&&!f&&!ne(n.tool,s,n.toolSkills))return n.wrongUntil=performance.now()+c,p(n),clearTimeout(n.deniedTimer),n.deniedTimer=setTimeout(function(){p(n)},c+20),t&&w().event("repair",{id:n.nodeId,wrong:!0,skill:s||""}),"wrongTool";n.wrongUntil&&(n.wrongUntil=0);const M=S(n);if(n.progress>=M)return n.cappedUntil=performance.now()+c,p(n),clearTimeout(n.deniedTimer),n.deniedTimer=setTimeout(function(){p(n)},c+20),"capped";n.cappedUntil&&(n.cappedUntil=0);const z=n.cost>0?u===1?n.cost:Math.max(1,Math.round(n.cost*u)):0;return t&&z>0&&O&&!O(z,e)?(w().event("repair",{id:n.nodeId,unpaid:!0,cost:z,skill:s||""}),n.deniedUntil=performance.now()+c,p(n),clearTimeout(n.deniedTimer),n.deniedTimer=setTimeout(function(){p(n)},c+20),"unpaid"):(n.deniedUntil&&(n.deniedUntil=0,clearTimeout(n.deniedTimer)),t&&n.share>0&&D&&D(n.nodeId,n.share,n.work),n.progress=Math.min(M,n.progress+(n.perHit>0?n.perHit:Math.round(o))),H&&H(n.nodeId,n.progress,n.work),n.jolt=G,t&&w().event("repair",{id:n.nodeId,done:n.progress,of:n.work,cost:n.cost||0,skill:s||""}),t&&(n.helped=!0),n.lookDoc&&!n.preloaded&&l.preloadNode&&(n.preloaded=!0,l.preloadNode(n.lookDoc)),(!l.playNodeEvent||!l.playNodeEvent(e,"hit",1))&&l.playEventDefault("collide"),n.progress>=n.work?(q(n,t),"fixed"):(p(n),"progress"))},update:function(e){a.forEach(function(o){if(o.smoke&&(o.smoke.update(e),o.smokeFade>0&&(o.smokeFade-=e,o.smokeFade<=0&&b(o))),o.jolt>0){o.jolt=Math.max(0,o.jolt-e);const t=o.jolt/G,s=1+.09*Math.sin((1-t)*Math.PI*3)*t;o.object3d.scale.set(o.baseScale.x*(2-s),o.baseScale.y*s,o.baseScale.z*(2-s)),o.jolt===0&&o.object3d.scale.copy(o.baseScale)}o.fixed&&o.rebreakS>0&&(o.fixedFor+=e,o.fixedFor>=o.rebreakS&&R(o))});for(let o=h.length-1;o>=0;o--){const t=h[o];t.t+=e,t.e.update(e),t.t>2.2&&(x.remove(t.e.points),t.e.dispose(),h.splice(o,1))}},project:function(){const e=performance.now();let o=null;a.forEach(function(t){if(!t.el)return;if(d.set(t.x,t.y,t.z).project(A),d.z>1||d.z<-1){t.el.style.opacity="0";return}o||(o=se(F));const s=(d.x*.5+.5)*o.w,i=(-d.y*.5+.5)*o.h,n=A.position.distanceTo(d.set(t.x,t.y,t.z));let f=n>=V?0:n<=v?1:1-(n-v)/(V-v);!t.fixed&&t.progress===0&&T&&(Math.hypot(T.x-t.x,T.z-t.z)<=ae||(f=0)),f>0&&(t.sizeAt==null||e-t.sizeAt>re)&&(t.w=t.el.offsetWidth,t.h=t.el.offsetHeight,t.sizeAt=e),le(s,i,t.w,t.h,o)||(f=0);const u=t.w!=null?ie(s,i,t.w,t.h,o):{x:s,y:i};t.el.style.left=u.x.toFixed(1)+"px",t.el.style.top=u.y.toFixed(1)+"px",t.el.style.opacity=f.toFixed(2)})},probe:function(){const e=[];return a.forEach(function(o){e.push({id:o.nodeId,progress:o.progress,work:o.work,fixed:o.fixed,helped:o.helped,cost:o.cost,tool:o.tool,share:o.share||void 0,cap:o.capBy?S(o):void 0,look:!!(o.lookDoc&&l.byId.has(o.lookDoc.id))})}),e},dispose:function(){y=!0,a.forEach(W);for(const e of h)x.remove(e.e.points),e.e.dispose();h.length=0}}}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.