@vimp-games/tanks 0.3.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/vimp_tanks_core_bg-CBFWntTH.wasm +0 -0
- package/dist/client-p02A9z6v.js +1 -0
- package/dist/core-node/package.json +17 -0
- package/dist/core-node/vimp_tanks_core.d.ts +231 -0
- package/dist/core-node/vimp_tanks_core.js +754 -0
- package/dist/core-node/vimp_tanks_core_bg.wasm +0 -0
- package/dist/core-node/vimp_tanks_core_bg.wasm.d.ts +57 -0
- package/dist/host-Da03_6hx.js +1 -0
- package/dist/manifest.json +6 -5
- package/dist/maps/garden.json +1 -1
- package/package.json +7 -5
- package/dist/assets/vimp_tanks_core_bg-6JRQcDoQ.wasm +0 -0
- package/dist/client-CWmsSKHE.js +0 -1
- package/dist/host-YfBWvsMD.js +0 -1
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{Container as C,Assets as H,Sprite as I,Spritesheet as ct,Rectangle as M,Graphics as T,Text as lt,Ticker as P,Particle as dt,ParticleContainer as at,BlurFilter as $}from"pixi.js";const _t=3;class Z{__destroy_into_raw(){const t=this.__wbg_ptr;return this.__wbg_ptr=0,tt.unregister(this),t}free(){const t=this.__destroy_into_raw();d.__wbg_clientcore_free(t,0)}apply_input(t,e,i){const s=F(t,d.__wbindgen_malloc,d.__wbindgen_realloc),o=D,r=F(e,d.__wbindgen_malloc,d.__wbindgen_realloc),a=D;d.clientcore_apply_input(this.__wbg_ptr,s,o,r,a,i)}cycle_weapon(t){d.clientcore_cycle_weapon(this.__wbg_ptr,t)}debug_json(){let t,e;try{const i=d.clientcore_debug_json(this.__wbg_ptr);return t=i[0],e=i[1],L(i[0],i[1])}finally{d.__wbindgen_free(t,e,1)}}decode_frame(t){let e,i;try{const s=et(t,d.__wbindgen_malloc),o=D,r=d.clientcore_decode_frame(this.__wbg_ptr,s,o);return e=r[0],i=r[1],L(r[0],r[1])}finally{d.__wbindgen_free(e,i,1)}}hot_ptr(){return d.clientcore_hot_ptr(this.__wbg_ptr)>>>0}hot_values(){const t=d.clientcore_hot_values(this.__wbg_ptr);var e=pt(t[0],t[1]).slice();return d.__wbindgen_free(t[0],t[1]*4,4),e}my_game_id(){return d.clientcore_my_game_id(this.__wbg_ptr)}constructor(t){const e=F(t,d.__wbindgen_malloc,d.__wbindgen_realloc),i=D,s=d.clientcore_new(e,i);if(s[2])throw it(s[1]);return this.__wbg_ptr=s[0],tt.register(this,this.__wbg_ptr,this),this}offset(){return d.clientcore_offset(this.__wbg_ptr)}push_frame(t,e){const i=et(t,d.__wbindgen_malloc),s=D;return d.clientcore_push_frame(this.__wbg_ptr,i,s,e)!==0}reset(){d.clientcore_reset(this.__wbg_ptr)}sample(t){return d.clientcore_sample(this.__wbg_ptr,t)>>>0}set_active(t){d.clientcore_set_active(this.__wbg_ptr,t)}set_map(t){const e=F(t,d.__wbindgen_malloc,d.__wbindgen_realloc),i=D,s=d.clientcore_set_map(this.__wbg_ptr,e,i);if(s[1])throw it(s[0])}set_model(t){const e=F(t,d.__wbindgen_malloc,d.__wbindgen_realloc),i=D;d.clientcore_set_model(this.__wbg_ptr,e,i)}sync_panel(t){const e=F(t,d.__wbindgen_malloc,d.__wbindgen_realloc),i=D;d.clientcore_sync_panel(this.__wbg_ptr,e,i)}take_divergence(){let t,e;try{const i=d.clientcore_take_divergence(this.__wbg_ptr);return t=i[0],e=i[1],L(i[0],i[1])}finally{d.__wbindgen_free(t,e,1)}}take_frames(){let t,e;try{const i=d.clientcore_take_frames(this.__wbg_ptr);return t=i[0],e=i[1],L(i[0],i[1])}finally{d.__wbindgen_free(t,e,1)}}try_fire(t){const e=d.clientcore_try_fire(this.__wbg_ptr,t);let i;return e[0]!==0&&(i=L(e[0],e[1]).slice(),d.__wbindgen_free(e[0],e[1]*1,1)),i}}Symbol.dispose&&(Z.prototype[Symbol.dispose]=Z.prototype.free);function ut(){return{__proto__:null,"./vimp_tanks_core_bg.js":{__proto__:null,__wbg_Error_92b29b0548f8b746:function(t,e){return Error(L(t,e))},__wbg___wbindgen_throw_344f42d3211c4765:function(t,e){throw new Error(L(t,e))},__wbindgen_init_externref_table:function(){const t=d.__wbindgen_externrefs,e=t.grow(4);t.set(0,void 0),t.set(e+0,void 0),t.set(e+1,null),t.set(e+2,!0),t.set(e+3,!1)}}}}const tt=typeof FinalizationRegistry>"u"?{register:()=>{},unregister:()=>{}}:new FinalizationRegistry(n=>d.__wbg_clientcore_free(n,1));typeof FinalizationRegistry>"u"||new FinalizationRegistry(n=>d.__wbg_gamecore_free(n,1));function pt(n,t){return n=n>>>0,ft().subarray(n/4,n/4+t)}let O=null;function ft(){return(O===null||O.byteLength===0)&&(O=new Float32Array(d.memory.buffer)),O}function L(n,t){return gt(n>>>0,t)}let N=null;function U(){return(N===null||N.byteLength===0)&&(N=new Uint8Array(d.memory.buffer)),N}function et(n,t){const e=t(n.length*1,1)>>>0;return U().set(n,e/1),D=n.length,e}function F(n,t,e){if(e===void 0){const a=W.encode(n),c=t(a.length,1)>>>0;return U().subarray(c,c+a.length).set(a),D=a.length,c}let i=n.length,s=t(i,1)>>>0;const o=U();let r=0;for(;r<i;r++){const a=n.charCodeAt(r);if(a>127)break;o[s+r]=a}if(r!==i){r!==0&&(n=n.slice(r)),s=e(s,i,i=r+n.length*3,1)>>>0;const a=U().subarray(s+r,s+i),c=W.encodeInto(n,a);r+=c.written,s=e(s,i,r,1)>>>0}return D=r,s}function it(n){const t=d.__wbindgen_externrefs.get(n);return d.__externref_table_dealloc(n),t}let q=new TextDecoder("utf-8",{ignoreBOM:!0,fatal:!0});q.decode();const mt=2146435072;let j=0;function gt(n,t){return j+=t,j>=mt&&(q=new TextDecoder("utf-8",{ignoreBOM:!0,fatal:!0}),q.decode(),j=t),q.decode(U().subarray(n,n+t))}const W=new TextEncoder;"encodeInto"in W||(W.encodeInto=function(n,t){const e=W.encode(n);return t.set(e),{read:n.length,written:e.length}});let D=0,d;function yt(n,t){return d=n.exports,O=null,N=null,d.__wbindgen_start(),d}async function xt(n,t){if(typeof Response=="function"&&n instanceof Response){if(typeof WebAssembly.instantiateStreaming=="function")try{return await WebAssembly.instantiateStreaming(n,t)}catch(s){if(n.ok&&e(n.type)&&n.headers.get("Content-Type")!=="application/wasm")console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve Wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n",s);else throw s}const i=await n.arrayBuffer();return await WebAssembly.instantiate(i,t)}else{const i=await WebAssembly.instantiate(n,t);return i instanceof WebAssembly.Instance?{instance:i,module:n}:i}function e(i){switch(i){case"basic":case"cors":case"default":return!0}return!1}}async function wt(n){if(d!==void 0)return d;n!==void 0&&(Object.getPrototypeOf(n)===Object.prototype?{module_or_path:n}=n:console.warn("using deprecated parameters for the initialization function; pass a single object instead")),n===void 0&&(n=new URL("/assets/vimp_tanks_core_bg-CBFWntTH.wasm",import.meta.url));const t=ut();(typeof n=="string"||typeof Request=="function"&&n instanceof Request||typeof URL=="function"&&n instanceof URL)&&(n=fetch(n));const{instance:e,module:i}=await xt(await n,t);return yt(e)}const St='@charset "UTF-8";#panel table td#panel-bullet:before{content:"bullet: "}#panel table td#panel-bomb:before{content:"bomb: "}#panel table td#panel-time:before{content:"time: "}#vimp{background:#222;position:absolute;inset:0;margin:auto;z-index:1}#radar{position:absolute;right:1%;top:35px;z-index:2;border-radius:50%;background-color:#00be5acc;box-shadow:inset 0 0 47px #ee6,0 0 0 3px #054}#team1{color:#f56}#team2{color:#7ed}#spectators{color:#fe5}#team1 tHead tr,#team2 tHead tr,#spectators tHead tr{border-bottom:1px solid #888;text-transform:capitalize;font-weight:700}#team1 tBody tr,#team2 tBody tr{border-bottom:1px solid #444}#team1 tHead td:first-child:before{content:"team1 ("}#team1 tHead td:first-child:after{content:")"}#team2 tHead td:first-child:before{content:"team2 ("}#team2 tHead td:first-child:after{content:")"}#spectators tHead td:first-child:before{content:"spectators"}#spectators tBody td:nth-child(1){padding:0 1%;line-height:1.4em}#spectators tBody td:nth-child(2),#spectators tBody td:nth-child(3),#spectators tBody td:nth-child(4),#spectators tBody td:nth-child(5){display:none}',k=(n,t,e)=>n+(t-n)*e,Q=(n,t,e)=>Math.min(e,Math.max(t,n)),bt=n=>n*(Math.PI/180),Tt=n=>{for(;n>Math.PI;)n-=Math.PI*2;for(;n<-Math.PI;)n+=Math.PI*2;return n},v=(n,t)=>Math.random()*(t-n)+n;class Mt extends C{constructor(t,e,i){super(),this._baseTexturePromise=null,this._assetUrl=null,this._renderer=i.renderer,this.scale=t.scale,this.sprite=null,this.mapSprite=null,t.type==="static"?(this._assetUrl=`/img/${t.spriteSheet.img}`,this._baseTexturePromise=H.load(this._assetUrl),this._map=t.map,this._tiles=t.tiles,this._spriteSheetData=t.spriteSheet,this._step=t.step,this.zIndex=t.layer||1,this.createStatic()):t.type==="dynamic"&&(this._assetUrl=`/img/${t.img}`,this._baseTexturePromise=H.load(this._assetUrl),this.zIndex=t.layer||2,this._rotation=bt(t.angle),this._width=t.width,this._height=t.height,this._x=t.position[0],this._y=t.position[1],this.createDynamic())}async createDynamic(){try{const t=await this._baseTexturePromise;this.sprite=new I(t),this.sprite.x=this._x,this.sprite.y=this._y,this.sprite.width=this._width,this.sprite.height=this._height,this.sprite.rotation=this._rotation,this.addChild(this.sprite)}catch(t){console.error(`Failed to create dynamic map with asset ${this._assetUrl}:`,t)}}async createStatic(){try{const t={};this._spriteSheetData.frames.forEach((h,f)=>{const[_,m,u,g]=h;t[`frame${f}`]={frame:{x:_,y:m,w:u,h:g}}});const e={frames:t,meta:{scale:"1"}},i=await this._baseTexturePromise,s=new ct(i,e);await s.parse();const o=this._map[0].length*this._step,r=this._map.length*this._step,a=new C;for(let h=0,f=this._map.length;h<f;h+=1)for(let _=0,m=this._map[h].length;_<m;_+=1){const u=this._map[h][_];if(this._tiles.includes(u)){const g=`frame${u}`,p=s.textures[g];if(p){const y=new I(p);y.x=_*this._step,y.y=h*this._step,a.addChild(y)}else console.warn(`Texture not found. Tile: ${u}, sprite: ${g}`)}}const c=this._renderer.generateTexture({target:a,frame:new M(0,0,o,r)});a.destroy({children:!0}),this.mapSprite=new I(c),this.addChild(this.mapSprite)}catch(t){console.error(`Failed to create static map with asset ${this._assetUrl}:`,t)}}update(t){this.sprite&&(this.sprite.x=t[0]/this.scale.x,this.sprite.y=t[1]/this.scale.y,this.sprite.rotation=t[2])}destroy(t){this.mapSprite&&(this.mapSprite.destroy({children:!0,texture:!0,textureSource:!0}),this.mapSprite=null),super.destroy({children:!0,texture:!1,textureSource:!1,...t}),this._assetUrl&&H.cache.has(this._assetUrl)&&H.unload(this._assetUrl).catch(e=>console.warn(`Failed to unload asset ${this._assetUrl} (was in cache):`,e)),this.sprite=null,this._baseTexturePromise=null,this._assetUrl=null,this._map=null,this._tiles=null,this._spriteSheetData=null,this._renderer=null}}class kt extends C{constructor(t){super(),this._map=t.map,this._physicsStatic=t.physicsStatic,this._step=t.step,this.zIndex=2,this.scale=t.scale,this.radarGraphics=new T,this.addChild(this.radarGraphics),this.createRadarMap()}createRadarMap(){const t=this.radarGraphics;if(t.clear(),Array.isArray(this._map))for(let e=0;e<this._map.length;e+=1){const i=this._map[e];if(Array.isArray(i))for(let s=0;s<i.length;s+=1){const o=i[s];this._physicsStatic.includes(o)&&t.rect(s*this._step,e*this._step,this._step/2,this._step/2)}}t.fill(16777215)}update(){}destroy(t){super.destroy({children:!0,texture:!1,textureSource:!1,...t}),this.radarGraphics=null,this._map=null,this._physicsStatic=null}}class vt extends C{constructor(t,e){super(),this.zIndex=2,this._textures=e.tankRadarTexture,this.body=new I,this.body.anchor.set(.5),this.addChild(this.body),this.x=t[0]||0,this.y=t[1]||0,this._condition=t[7],this._teamId=t[9],this.scale.set(5,5),this.create()}create(){this._condition===0?this.body.texture=this._textures.destroyed:this._teamId===1?this.body.texture=this._textures.liveTeamId1:this._teamId===2&&(this.body.texture=this._textures.liveTeamId2)}update(t){this.x=t[0],this.y=t[1];const e=t[7],i=t[9];let s=!1;e!==void 0&&e!==this._condition&&(this._condition=e,s=!0),i!==void 0&&i!==this._teamId&&(this._teamId=i,s=!0),s&&this.create()}destroy(t){super.destroy({children:!0,texture:!1,textureSource:!1,...t}),this.body=null,this._textures=null}}const It=1,st=1.1,Ct=1.18,Dt=.9,At=1;function Pt(n){const t=Q(n,0,1),e=Math.max(0,n-1),i=k(It,st,t)+(Ct-st)*e,s=k(Dt,At,t);return{rate:i,volumeFactor:s}}class Et extends C{constructor(t,e,i){super(),this.zIndex=3,this.body=new I,this.gun=new I,this.wreck=new I,this.body.anchor.set(.5),this.wreck.anchor.set(.5),this.addChild(this.body,this.gun,this.wreck),this._textures=e.tankTexture,this.x=t[0]||0,this.y=t[1]||0,this.rotation=t[2]||0,this.gun.rotation=t[3]||0,this._engineLoad=t[6]||0,this._condition=t[7],this._size=t[8],this._teamId=t[9];const s=this._teamId===1?this._textures.liveTeamId1:this._textures.liveTeamId2,o=s?s.gunAnchor:null;o?this.gun.anchor.set(o.x,o.y):this.gun.anchor.set(.5);const a=this._size/10;this.body.scale.set(a),this.gun.scale.set(a),this.wreck.scale.set(a),this._soundManager=i.soundManager,this._soundId=null;const c=this._soundManager.getSoundConfig("tankEngine")||{};this._baseEngineVolume=c.volume||0,this.create()}_initSounds(){this._soundId||this._condition===0||(this._soundId=this._soundManager.registerSound("tankEngine",this._getSoundData()))}_getSoundData(){const{rate:t,volumeFactor:e}=Pt(this._engineLoad);return{position:{x:this.x,y:this.y},rate:t,volume:this._baseEngineVolume*e}}create(){if(this._condition===0)this.body.visible=!1,this.gun.visible=!1,this.wreck.texture=this._textures.destroyed,this.wreck.visible=!0,this.gun.rotation=0,this.destroySounds();else{this.wreck.visible=!1;let t;this._teamId===1?t=this._textures.liveTeamId1:this._teamId===2&&(t=this._textures.liveTeamId2),this.body.texture=t.body,this.gun.texture=t.gun,this.body.visible=!0,this.gun.visible=!0,this._initSounds()}}update(t){this.x=t[0],this.y=t[1],this.rotation=t[2],this.gun.rotation=t[3],this._engineLoad=t[6],this._soundId&&this._condition>0&&this._soundManager.updateSoundData(this._soundId,this._getSoundData());const e=t[7],i=t[9];let s=!1;e!==void 0&&e!==this._condition&&(this._condition=e,s=!0),i!==void 0&&i!==this._teamId&&(this._teamId=i,s=!0),s&&this.create()}destroySounds(){this._soundId&&(this._soundManager.unregisterSound(this._soundId),this._soundId=null)}destroy(t){this.destroySounds(),super.destroy({children:!0,texture:!1,textureSource:!1,...t})}}class Rt extends C{constructor(t,e,i){super(),this.zIndex=2,this.body=new I(e.bombTexture),this.body.anchor.set(.5),this.x=t[0],this.y=t[1],this.rotation=t[2],this._size=t[3],this._totalDurationMs=t[4],this._soundManager=i.soundManager,this._soundId=null;const s=e.bombTexture.width,o=this._size/s;this.body.scale.set(o);const r=64,a=this._size/1.2/r;this.text=new lt({style:{fontFamily:"Arial",fontSize:r,fill:16777215,align:"center"}}),this.text.anchor.set(.5),this.text.scale.set(a),this.text.x=0,this.text.y=0,this._accumulatedTimeMs=0,this._secondsLeft="",this.addChild(this.body,this.text),this._updateTimerDisplay(this._totalDurationMs),this._tickListener=c=>this._updateTimer(c.deltaMS),P.shared.add(this._tickListener),this._soundId=this._soundManager.registerSound("bombHasBeenPlanted",{position:{x:this.x,y:this.y}})}_updateTimer(t){this._accumulatedTimeMs+=t;const e=Math.max(0,this._totalDurationMs-this._accumulatedTimeMs);this._updateTimerDisplay(e),e<=0&&(this._stopTimer(),this._updateTimerDisplay(0))}_updateTimerDisplay(t){const e=Math.round(t/1e3);this._secondsLeft!==e&&(this._secondsLeft=e,this.text.text=`${this._secondsLeft}`)}update(){}_stopTimer(){this._tickListener&&(P.shared.remove(this._tickListener),this._tickListener=null)}destroy(t){this._stopTimer(),this._soundId&&(this._soundManager.unregisterSound(this._soundId),this._soundId=null),super.destroy({children:!0,texture:!1,textureSource:!1,...t}),this.body=null,this.text=null}}class V extends C{constructor(t){super(),this._tickListener=null,this._isStarted=!1,this.isComplete=!1,this.onComplete=t}run(){this.isComplete||this._isStarted||(this._isStarted=!0,this._tickListener=t=>this._update(t.deltaMS),P.shared.add(this._tickListener),this._onEffectStart(),this.isComplete||this._update(0))}_onEffectStart(){}_update(){}_completeEffect(){this.isComplete||(this.isComplete=!0,this._tickListener&&(P.shared.remove(this._tickListener),this._tickListener=null),typeof this.onComplete=="function"&&this.onComplete())}destroy(t){this.isComplete=!0,this._tickListener&&(P.shared.remove(this._tickListener),this._tickListener=null),this.parent&&this.parent.removeChild(this),super.destroy({texture:!1,textureSource:!1,...t,children:!0})}}const nt=50;class Lt extends V{constructor(t,e,i,s,o){super(s);const r=o.explosionTexture;this.x=t,this.y=e,this._radius=i,this._durationMs=3e3,this._elapsedMs=0;const a=this._radius/nt;this._mainBody=new I(r),this._mainBody.anchor.set(.5),this._mainBody.tint=11393254,this._mainBody.scale.set(a),this._core=new I(r),this._core.anchor.set(.5),this._core.tint=13882323,this._core.scale.set(a),this.addChild(this._mainBody,this._core)}_update(t){if(!this.isComplete)if(this._elapsedMs+=t,this._elapsedMs<=this._durationMs){const e=this._elapsedMs/this._durationMs;this._draw(e)}else this._completeEffect()}_draw(t){const e=o=>o*o,i=this._radius/nt;this._mainBody.alpha=.6*(1-e(t));const s=Math.min(1,t*1.5);this._core.alpha=.7-s,this._core.scale.set(i*(1-s))}destroy(t){super.destroy(t)}}const K=[],Y={get(n){if(K.length>0){const t=K.pop();return t.texture=n,t.alpha=1,t.scaleX=1,t.scaleY=1,t.rotation=0,t.tint=16777215,t.anchorX=.5,t.anchorY=.5,t}return new dt({texture:n,anchorX:.5,anchorY:.5})},release(n){n&&K.push(n)}},rt=400,ot=800;class Ft extends V{constructor(t){super(),this.explosionTexture=t.explosionTexture,this._particleContainer=new at({texture:this.explosionTexture,boundsArea:new M(-rt/2,-ot/2,rt,ot),dynamicProperties:{position:!0,vertex:!0,rotation:!0,color:!0}}),this.addChild(this._particleContainer),this._particles=[],this._isSpawning=!0,this._particleSpawnRateMs=50,this._particleMaxLifeMs=2e3,this._minStartScale=.02,this._maxStartScale=.05,this._startAlpha=.1,this._initialOffsetX=15,this._initialOffsetY=15,this._lastSpawnTime=0;for(let e=0;e<30;e+=1)this._createParticle()}stopSpawning(){this._isSpawning=!1}_createParticle(){const t=Y.get(this.explosionTexture),e=.2+Math.random()*.4,i=Math.floor(e*255);t.tint=i<<16|i<<8|i;const s=this._minStartScale+Math.random()*(this._maxStartScale-this._minStartScale),o=.6+Math.random()*.8,r=.6+Math.random()*.8;t.scaleX=s*o,t.scaleY=s*r,t.alpha=this._startAlpha+Math.random()*.1,t.rotation=Math.random()*Math.PI*2,t.x=(Math.random()-.5)*this._initialOffsetX,t.y=(Math.random()-.5)*this._initialOffsetY;const a={view:t,life:0,maxLife:this._particleMaxLifeMs*(.7+Math.random()*.6),aspectRatioX:o,aspectRatioY:r,vx:(Math.random()-.5)*.2,vy:-.3-Math.random()*.4,swaySpeed:.002+Math.random()*.003,swayAmp:.025+Math.random()*.05,swayOffset:Math.random()*100,rotationSpeed:(Math.random()-.5)*.05,targetScale:.08+Math.random()*.08,startScale:s};this._particleContainer.addParticle(t),this._particles.push(a)}_update(t){if(!this.isComplete){if(t=Math.min(t,100),this._isSpawning)for(this._lastSpawnTime+=t;this._lastSpawnTime>this._particleSpawnRateMs;)this._createParticle(),this._lastSpawnTime-=this._particleSpawnRateMs;for(let e=this._particles.length-1;e>=0;e-=1){const i=this._particles[e],s=i.view;if(i.life+=t,i.life>=i.maxLife)this._particleContainer.removeParticle(s),Y.release(s),this._particles.splice(e,1);else{const o=i.life/i.maxLife;i.vy*=.98,i.vx*=.95;const r=Math.sin(i.life*i.swaySpeed+i.swayOffset)*i.swayAmp;s.x+=(i.vx+r)*(t/16),s.y+=i.vy*(t/16),s.rotation+=i.rotationSpeed*(t/16);const a=1-Math.pow(1-o,3),c=i.startScale+(i.targetScale-i.startScale)*a;if(s.scaleX=c*i.aspectRatioX,s.scaleY=c*i.aspectRatioY,o<.1)s.alpha=o/.1*this._startAlpha;else if(o>.4){const h=(o-.4)/.6;s.alpha=this._startAlpha*(1-h)}else s.alpha=this._startAlpha}}!this._isSpawning&&this._particles.length===0&&this._isStarted&&(this._completeEffect(),this.destroyed||this.destroy())}}destroy(t){for(let e=0;e<this._particles.length;e+=1)Y.release(this._particles[e].view);this._particles=[],super.destroy(t)}}const Xt=50,Yt=15;class zt extends V{constructor(t,e,i,s){super(i),this._assets=s,this.x=t,this.y=e,this._funnelDurationMs=2e4,this._funnelFadeDurationMs=4e3,this._elapsedMs=0,this._isFading=!1,this._smokeDurationMs=4e3,this._smokeSpawningStopped=!1,this._funnel=this._createFunnelSprite(),this._smoke=new Ft(this._assets),this.addChild(this._funnel,this._smoke)}_createFunnelSprite(){const t=this._assets.funnelTexture,e=new I(t);e.anchor.set(.5),e.tint=3815994;const i=Yt/(Xt*2);return e.scale.set(i),e}_onEffectStart(){super._onEffectStart(),this._smoke&&this._smoke.run()}_update(t){if(this.isComplete)return;this._elapsedMs+=t,!this._smokeSpawningStopped&&this._elapsedMs>=this._smokeDurationMs&&(this._smoke.stopSpawning(),this._smokeSpawningStopped=!0);const e=this._funnelDurationMs-this._elapsedMs;if(e<=this._funnelFadeDurationMs){this._isFading||(this._isFading=!0);const i=e/this._funnelFadeDurationMs;this._funnel.alpha=Math.max(0,i)}e<=0&&this._completeEffect()}destroy(t){this._smoke&&(this._smoke.destroy(),this._smoke=null),this._funnel=null,super.destroy(t)}}class Bt extends C{constructor(t,e,i){super(),this.originX=t[0],this.originY=t[1],this.radius=t[2],this._assets=e,this._soundManager=i.soundManager,this.x=this.originX,this.y=this.originY,this.explosion=null,this.funnel=null,this._isDestroyed=!1,this._soundId=this._soundManager.registerSound("explosion",{position:{x:this.originX,y:this.originY}})}run(){if(this._isDestroyed)return;const t=this.parent;this.funnel=new zt(this.originX,this.originY,this._onFunnelComplete.bind(this),this._assets),this.funnel.zIndex=2,t.addChild(this.funnel),this.explosion=new Lt(this.originX,this.originY,this.radius,this._onExplosionComplete.bind(this),this._assets),this.explosion.zIndex=4,t.addChild(this.explosion),this.funnel.run(),this.explosion.run()}_onExplosionComplete(){this._isDestroyed||this.explosion&&(this.explosion.destroy(),this.explosion=null)}_onFunnelComplete(){this._isDestroyed||this.destroy()}destroy(){this._isDestroyed||(this._isDestroyed=!0,this._soundId&&(this._soundManager.unregisterSound(this._soundId),this._soundId=null),this.explosion&&(this.explosion.destroy(),this.explosion=null),this.funnel&&(this.funnel.destroy(),this.funnel=null),this.parent&&this.parent.removeChild(this),super.destroy({children:!0}))}}const X=400,Ot=0,Nt=0,b={particleLifetime:{min:800,max:1800},particleStartSizeFactor:{1:2,2:1,0:.25},particleEndSizeFactor:{1:3,2:2,0:1},particleStartAlpha:.08,particleEndAlpha:0,particleColor:3355443,particleSpawnRate:{1:60,2:50,0:30},particleInitialVelocity:{away:{min:-10,max:100},side:{min:-30,max:30}},airResistance:.92,particleVelocityVariance:10,streamOffsetFactor:.1,burstParticleCount:3};class Ut extends C{constructor(t,e){super(),this.zIndex=4,this._smokeTexture=e.smokeTexture,this._emitterX=t[0],this._emitterY=t[1],this._emitterRotation=t[2],this._emitterVX=t[4],this._emitterVY=t[5],this._engineLoad=t[6],this._condition=t[7],this._size=t[8],this._width=this._size*4,this._height=this._size*3,this._particleScaleMultiplier=Math.max(.5,Math.sqrt(this._width*this._height*.001)),this._particles=[],this._particleContainer=new at({texture:this._smokeTexture,boundsArea:new M(this._emitterX-X,this._emitterY-X,X*2,X*2),dynamicProperties:{position:!0,vertex:!0,rotation:!0,color:!0}}),this.addChild(this._particleContainer),this._timeSinceLastSpawn=0,this._tickListener=i=>this._updateParticles(i.deltaMS),P.shared.add(this._tickListener)}update(t){const e=this._condition;this._emitterX=t[0],this._emitterY=t[1],this._emitterRotation=t[2],this._emitterVX=t[4],this._emitterVY=t[5],this._engineLoad=t[6],this._condition=t[7],this._particleContainer.boundsArea.x=this._emitterX-X,this._particleContainer.boundsArea.y=this._emitterY-X,this._condition!==e&&this._condition!==3&&this._triggerSmokeBurst()}_triggerSmokeBurst(){let t=0;if(this._condition===1?t=2:(this._condition===2||this._condition===0)&&(t=1),t>0){const e=b.burstParticleCount,i=Math.ceil(e/t);for(let s=0;s<i;s+=1)for(let o=0;o<t;o+=1)this.spawnParticle(o,t,!0)}}_updateParticles(t){if(t<=0)return;const e=t/1e3;this._timeSinceLastSpawn+=t;let i=0;this._condition===3?i=0:this._condition===1?i=2:(this._condition===2||this._condition===0)&&(i=1);const s=b.particleSpawnRate[this._condition]||0,o=s>0?1e3/s:1/0;if(i>0&&s>0)for(;this._timeSinceLastSpawn>=o;){for(let c=0;c<i;c+=1)this.spawnParticle(c,i);this._timeSinceLastSpawn-=o}else this._timeSinceLastSpawn=0;const a=1-Math.pow(b.airResistance,t/16);for(let c=this._particles.length-1;c>=0;c-=1){const h=this._particles[c];if(h.age+=t,h.age>=h.lifetime){this._particleContainer.removeParticle(h.view),Y.release(h.view),this._particles.splice(c,1);continue}h.vx=h.vx+(Ot-h.vx)*a,h.vy=h.vy+(Nt-h.vy)*a,h.x+=h.vx*e,h.y+=h.vy*e;const f=h.age/h.lifetime,_=1-(1-f)*(1-f),m=k(h.startSizeFactor,h.endSizeFactor,_),u=k(h.startAlpha,h.endAlpha,f),g=m*this._particleScaleMultiplier,p=h.view;p.x=h.x,p.y=h.y,p.scaleX=g,p.scaleY=g,p.alpha=u,p.rotation+=h.rotSpeed*e}}spawnParticle(t,e,i=!1){const s=v(b.particleLifetime.min,b.particleLifetime.max);let o=b.particleStartSizeFactor[this._condition]||.3,r=b.particleEndSizeFactor[this._condition]||1,a=b.particleStartAlpha,c=1;i&&(o*=2,r*=2.5,a=.8,c=2);const h=this._emitterRotation,f=h+Math.PI,_=Math.cos(f),m=Math.sin(f),u=h+Math.PI/2,g=Math.cos(u),p=Math.sin(u);let y=0;const x=this._width/2*b.streamOffsetFactor;e===2?y=t===0?-x:x:e===3&&(y=(t-1)*x);const w=this._height*.22,S=this._emitterX+_*w+g*y,l=this._emitterY+m*w+p*y;let R=v(b.particleInitialVelocity.away.min,b.particleInitialVelocity.away.max),z=v(b.particleInitialVelocity.side.min,b.particleInitialVelocity.side.max);R*=c,z*=c;let E=_*R+g*z,B=m*R+p*z;const G=b.particleVelocityVariance;E+=v(-G,G),B+=v(-G,G),E+=this._emitterVX,B+=this._emitterVY;const A=Y.get(this._smokeTexture);A.tint=b.particleColor,A.x=S,A.y=l,A.alpha=a;const J=o*this._particleScaleMultiplier;A.scaleX=J,A.scaleY=J,A.rotation=v(0,Math.PI*2);const ht={view:A,x:S,y:l,vx:E,vy:B,age:0,lifetime:s,startSizeFactor:o,endSizeFactor:r,startAlpha:a,endAlpha:b.particleEndAlpha,rotSpeed:v(-1,1)};this._particleContainer.addParticle(A),this._particles.push(ht)}_stopTimer(){this._tickListener&&(P.shared.remove(this._tickListener),this._tickListener=null)}destroy(t){this._stopTimer();for(let e=0;e<this._particles.length;e+=1)Y.release(this._particles[e].view);this._particles=[],super.destroy({texture:!1,textureSource:!1,...t,children:!0})}}class Wt extends I{constructor(t,e,i,s,o,r,a){super(a),this.anchor.set(.5),this.x=t,this.y=e,this.rotation=i,this.width=o,this.height=s,this.alpha=r,this._initialAlpha=r,this._elapsedTime=0,this._fadeDuration=1800+Math.random()*700}update(t){this._elapsedTime+=t;const e=Math.min(this._elapsedTime/this._fadeDuration,1);return this.alpha=(1-e)*this._initialAlpha,e>=1}}class Vt extends C{constructor(t,e){super(),this.zIndex=1,this._currentX=t[0]||0,this._currentY=t[1]||0,this._currentRotation=t[2]||0,this._engineLoad=t[6]||0,this._condition=t[7],this._size=t[8],this._prevX=this._currentX,this._prevY=this._currentY,this._prevRotation=this._currentRotation,this._prevSpeed=0,this._prevAngularSpeed=0,this._assets=e,this._trackMarkCooldown=2,this._lastTrackMarkTime=0,this._minAbsAccelerationForMark=4,this._minAngularSpeedForMark=.02,this._minRotationAccelerationForMark=.4,this._minSpeedForRotationMarks=1.4,this._trackWidth=this._size*.4,this._trackLength=this._size*.5;const i=this._size*3;this._trackOffset=i/2*.7,this._backwardOffset=i*.4,this._trackInitialAlpha=.4,this._tickListener=s=>this._internalUpdate(s.deltaMS),P.shared.add(this._tickListener)}update(t){this._currentX=t[0],this._currentY=t[1],this._currentRotation=t[2],this._engineLoad=t[6],this._condition=t[7]}_internalUpdate(t){if(t<=0)return;for(let u=this.children.length-1;u>=0;u-=1){const g=this.children[u];g.update(t)&&g.destroy()}const e=this._currentX-this._prevX,i=this._currentY-this._prevY,s=Math.sqrt(e*e+i*i),o=Tt(this._currentRotation-this._prevRotation),r=Math.abs(o),a=s-this._prevSpeed,c=Math.abs(a),h=r-this._prevAngularSpeed,f=Math.abs(h),_=performance.now();let m=!1;this._condition!==0&&_-this._lastTrackMarkTime>this._trackMarkCooldown&&(c>this._minAbsAccelerationForMark&&(m=!0),s>this._minSpeedForRotationMarks&&(r>this._minAngularSpeedForMark||f>this._minRotationAccelerationForMark)&&(m=!0)),this._engineLoad>1&&(m=!0),m&&(this.createTrackMarksAtPreviousPosition(),this._lastTrackMarkTime=_),this._prevX=this._currentX,this._prevY=this._currentY,this._prevRotation=this._currentRotation,this._prevSpeed=s,this._prevAngularSpeed=r}createTrackMarksAtPreviousPosition(){for(let t=-1;t<=1;t+=2){const e=Math.cos(this._prevRotation+Math.PI/2)*this._trackOffset*t,i=Math.sin(this._prevRotation+Math.PI/2)*this._trackOffset*t,s=-Math.cos(this._prevRotation)*this._backwardOffset,o=-Math.sin(this._prevRotation)*this._backwardOffset,r=this._prevX+e+s,a=this._prevY+i+o,c=new Wt(r,a,this._prevRotation,this._trackWidth,this._trackLength,this._trackInitialAlpha,this._assets.trackMarkTexture);this.addChild(c)}}_stopTimer(){this._tickListener&&(P.shared.remove(this._tickListener),this._tickListener=null)}destroy(t){this._stopTimer(),super.destroy({children:!0,texture:!1,textureSource:!1,...t})}}class Gt extends V{constructor(t,e,i,s,o){super(o),this.startPositionX=t,this.startPositionY=e,this.endPositionX=i,this.endPositionY=s,this.config={color:16777113,alphaStart:1,alphaEnd:.6,trailLength:55,tracerSpeed:19e3,minDuration:45,maxDuration:80,trailShrinkPower:1,trailStartOffset:30,segmentCount:12,segmentRadius:1,alphaPulseFrequency:.1,alphaPulseAmplitude:.15},this.graphics=new T,this.addChild(this.graphics),this.elapsedTime=0,this.dx=this.endPositionX-this.startPositionX,this.dy=this.endPositionY-this.startPositionY,this.totalDist=Math.hypot(this.dx,this.dy),this.totalDist>.001?(this.nx=this.dx/this.totalDist,this.ny=this.dy/this.totalDist,this.animationDuration=this.totalDist/this.config.tracerSpeed*1e3):(this.nx=0,this.ny=0,this.totalDist=0,this.animationDuration=this.config.minDuration),this.animationDuration=Math.max(this.config.minDuration,this.animationDuration),this.animationDuration=Math.min(this.config.maxDuration,this.animationDuration),this.animationDuration<=0&&(this.animationDuration=this.config.minDuration)}_drawSegment(t,e,i,s,o){this.graphics.circle(t,e,i),this.graphics.fill({color:s,alpha:Q(o,0,1)})}_update(t){if(this.isComplete)return;this.elapsedTime+=t,this.graphics.clear();const e=Math.min(this.elapsedTime/this.animationDuration,1);if(e>0){const i=k(this.startPositionX,this.endPositionX,e),s=k(this.startPositionY,this.endPositionY,e),o=k(this.config.alphaStart,this.config.alphaEnd,e),r=Math.sin(this.elapsedTime*this.config.alphaPulseFrequency)*this.config.alphaPulseAmplitude;let a=o+r;a=Q(a,0,this.config.alphaStart);const c=Math.pow(e,this.config.trailShrinkPower),h=k(this.config.trailLength,0,c),f=this.totalDist*e;if(f>=this.config.trailStartOffset){let _=f;this.totalDist>.001&&(_=Math.max(0,f-this.config.trailStartOffset));const m=Math.min(_,h);let u,g;this.totalDist>.001?(u=i-this.nx*m,g=s-this.ny*m):(u=i,g=s);const p=Math.hypot(i-u,s-g);if(p<this.config.segmentRadius*.5&&this.totalDist===0)this._drawSegment(i,s,this.config.segmentRadius,this.config.color,a);else if(p>=this.config.segmentRadius*.5){const y=Math.max(1,this.config.segmentCount);for(let x=0;x<y;x++){let w=.5;y>1&&(w=x/(y-1));const S=k(u,i,w),l=k(g,s,w),R=k(1,.8,w);this._drawSegment(S,l,this.config.segmentRadius,this.config.color,a*R)}}}}this.elapsedTime>=this.animationDuration&&(this.graphics.clear(),this._completeEffect())}destroy(t){this.graphics&&this.graphics.clear(),super.destroy(t)}}const Ht=10;class qt extends V{constructor(t,e,i,s,o,r){super(o),this.x=t,this.y=e,this._assets=r,this._particleTexture=this._assets.impactParticleTexture,this.config={particleCount:v(2,4),particleMinSize:1,particleMaxSize:3,minInitialSpeed:10,maxInitialSpeed:300,minLifetime:8e3,maxLifetime:15e3,color:[3355443,2236962,4473924],fadeOutStart:.8,impactDirectionX:i,impactDirectionY:s,spreadAngle:60,dragCoefficient:13,minSpeedThreshold:1,lingerDuration:6e3},this.config.impactDirectionX===0&&this.config.impactDirectionY===0?this.useOmnidirectionalSpread=!0:this.useOmnidirectionalSpread=!1,this.particlesData=[],this.elapsedTime=0,this._createParticles()}_createParticles(){let t;this.useOmnidirectionalSpread||(t=Math.atan2(this.config.impactDirectionY,this.config.impactDirectionX));const i=this.config.spreadAngle*(Math.PI/180)/2;for(let s=0,o=this.config.particleCount;s<o;s+=1){let r;this.useOmnidirectionalSpread?r=Math.random()*Math.PI*2:r=t+v(-i,i);const a=v(this.config.minInitialSpeed,this.config.maxInitialSpeed),c=new I(this._particleTexture);c.anchor.set(.5);const h={sprite:c,x:0,y:0,vx:Math.cos(r)*a,vy:Math.sin(r)*a,size:v(this.config.particleMinSize,this.config.particleMaxSize),color:Array.isArray(this.config.color)?this.config.color[Math.floor(Math.random()*this.config.color.length)]:this.config.color,lifetime:v(this.config.minLifetime,this.config.maxLifetime),age:0,alpha:1,active:!0,isMoving:!0,timeSinceStopped:0};c.tint=h.color,this.particlesData.push(h),this.addChild(c)}}_update(t){if(this.isComplete)return;this.elapsedTime+=t;const e=t/1e3;let i=0;for(let s=0,o=this.particlesData.length;s<o;s+=1){const r=this.particlesData[s];if(!r.active)continue;if(i+=1,r.age+=t,r.isMoving){const f=Math.hypot(r.vx,r.vy);if(f>0){const m=f*this.config.dragCoefficient*e,u=Math.max(0,1-m/f);r.vx*=u,r.vy*=u}r.x+=r.vx*e,r.y+=r.vy*e,Math.hypot(r.vx,r.vy)<this.config.minSpeedThreshold&&(r.isMoving=!1,r.vx=0,r.vy=0)}else r.timeSinceStopped+=t;const a=r.age/r.lifetime;if(!r.isMoving&&r.timeSinceStopped>=this.config.lingerDuration){const f=r.timeSinceStopped-this.config.lingerDuration,_=Math.min(500,r.lifetime*(1-this.config.fadeOutStart));r.alpha=k(1,0,Math.min(f/_,1))}else if(a>=this.config.fadeOutStart){const f=r.age-r.lifetime*this.config.fadeOutStart,_=r.lifetime*(1-this.config.fadeOutStart);r.alpha=_>0?k(1,0,Math.min(f/_,1)):0}(r.age>=r.lifetime||r.alpha<.01)&&(r.active=!1,r.alpha=0);const c=r.sprite;c.position.set(r.x,r.y),c.alpha=r.alpha,c.visible=r.active;const h=r.size/Ht;c.scale.set(h)}i===0&&this._isStarted&&this._completeEffect()}destroy(t){this.particlesData=[],super.destroy(t)}}class $t extends C{constructor(t,e,i){super(),this.zIndex=2,this.startPositionX=t[0],this.startPositionY=t[1],this.endPositionX=t[2],this.endPositionY=t[3],this.soundPositionX=t[4],this.soundPositionY=t[5],this.hit=t[6],this._assets=e,this._soundManager=i.soundManager,this.tracer=null,this.impact=null,this._isDestroyed=!1,this._visualsComplete=!1,this._soundComplete=!1,this._soundId=this._soundManager.registerSound("shot",{position:{x:this.soundPositionX,y:this.soundPositionY}},()=>{this._soundComplete=!0,this._soundId=null,this._tryDestroy()}),this._soundId||(this._soundComplete=!0)}run(){this._isDestroyed||(this.tracer=new Gt(this.startPositionX,this.startPositionY,this.endPositionX,this.endPositionY,this._onTracerComplete.bind(this)),this.addChild(this.tracer),this.tracer.run())}_onTracerComplete(){if(!this._isDestroyed)if(this.hit){const t=this.endPositionX-this.startPositionX,e=this.endPositionY-this.startPositionY,i=Math.hypot(t,e);let s=0,o=0;i>.001&&(s=-(t/i),o=-(e/i)),this.impact=new qt(this.endPositionX,this.endPositionY,s,o,this._onImpactComplete.bind(this),this._assets),this.addChild(this.impact),this.impact.run()}else this._visualsComplete=!0,this._tryDestroy()}_onImpactComplete(){this._isDestroyed||(this._visualsComplete=!0,this._tryDestroy())}_tryDestroy(){this._visualsComplete&&this._soundComplete&&this.destroy()}destroy(){this._isDestroyed||(this._isDestroyed=!0,this._soundId&&(this._soundManager.unregisterSound(this._soundId),this._soundId=null),this.tracer&&(this.tracer.destroy(),this.tracer=null),this.impact&&(this.impact.destroy(),this.impact=null),this.parent&&this.parent.removeChild(this),super.destroy({children:!0}))}}const jt={Map:Mt,MapRadar:kt,TankRadar:vt,Tank:Et,Bomb:Rt,ExplosionEffect:Bt,Smoke:Ut,Tracks:Vt,ShotEffect:$t};function Kt(n,t){const{radius:e,blur:i,color:s}=n,o=new T;o.circle(e+i,e+i,e),o.fill(s),o.filters=[new $({strength:i,quality:40})];const r=t.generateTexture({target:o,frame:new M(0,0,(e+i)*2,(e+i)*2)});return o.destroy(!0),r}function Zt(n,t){const{baseRadius:e,irregularity:i,blur:s,numPoints:o}=n,r=new T,a=(e+i+s)*2,c=a/2,h=[];for(let _=0;_<o;_+=1){const m=_/o*Math.PI*2,u=e+v(-i,i);h.push(c+u*Math.cos(m),c+u*Math.sin(m))}r.poly(h).fill(16777215),r.filters=[new $({strength:s,quality:10})];const f=t.generateTexture({target:r,frame:new M(0,0,a,a)});return r.destroy(!0),f}function Qt(n,t){const{radius:e,blur:i,color:s}=n,o=new T;o.circle(e+i,e+i,e),o.fill(s),o.filters=[new $({strength:i,quality:40})];const r=t.generateTexture({target:o,frame:new M(0,0,(e+i)*2,(e+i)*2)});return o.destroy(!0),r}function Jt(n,t){const{colors:e}=n,i={},s=10,o=s*4,r=s*3,a=15658734,c=f=>{const _=new T,m=new T,u=o,g=r;_.rect(-u/2,-g/2,u,g).fill(5592405).rect(-u/2+1,-g/2+1,u-2,g-2).fill(10066329).rect(-u/2+2,-g/2+2,u-4,g-4).fill(13421772).rect(-u/2+3,-g/2+3,u-6,g-6).fill(a),m.moveTo(1.33*s,-.42*s).lineTo(.42*s,-1*s).lineTo(-.42*s,-1*s).lineTo(-1.33*s,-.42*s).lineTo(-1.33*s,.42*s).lineTo(-.42*s,1*s).lineTo(.42*s,1*s).lineTo(1.33*s,.42*s).closePath().fill(f).stroke({width:.17*s,color:11184810}).moveTo(2.33*s,-.25*s).lineTo(.25*s,-.25*s).lineTo(.25*s,.25*s).lineTo(2.33*s,.25*s).closePath().stroke({width:.17*s,color:11184810}).fill(f);const p=_.getBounds(),y=t.generateTexture({target:_,frame:new M(p.x,p.y,p.width,p.height)}),x=m.getBounds(),w=t.generateTexture({target:m,frame:new M(x.x,x.y,x.width,x.height)}),S={x:-x.x/x.width,y:-x.y/x.height};return _.destroy(!0),m.destroy(!0),{body:y,gun:w,gunAnchor:S}},h=()=>{const f=new C,_=new T,m=new T;f.addChild(_,m);const u=3815994,g=2434341,p=3158064,y=1579032,x=5263440,w=o,S=r,l=s;_.moveTo(-w/2-l*.1,-S/2+l*.2).lineTo(w/2+l*.2,-S/2-l*.1).lineTo(w/2-l*.1,S/2+l*.3).lineTo(-w/2+l*.3,S/2-l*.2).closePath().fill(u).stroke({width:l*.2,color:x,alignment:.5}),_.moveTo(-w/2+l*.4,-S/2+l*.5).lineTo(w/2-l*.3,-S/2+l*.2).lineTo(w/2-l*.4,S/2-l*.1).lineTo(-w/2+l*.2,S/2-l*.4).closePath().fill(g),_.circle(w*.15,S*.1,l*1.2).fill(y),_.circle(-w*.3,-S*.25,l*.5).fill(y),m.position.set(l*.3,-l*.2);const R=[l*1.1,-l*.7,l*.2,-l*1,-l*.6,-l*.9,-l*1.3,-l*.2,-l*1.1,l*.6,-l*.2,l*1,l*.7,l*.8,l*1.3,l*.1];m.poly(R).fill(p).stroke({width:l*.15,color:x,alignment:0});const z=[l*.8,-l*.25,l*1.5,-l*.4,l*1.4,l*.15,l*.7,l*.05];m.poly(z).fill(p).stroke({width:l*.1,color:x,alignment:0}),m.circle(l*.1,-l*.2,l*.4).fill(y);const E=f.getBounds(),B=t.generateTexture({target:f,frame:new M(E.x,E.y,E.width,E.height)});return f.destroy({children:!0}),B};return i.liveTeamId1=c(e.teamId1),i.liveTeamId2=c(e.teamId2),i.destroyed=h(),i}function te(n,t){const{radius:e,borderWidth:i,crossSize:s,crossThickness:o,colors:r}=n,a={},c=(e+i)*2,h=c/2,f=15658734,_=3355443,m=g=>{const p=new T;p.circle(h,h,e).fill(f),p.circle(h,h,e-i).fill(g);const y=t.generateTexture({target:p,frame:new M(0,0,c,c)});return p.destroy(!0),y},u=()=>{const g=new T,p=s/2;g.moveTo(h-p,h-p).lineTo(h+p,h+p).moveTo(h-p,h+p).lineTo(h+p,h-p).stroke({width:o,color:_});const y=t.generateTexture({target:g,frame:new M(0,0,c,c)});return g.destroy(!0),y};return a.liveTeamId1=m(r.teamId1),a.liveTeamId2=m(r.teamId2),a.destroyed=u(),a}function ee(n,t){const{colorOuter:e,colorInner:i}=n,s=new T,o=20,r=1;s.rect(0,0,o,o).fill(e),s.rect(r,r,o-r*2,o-r*2).fill(i);const a=t.generateTexture({target:s,frame:new M(0,0,o,o)});return s.destroy(!0),a}function ie(n,t){const{width:e,length:i,color:s}=n,o=new T;o.rect(0,0,i,e).fill(s);const r=t.generateTexture({target:o,frame:new M(0,0,i,e)});return o.destroy(!0),r}function se(n,t){const{radius:e,blur:i,color:s}=n,o=new T,r=(e+i)*2,a=r/2;o.circle(a,a,e),o.fill(s),o.filters=[new $({strength:i,quality:10})];const c=t.generateTexture({target:o,frame:new M(0,0,r,r)});return o.destroy(!0),c}const ne={explosionTexture:Kt,funnelTexture:Zt,smokeTexture:Qt,tankTexture:Jt,tankRadarTexture:te,bombTexture:ee,trackMarkTexture:ie,impactParticleTexture:se},re=n=>(n??"").split(/[?#]/)[0].endsWith(".js"),oe=n=>import(n),he={id:"tanks",engineApi:_t,async createClientCore(n,{wasmUrl:t}){if(re(t)){const i=await oe(t);return{core:new i.ClientCore(n),memory:null}}const e=await wt({module_or_path:t});return{core:new Z(n),memory:e.memory}},parts:jt,bakers:ne,styles:St,hooks:{onAuth(n,t){n.set_model(t.model)},onPanel(n,t){n.sync_panel(JSON.stringify(t))},onLocalAction(n,t,e,i){return t!=="down"?null:e==="fire"?n.try_fire(i)||null:((e==="nextWeapon"||e==="prevWeapon")&&n.cycle_weapon(e==="prevWeapon"),null)}}};export{he as default};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "vimp-tanks-core",
|
|
3
|
+
"description": "VIMP Tanks — игровая симуляция (танки/оружие/боты) + wasm-bindgen ABI (GameCore/ClientCore) поверх vimp-engine-core.",
|
|
4
|
+
"version": "0.1.0",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/lgick/vimp-tanks"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"vimp_tanks_core_bg.wasm",
|
|
12
|
+
"vimp_tanks_core.js",
|
|
13
|
+
"vimp_tanks_core.d.ts"
|
|
14
|
+
],
|
|
15
|
+
"main": "vimp_tanks_core.js",
|
|
16
|
+
"types": "vimp_tanks_core.d.ts"
|
|
17
|
+
}
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
/* tslint:disable */
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Клиентский режим ядра (срез 2.6): интерполяция снапшотов, предикт
|
|
6
|
+
* своего танка, визуальный спавн снарядов и распаковка кадров v3.
|
|
7
|
+
* Живёт в главном потоке вкладки клиента; горячие позиции читаются
|
|
8
|
+
* zero-copy плоским Float32-буфером, событийные кадры — JSON-строкой.
|
|
9
|
+
*/
|
|
10
|
+
export class ClientCore {
|
|
11
|
+
free(): void;
|
|
12
|
+
[Symbol.dispose](): void;
|
|
13
|
+
/**
|
|
14
|
+
* Ввод игрока: action ('down'/'up') + имя клавиши — в историю
|
|
15
|
+
* предикта.
|
|
16
|
+
*/
|
|
17
|
+
apply_input(action: string, key_name: string, local_now: number): void;
|
|
18
|
+
/**
|
|
19
|
+
* Локальный цикл смены оружия (авторитетное подтверждение — панелью).
|
|
20
|
+
*/
|
|
21
|
+
cycle_weapon(back: boolean): void;
|
|
22
|
+
/**
|
|
23
|
+
* Дамп клиентского состояния для отладки: сетевой буфер
|
|
24
|
+
* (глубина, окно seq, оффсет, последний кадр), свой gameId,
|
|
25
|
+
* размеры hot-буфера и очереди событийных кадров.
|
|
26
|
+
*/
|
|
27
|
+
debug_json(): string;
|
|
28
|
+
/**
|
|
29
|
+
* Чистая распаковка кадра v3 → JSON {port, seq, serverTime,
|
|
30
|
+
* camera, player, snapshot} (замена unpackFrame в тестах);
|
|
31
|
+
* 'null' при несовпадении версии или повреждённом кадре.
|
|
32
|
+
*/
|
|
33
|
+
decode_frame(data: Uint8Array): string;
|
|
34
|
+
/**
|
|
35
|
+
* Указатель на hot-буфер (zero-copy чтение из JS:
|
|
36
|
+
* new Float32Array(wasm.memory.buffer, ptr, len) — view
|
|
37
|
+
* пересоздавать каждый тик, рост памяти WASM инвалидирует
|
|
38
|
+
* buffer).
|
|
39
|
+
*/
|
|
40
|
+
hot_ptr(): number;
|
|
41
|
+
/**
|
|
42
|
+
* Копия hot-буфера (nodejs-таргет; горячий путь браузера —
|
|
43
|
+
* hot_ptr).
|
|
44
|
+
*/
|
|
45
|
+
hot_values(): Float32Array;
|
|
46
|
+
/**
|
|
47
|
+
* Свой gameId из последнего player-блока; -1, если ещё не
|
|
48
|
+
* приходил.
|
|
49
|
+
*/
|
|
50
|
+
my_game_id(): number;
|
|
51
|
+
/**
|
|
52
|
+
* Создаёт клиентское ядро из JSON-конфига `{engine: {...}, game: {...}}`
|
|
53
|
+
* (собирается src/lib/clientCoreConfig.js из CONFIG_DATA + opcodes).
|
|
54
|
+
*/
|
|
55
|
+
constructor(config_json: string);
|
|
56
|
+
/**
|
|
57
|
+
* EMA-оценка (serverTime − localNow); NaN, если кадров ещё не
|
|
58
|
+
* было.
|
|
59
|
+
*/
|
|
60
|
+
offset(): number;
|
|
61
|
+
/**
|
|
62
|
+
* Бинарный кадр из транспорта: распаковка, вставка в буфер по
|
|
63
|
+
* seq (+дедупликация/опоздавшие), reconciliation предикта по
|
|
64
|
+
* player-блоку. false — кадр отброшен (чужой порт/версия/
|
|
65
|
+
* повреждён).
|
|
66
|
+
*/
|
|
67
|
+
push_frame(data: Uint8Array, local_now: number): boolean;
|
|
68
|
+
/**
|
|
69
|
+
* Полный сброс (порт CLEAR).
|
|
70
|
+
*/
|
|
71
|
+
reset(): void;
|
|
72
|
+
/**
|
|
73
|
+
* Весь рендер-тик: выдача пересечённых кадров (фильтр дублей
|
|
74
|
+
* своих эффектов → JSON-очередь), интерполяция, шаг предикта,
|
|
75
|
+
* запись hot-буфера. Возвращает длину hot-буфера в
|
|
76
|
+
* f32-элементах.
|
|
77
|
+
*/
|
|
78
|
+
sample(local_now: number): number;
|
|
79
|
+
/**
|
|
80
|
+
* Смена режима игрок/спектатор (KEYSET_DATA).
|
|
81
|
+
*/
|
|
82
|
+
set_active(active: boolean): void;
|
|
83
|
+
/**
|
|
84
|
+
* Данные карты (MAP_DATA): мир raycast + сброс буфера и
|
|
85
|
+
* предикта.
|
|
86
|
+
*/
|
|
87
|
+
set_map(map_json: string): void;
|
|
88
|
+
/**
|
|
89
|
+
* Модель танка пользователя (известна при авторизации).
|
|
90
|
+
*/
|
|
91
|
+
set_model(model: string): void;
|
|
92
|
+
/**
|
|
93
|
+
* Авторитетное состояние панели (PANEL_DATA): патроны/активное оружие.
|
|
94
|
+
*/
|
|
95
|
+
sync_panel(panel_json: string): void;
|
|
96
|
+
/**
|
|
97
|
+
* Записи расхождения предикта с авторитетным состоянием
|
|
98
|
+
* (JSON {samples, violations, dropped, maxDelta, records});
|
|
99
|
+
* очередь очищается. 'null' — детектор выключен (конфиг без
|
|
100
|
+
* секции divergence, боевой путь).
|
|
101
|
+
*/
|
|
102
|
+
take_divergence(): string;
|
|
103
|
+
/**
|
|
104
|
+
* Событийные кадры JSON-строкой [{game, camera}, ...] в
|
|
105
|
+
* форме, готовой для applyShot; вызывать при флаге hasFrames
|
|
106
|
+
* hot-буфера, очередь очищается.
|
|
107
|
+
*/
|
|
108
|
+
take_frames(): string;
|
|
109
|
+
/**
|
|
110
|
+
* Локальный визуальный выстрел: гейты (кулдаун/патроны/pending-бомба/
|
|
111
|
+
* жив/активен) внутри. JSON спавна для applyGameData либо None.
|
|
112
|
+
*/
|
|
113
|
+
try_fire(local_now: number): string | undefined;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Публичный ABI ядра для JS-оболочки (Worker хоста / тестовый харнесс).
|
|
118
|
+
*/
|
|
119
|
+
export class GameCore {
|
|
120
|
+
free(): void;
|
|
121
|
+
[Symbol.dispose](): void;
|
|
122
|
+
/**
|
|
123
|
+
* Живые игроки плоским массивом [id, teamId, x, y, ...]
|
|
124
|
+
* (аналог Game.getAlivePlayers для меты).
|
|
125
|
+
*/
|
|
126
|
+
alive_players(): Float32Array;
|
|
127
|
+
/**
|
|
128
|
+
* Ввод игрока: seq + action ('down'/'up') + имя клавиши
|
|
129
|
+
* (wire-формат 'seq:action:name' разбирает JS-оболочка).
|
|
130
|
+
*/
|
|
131
|
+
apply_input(game_id: number, seq: number, action: string, key_name: string): void;
|
|
132
|
+
/**
|
|
133
|
+
* Содержал ли последний `pack_body()` событийные блоки
|
|
134
|
+
* (трассеры/бомбы/взрывы/удаления). JS-Worker вызывает после
|
|
135
|
+
* `pack_body()` для выбора канала WebRTC: события → meta
|
|
136
|
+
* (reliable), только позиции → state.
|
|
137
|
+
*/
|
|
138
|
+
body_has_events(): boolean;
|
|
139
|
+
/**
|
|
140
|
+
* Полная очистка мира (смена карты).
|
|
141
|
+
*/
|
|
142
|
+
clear(): void;
|
|
143
|
+
/**
|
|
144
|
+
* Курированный дамп мира для отладки (тела, коллайдеры,
|
|
145
|
+
* карта, нав-граф, spatial-сетка, rng, аккумулятор) —
|
|
146
|
+
* читаемая альтернатива serialize_state.
|
|
147
|
+
*/
|
|
148
|
+
debug_json(): string;
|
|
149
|
+
deserialize_state(data: Uint8Array): void;
|
|
150
|
+
/**
|
|
151
|
+
* Копия последнего кадра (nodejs-таргет не отдаёт память
|
|
152
|
+
* наружу; горячий путь браузера использует frame_ptr + память
|
|
153
|
+
* WASM).
|
|
154
|
+
*/
|
|
155
|
+
frame_bytes(): Uint8Array;
|
|
156
|
+
/**
|
|
157
|
+
* Указатель на буфер последнего кадра (zero-copy чтение из JS:
|
|
158
|
+
* new Uint8Array(wasm.memory.buffer, ptr, len)).
|
|
159
|
+
*/
|
|
160
|
+
frame_ptr(): number;
|
|
161
|
+
is_alive(game_id: number): boolean;
|
|
162
|
+
last_input_seq(game_id: number): number;
|
|
163
|
+
/**
|
|
164
|
+
* Загружает карту из JSON (см. scripts/export-maps.js).
|
|
165
|
+
*/
|
|
166
|
+
load_map(map_json: string): void;
|
|
167
|
+
/**
|
|
168
|
+
* Информация о загруженной карте: setId, масштабированные
|
|
169
|
+
* респауны, размеры мира (JSON).
|
|
170
|
+
*/
|
|
171
|
+
map_info(): string;
|
|
172
|
+
/**
|
|
173
|
+
* Создаёт ядро из JSON-конфига `{engine: {...}, game: {...}}`
|
|
174
|
+
* (собирается JS-оболочкой из game.js + models.js + weapons.js +
|
|
175
|
+
* opcodes.js, см. PLAN.md §3.4).
|
|
176
|
+
*/
|
|
177
|
+
constructor(config_json: string);
|
|
178
|
+
/**
|
|
179
|
+
* Пакует broadcast-тело кадра, дренируя накопленные события
|
|
180
|
+
* снапшота. Вызывать один раз на отправляемый кадр (throttle
|
|
181
|
+
* частоты отправки — забота JS-оболочки).
|
|
182
|
+
*/
|
|
183
|
+
pack_body(): void;
|
|
184
|
+
/**
|
|
185
|
+
* Собирает per-user кадр v3 во внутренний буфер, возвращает
|
|
186
|
+
* длину. Кадр читается zero-copy через frame_ptr() + память
|
|
187
|
+
* WASM. player_id < 0 — кадр без player-блока (наблюдатель).
|
|
188
|
+
*/
|
|
189
|
+
pack_frame(server_time: number, seq: number, has_camera: boolean, camera_x: number, camera_y: number, force_reset: boolean, shake: string | null | undefined, player_id: number): number;
|
|
190
|
+
/**
|
|
191
|
+
* Полные данные всех игроков (Game.getPlayersData) одной
|
|
192
|
+
* JSON-строкой для первого кадра (FIRST_SHOT_DATA). Не
|
|
193
|
+
* дренирует накопители.
|
|
194
|
+
*/
|
|
195
|
+
players_data(): string;
|
|
196
|
+
/**
|
|
197
|
+
* Координаты танка [x, y] (скруглены до 2 знаков) или пустой
|
|
198
|
+
* массив.
|
|
199
|
+
*/
|
|
200
|
+
position_of(game_id: number): Float32Array;
|
|
201
|
+
remove_actor(game_id: number): void;
|
|
202
|
+
/**
|
|
203
|
+
* Удаляет игроков и снаряды, возвращает JSON-массив имён для
|
|
204
|
+
* очистки полотна клиентов (Game.removePlayersAndShots).
|
|
205
|
+
*/
|
|
206
|
+
remove_players_and_shots(): string;
|
|
207
|
+
remove_scripted_actor(game_id: number): void;
|
|
208
|
+
/**
|
|
209
|
+
* Респаун/смена команды (аналог Game.changePlayerData).
|
|
210
|
+
*/
|
|
211
|
+
reset_actor(game_id: number, team_id: number, x: number, y: number, angle_deg: number): void;
|
|
212
|
+
/**
|
|
213
|
+
* Сброс здоровья/боезапаса всех танков (аналог Panel.reset).
|
|
214
|
+
*/
|
|
215
|
+
reset_all_vitals(): void;
|
|
216
|
+
/**
|
|
217
|
+
* Дамп состояния симуляции (Worker Handoff, Этап 5.2).
|
|
218
|
+
*/
|
|
219
|
+
serialize_state(): Uint8Array;
|
|
220
|
+
spawn_actor(game_id: number, model: string, team_id: number, x: number, y: number, angle_deg: number): void;
|
|
221
|
+
spawn_scripted_actor(game_id: number, model: string, team_id: number, x: number, y: number, angle_deg: number): void;
|
|
222
|
+
/**
|
|
223
|
+
* Шаг симуляции: фиксированные подшаги физики + ИИ ботов.
|
|
224
|
+
*/
|
|
225
|
+
step(dt: number): void;
|
|
226
|
+
/**
|
|
227
|
+
* События за тик (kill/health/ammo/weapon/shake) одной
|
|
228
|
+
* JSON-строкой; буфер очищается.
|
|
229
|
+
*/
|
|
230
|
+
take_events(): string;
|
|
231
|
+
}
|