@vimp-games/tanks 0.22.9 → 0.22.11

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.
@@ -44,6 +44,15 @@ export class ClientCore {
44
44
  * Зеркало `dispatch` игрового ядра (см. игровой макрос).
45
45
  */
46
46
  dispatch(op: string, payload: Uint8Array): Uint8Array;
47
+ /**
48
+ * Уровень пола под мировой точкой для пули, летящей на уровне `level`:
49
+ * сам `level`, если там его плита (у земли — всегда), иначе уровень
50
+ * приземления — то же правило, что у сегментов луча
51
+ * (`shot_levels::floor_under`). По нему клиент ищет грань стены или
52
+ * насыпи под пулей с моста и кладёт осколки её попадания на пол под ними.
53
+ * Карты нет — `level`.
54
+ */
55
+ floor_level(level: number, x: number, y: number): number;
47
56
  /**
48
57
  * Указатель на hot-буфер (zero-copy чтение из JS:
49
58
  * new Float32Array(wasm.memory.buffer, ptr, len) — view
@@ -137,9 +146,11 @@ export class ClientCore {
137
146
  * Сегменты луча выстрела по уровням — те же `shot_levels::ray_segments`,
138
147
  * по которым хост судит попадание: `(x, y)` — дуло, `(dx, dy)` —
139
148
  * единичное направление, `range` — длина луча, `level` — уровень
140
- * стрелка. Плоско: `[t0, t1, level, …]`, `t` — мировые единицы вдоль
141
- * луча. Трассер режется по ним на куски, и каждый рисуется на своём
142
- * уровне: луч с моста идёт над плитой и падает за кромкой. Карты нет —
149
+ * стрелка (пуля ровно на уровне стрелка — наклона ствола рендер не
150
+ * знает). Плоско: `[t0, t1, fly, …]`, `t` — мировые единицы вдоль
151
+ * луча, третий элемент — уровень ПРОЕКЦИИ сегмента. Трассер режется по
152
+ * ним на куски, и каждый рисуется на своём уровне: луч с моста идёт над
153
+ * плитой и дальше на её высоте. Карты нет —
143
154
  * один сегмент `[0, range, level]`; одноуровневая карта — один
144
155
  * сегмент уровня 0, как у хоста.
145
156
  */
@@ -120,6 +120,22 @@ class ClientCore {
120
120
  wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);
121
121
  return v3;
122
122
  }
123
+ /**
124
+ * Уровень пола под мировой точкой для пули, летящей на уровне `level`:
125
+ * сам `level`, если там его плита (у земли — всегда), иначе уровень
126
+ * приземления — то же правило, что у сегментов луча
127
+ * (`shot_levels::floor_under`). По нему клиент ищет грань стены или
128
+ * насыпи под пулей с моста и кладёт осколки её попадания на пол под ними.
129
+ * Карты нет — `level`.
130
+ * @param {number} level
131
+ * @param {number} x
132
+ * @param {number} y
133
+ * @returns {number}
134
+ */
135
+ floor_level(level, x, y) {
136
+ const ret = wasm.clientcore_floor_level(this.__wbg_ptr, level, x, y);
137
+ return ret;
138
+ }
123
139
  /**
124
140
  * Указатель на hot-буфер (zero-copy чтение из JS:
125
141
  * new Float32Array(wasm.memory.buffer, ptr, len) — view
@@ -302,9 +318,11 @@ class ClientCore {
302
318
  * Сегменты луча выстрела по уровням — те же `shot_levels::ray_segments`,
303
319
  * по которым хост судит попадание: `(x, y)` — дуло, `(dx, dy)` —
304
320
  * единичное направление, `range` — длина луча, `level` — уровень
305
- * стрелка. Плоско: `[t0, t1, level, …]`, `t` — мировые единицы вдоль
306
- * луча. Трассер режется по ним на куски, и каждый рисуется на своём
307
- * уровне: луч с моста идёт над плитой и падает за кромкой. Карты нет —
321
+ * стрелка (пуля ровно на уровне стрелка — наклона ствола рендер не
322
+ * знает). Плоско: `[t0, t1, fly, …]`, `t` — мировые единицы вдоль
323
+ * луча, третий элемент — уровень ПРОЕКЦИИ сегмента. Трассер режется по
324
+ * ним на куски, и каждый рисуется на своём уровне: луч с моста идёт над
325
+ * плитой и дальше на её высоте. Карты нет —
308
326
  * один сегмент `[0, range, level]`; одноуровневая карта — один
309
327
  * сегмент уровня 0, как у хоста.
310
328
  * @param {number} x
@@ -10,6 +10,7 @@ export const clientcore_cycle_weapon: (a: number, b: number) => void;
10
10
  export const clientcore_debug_json: (a: number) => [number, number];
11
11
  export const clientcore_decode_frame: (a: number, b: number, c: number) => [number, number];
12
12
  export const clientcore_dispatch: (a: number, b: number, c: number, d: number, e: number) => [number, number];
13
+ export const clientcore_floor_level: (a: number, b: number, c: number, d: number) => number;
13
14
  export const clientcore_hot_ptr: (a: number) => number;
14
15
  export const clientcore_hot_values: (a: number) => [number, number];
15
16
  export const clientcore_map_dynamics_to_world: (a: number, b: number, c: number, d: number, e: number) => [number, number];
@@ -0,0 +1 @@
1
+ class we{__destroy_into_raw(){const e=this.__wbg_ptr;return this.__wbg_ptr=0,Me.unregister(this),e}free(){const e=this.__destroy_into_raw();l.__wbg_gamecore_free(e,0)}abi_describe(){let e,a;try{const r=l.gamecore_abi_describe(this.__wbg_ptr);return e=r[0],a=r[1],R(r[0],r[1])}finally{l.__wbindgen_free(e,a,1)}}alive_players(){const e=l.gamecore_alive_players(this.__wbg_ptr);var a=Ne(e[0],e[1]).slice();return l.__wbindgen_free(e[0],e[1]*4,4),a}apply_aim(e,a,r,o,s){l.gamecore_apply_aim(this.__wbg_ptr,e,a,r,o,s)}apply_input(e,a,r,o){const s=E(r,l.__wbindgen_malloc,l.__wbindgen_realloc),i=x,c=E(o,l.__wbindgen_malloc,l.__wbindgen_realloc),d=x;l.gamecore_apply_input(this.__wbg_ptr,e,a,s,i,c,d)}body_has_events(){return l.gamecore_body_has_events(this.__wbg_ptr)!==0}clear(){l.gamecore_clear(this.__wbg_ptr)}debug_json(){let e,a;try{const r=l.gamecore_debug_json(this.__wbg_ptr);return e=r[0],a=r[1],R(r[0],r[1])}finally{l.__wbindgen_free(e,a,1)}}deserialize_state(e){const a=Le(e,l.__wbindgen_malloc),r=x,o=l.gamecore_deserialize_state(this.__wbg_ptr,a,r);if(o[1])throw C(o[0])}dispatch(e,a){const r=E(e,l.__wbindgen_malloc,l.__wbindgen_realloc),o=x,s=Le(a,l.__wbindgen_malloc),i=x,c=l.gamecore_dispatch(this.__wbg_ptr,r,o,s,i);var d=be(c[0],c[1]).slice();return l.__wbindgen_free(c[0],c[1]*1,1),d}frame_bytes(){const e=l.gamecore_frame_bytes(this.__wbg_ptr);var a=be(e[0],e[1]).slice();return l.__wbindgen_free(e[0],e[1]*1,1),a}frame_ptr(){return l.gamecore_frame_ptr(this.__wbg_ptr)>>>0}is_alive(e){return l.gamecore_is_alive(this.__wbg_ptr,e)!==0}last_input_seq(e){return l.gamecore_last_input_seq(this.__wbg_ptr,e)>>>0}load_map(e){const a=E(e,l.__wbindgen_malloc,l.__wbindgen_realloc),r=x,o=l.gamecore_load_map(this.__wbg_ptr,a,r);if(o[1])throw C(o[0])}map_info(){let e,a;try{const r=l.gamecore_map_info(this.__wbg_ptr);return e=r[0],a=r[1],R(r[0],r[1])}finally{l.__wbindgen_free(e,a,1)}}constructor(e){const a=E(e,l.__wbindgen_malloc,l.__wbindgen_realloc),r=x,o=l.gamecore_new(a,r);if(o[2])throw C(o[1]);return this.__wbg_ptr=o[0],Me.register(this,this.__wbg_ptr,this),this}pack_body(){const e=l.gamecore_pack_body(this.__wbg_ptr);if(e[1])throw C(e[0])}pack_frame(e,a,r,o,s,i,c,d){var p=nt(c)?0:E(c,l.__wbindgen_malloc,l.__wbindgen_realloc),m=x;return l.gamecore_pack_frame(this.__wbg_ptr,e,a,r,o,s,i,p,m,d)>>>0}players_data(){let e,a;try{const r=l.gamecore_players_data(this.__wbg_ptr);return e=r[0],a=r[1],R(r[0],r[1])}finally{l.__wbindgen_free(e,a,1)}}position_of(e){const a=l.gamecore_position_of(this.__wbg_ptr,e);var r=Ne(a[0],a[1]).slice();return l.__wbindgen_free(a[0],a[1]*4,4),r}remove_actor(e){l.gamecore_remove_actor(this.__wbg_ptr,e)}remove_players_and_shots(){let e,a;try{const r=l.gamecore_remove_players_and_shots(this.__wbg_ptr);return e=r[0],a=r[1],R(r[0],r[1])}finally{l.__wbindgen_free(e,a,1)}}remove_scripted_actor(e){l.gamecore_remove_scripted_actor(this.__wbg_ptr,e)}reset_actor(e,a,r,o,s){l.gamecore_reset_actor(this.__wbg_ptr,e,a,r,o,s)}reset_all_vitals(){l.gamecore_reset_all_vitals(this.__wbg_ptr)}serialize_state(){const e=l.gamecore_serialize_state(this.__wbg_ptr);if(e[3])throw C(e[2]);var a=be(e[0],e[1]).slice();return l.__wbindgen_free(e[0],e[1]*1,1),a}set_actor_level(e,a){l.gamecore_set_actor_level(this.__wbg_ptr,e,a)}spawn_actor(e,a,r,o,s,i){const c=E(a,l.__wbindgen_malloc,l.__wbindgen_realloc),d=x,p=l.gamecore_spawn_actor(this.__wbg_ptr,e,c,d,r,o,s,i);if(p[1])throw C(p[0])}spawn_scripted_actor(e,a,r,o,s,i){const c=E(a,l.__wbindgen_malloc,l.__wbindgen_realloc),d=x,p=l.gamecore_spawn_scripted_actor(this.__wbg_ptr,e,c,d,r,o,s,i);if(p[1])throw C(p[0])}step(e){l.gamecore_step(this.__wbg_ptr,e)}take_events(){let e,a;try{const r=l.gamecore_take_events(this.__wbg_ptr);return e=r[0],a=r[1],R(r[0],r[1])}finally{l.__wbindgen_free(e,a,1)}}}Symbol.dispose&&(we.prototype[Symbol.dispose]=we.prototype.free);function at(){return{__proto__:null,"./vimp_tanks_core_bg.js":{__proto__:null,__wbg_Error_92b29b0548f8b746:function(e,a){return Error(R(e,a))},__wbg___wbindgen_throw_344f42d3211c4765:function(e,a){throw new Error(R(e,a))},__wbindgen_init_externref_table:function(){const e=l.__wbindgen_externrefs,a=e.grow(4);e.set(0,void 0),e.set(a+0,void 0),e.set(a+1,null),e.set(a+2,!0),e.set(a+3,!1)}}}}typeof FinalizationRegistry>"u"||new FinalizationRegistry(t=>l.__wbg_clientcore_free(t,1));const Me=typeof FinalizationRegistry>"u"?{register:()=>{},unregister:()=>{}}:new FinalizationRegistry(t=>l.__wbg_gamecore_free(t,1));function Ne(t,e){return t=t>>>0,rt().subarray(t/4,t/4+e)}function be(t,e){return t=t>>>0,j().subarray(t/1,t/1+e)}let q=null;function rt(){return(q===null||q.byteLength===0)&&(q=new Float32Array(l.memory.buffer)),q}function R(t,e){return st(t>>>0,e)}let X=null;function j(){return(X===null||X.byteLength===0)&&(X=new Uint8Array(l.memory.buffer)),X}function nt(t){return t==null}function Le(t,e){const a=e(t.length*1,1)>>>0;return j().set(t,a/1),x=t.length,a}function E(t,e,a){if(a===void 0){const c=K.encode(t),d=e(c.length,1)>>>0;return j().subarray(d,d+c.length).set(c),x=c.length,d}let r=t.length,o=e(r,1)>>>0;const s=j();let i=0;for(;i<r;i++){const c=t.charCodeAt(i);if(c>127)break;s[o+i]=c}if(i!==r){i!==0&&(t=t.slice(i)),o=a(o,r,r=i+t.length*3,1)>>>0;const c=j().subarray(o+i,o+r),d=K.encodeInto(t,c);i+=d.written,o=a(o,r,i,1)>>>0}return x=i,o}function C(t){const e=l.__wbindgen_externrefs.get(t);return l.__externref_table_dealloc(t),e}let ce=new TextDecoder("utf-8",{ignoreBOM:!0,fatal:!0});ce.decode();const ot=2146435072;let xe=0;function st(t,e){return xe+=e,xe>=ot&&(ce=new TextDecoder("utf-8",{ignoreBOM:!0,fatal:!0}),ce.decode(),xe=e),ce.decode(j().subarray(t,t+e))}const K=new TextEncoder;"encodeInto"in K||(K.encodeInto=function(t,e){const a=K.encode(t);return e.set(a),{read:t.length,written:a.length}});let x=0,l;function it(t,e){return l=t.exports,q=null,X=null,l.__wbindgen_start(),l}async function lt(t,e){if(typeof Response=="function"&&t instanceof Response){if(typeof WebAssembly.instantiateStreaming=="function")try{return await WebAssembly.instantiateStreaming(t,e)}catch(o){if(t.ok&&a(t.type)&&t.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",o);else throw o}const r=await t.arrayBuffer();return await WebAssembly.instantiate(r,e)}else{const r=await WebAssembly.instantiate(t,e);return r instanceof WebAssembly.Instance?{instance:r,module:t}:r}function a(r){switch(r){case"basic":case"cors":case"default":return!0}return!1}}async function ct(t){if(l!==void 0)return l;t!==void 0&&(Object.getPrototypeOf(t)===Object.prototype?{module_or_path:t}=t:console.warn("using deprecated parameters for the initialization function; pass a single object instead")),t===void 0&&(t=new URL("/assets/vimp_tanks_core_bg-GriiC3GE.wasm",import.meta.url));const e=at();(typeof t=="string"||typeof Request=="function"&&t instanceof Request||typeof URL=="function"&&t instanceof URL)&&(t=fetch(t));const{instance:a,module:r}=await lt(await t,e);return it(a)}function pt(t){const e={},a=(r,o={},s={})=>{for(const[i,c]of Object.entries(s))for(const d of o[i]||[]){const p=e[r]??={};p[d]=Math.max(p[d]??0,c)}};a("0",t.layers,t.volumes);for(const[r,o]of Object.entries(t.levels||{}))a(String(r),o.layers,o.volumes);return e}function mt(t){const e=pt(t);return Object.keys(e).length===0?t:{...t,game:{...t.game,wallHeights:e}}}const ft={setId:"c1",scale:.2,spriteSheet:{img:"tiles3.png",frames:[[0,64,32,32],[0,192,32,32],[96,64,32,32]]},layers:{1:[0,1],4:[2]},step:32,physicsStatic:[1],physicsDynamic:(function(){const r=[];for(let p=0;p<20;p+=1)for(let m=0;m<1;m+=1){const O=(104+m*3)*32+48,ge=(45+p*3)*32+48;r.push({density:20,layer:3,position:[O,ge],angle:0,width:96,height:96,img:"b1.png",linearDamping:8,angularDamping:16})}return r})(),respawns:{team1:[[448,1840,0],[256,2304,0],[448,2688,0],[256,3e3,0],[256,512,0],[448,832,0],[256,1152,0],[448,3648,0],[256,3968,0],[448,4288,0]],team2:[[6272,1840,180],[6464,2304,180],[6272,2688,180],[6464,3e3,180],[6464,512,180],[6272,832,180],[6464,1152,180],[6272,3648,180],[6464,3968,180],[6272,4288,180]]},map:(function(){const a={floor:0,wall:1,effect:2},r=Array.from({length:150},()=>Array(210).fill(a.floor));for(let s=0;s<150;s++)for(let i=0;i<210;i++)(s<2||s>=148||i<2||i>=208)&&(r[s][i]=a.wall);const o=(s,i,c,d)=>{for(let p=i;p<=d;p++)for(let m=s;m<=c;m++)m>=0&&m<210&&p>=0&&p<150&&(r[p][m]=a.wall)};o(50,0,51,30),o(50,119,51,149),o(158,0,159,30),o(158,119,159,149),o(80,30,130,31),o(80,118,130,119);for(let s=64;s<86;s++)for(let i=2;i<208;i++)(i+s)%2===0?r[s][i]=a.effect:r[s][i]=a.floor;return r})()},Q=32,Be=16,n={EMPTY:0,ASPHALT:1,SIDEWALK:2,LANE:3,SAND:4,MUD:5,WATER:6,OIL:7,CONVEYOR_E:8,CONVEYOR_W:9,BOOST_N:10,BOOST_E:11,WALL:12,ROOF:13,SLAB:14,RAILING:15,RAMP_N:16,RAMP_S:17,RAMP_E:18,RAMP_W:19,CANAL_WALL:20,WATER_2:21,WATER_3:22,WATER_4:23,CONVEYOR_E_2:24,CONVEYOR_E_3:25,CONVEYOR_E_4:26,CONVEYOR_W_2:27,CONVEYOR_W_3:28,CONVEYOR_W_4:29,BOOST_N_2:30,BOOST_E_2:31,FAN:32},dt=n.FAN+1,ut=Array.from({length:dt},(t,e)=>[e%Be*Q,Math.floor(e/Be)*Q,Q,Q]),Y=96,pe=72,T=32,v={x0:22,x1:73,railNorth:20,railSouth:26},Ce={x0:15,x1:21},Ie={x0:74,x1:80},De={x0:38,x1:40},Fe={x0:55,x1:57},_={x0:24,x1:36,y0:30,y1:40},J={x0:18,x1:19,y0:34,y1:36},z={x0:20,x1:23,y0:34,y1:36},We={x0:29,x1:31},ee={wallNorth:54,wallSouth:62},Se=[{x0:27,x1:31},{x0:64,x1:68}],V={y0:53,y1:63},Ve={y0:50,y1:52},Pe={y0:64,y1:66},Ye={x0:45,x1:50},te={x0:47,x1:48,y0:64,y1:65},ve=[{x0:4,x1:10,y0:3,y1:7,roof:!0},{x0:25,x1:31,y0:3,y1:7,roof:!0},{x0:37,x1:44,y0:3,y1:15},{x0:51,x1:58,y0:3,y1:15},{x0:85,x1:91,y0:3,y1:7},{x0:38,x1:43,y0:29,y1:32,roof:!0},{x0:52,x1:57,y0:29,y1:32,roof:!0},{x0:38,x1:43,y0:39,y1:42,roof:!0},{x0:52,x1:57,y0:39,y1:42,roof:!0},{x0:62,x1:70,y0:31,y1:39},{x0:3,x1:8,y0:45,y1:50,roof:!0},{x0:87,x1:92,y0:45,y1:50,roof:!0}],qe=t=>Array.from({length:pe},()=>Array(Y).fill(t)),u=(t,e,a,r,o,s)=>{for(let i=a;i<=o;i+=1)for(let c=e;c<=r;c+=1)t[i][c]=s},Z=(t,e,a,r,o)=>u(t,a,e,r,e,o),D=(t,e,a,r,o)=>u(t,e,a,e,r,o),ye=(t,e,a)=>t>=e&&t<=a,$=(t,e,a,r)=>{for(let o=a;o<=r;o+=2)t[e][o]===n.ASPHALT&&(t[e][o]=n.LANE)},yt=(function(){const t=qe(n.ASPHALT);for(const e of ve)u(t,e.x0-1,e.y0-1,e.x1+1,e.y1+1,n.SIDEWALK);for(const e of ve)u(t,e.x0,e.y0,e.x1,e.y1,n.WALL);$(t,23,2,93),$(t,35,38,44),$(t,35,51,57),$(t,47,2,93),$(t,68,2,93),u(t,6,11,17,12,n.CONVEYOR_E),u(t,16,15,27,16,n.CONVEYOR_W),u(t,63,9,72,15,n.SAND),u(t,80,12,90,16,n.SAND),u(t,73,3,79,8,n.MUD),u(t,75,11,79,16,n.MUD),u(t,45,34,50,37,n.OIL),u(t,1,ee.wallNorth+1,Y-2,ee.wallSouth-1,n.WATER);for(const e of[ee.wallNorth,ee.wallSouth])for(let a=1;a<Y-1;a+=1)ye(a,Ye.x0,Ye.x1)||Se.some(o=>ye(a,o.x0,o.x1))||(t[e][a]=n.CANAL_WALL);u(t,te.x0,te.y0,te.x1,te.y1,n.BOOST_N),u(t,J.x0,J.y0,J.x1,J.y1,n.BOOST_E),u(t,Ce.x0,v.railNorth+1,Ce.x1,v.railSouth-1,n.RAMP_E),u(t,Ie.x0,v.railNorth+1,Ie.x1,v.railSouth-1,n.RAMP_W),u(t,z.x0,z.y0,z.x1,z.y1,n.RAMP_E);for(const e of Se)u(t,e.x0+1,Ve.y0,e.x1-1,Ve.y1,n.RAMP_S),u(t,e.x0+1,Pe.y0,e.x1-1,Pe.y1,n.RAMP_N);return Z(t,0,0,Y-1,n.WALL),Z(t,pe-1,0,Y-1,n.WALL),D(t,0,0,pe-1,n.WALL),D(t,Y-1,0,pe-1,n.WALL),t})(),_t=(function(){const t=qe(n.EMPTY);for(const e of ve)e.roof&&u(t,e.x0,e.y0,e.x1,e.y1,n.ROOF);u(t,v.x0,v.railNorth+1,v.x1,v.railSouth-1,n.SLAB);for(let e=v.x0;e<=v.x1;e+=1)t[v.railNorth][e]=ye(e,De.x0,De.x1)?n.SLAB:n.RAILING,t[v.railSouth][e]=ye(e,Fe.x0,Fe.x1)?n.SLAB:n.RAILING;u(t,60,22,62,24,n.OIL),u(t,_.x0,_.y0,_.x1,_.y1,n.SLAB),Z(t,_.y0,_.x0,_.x1,n.RAILING),Z(t,_.y1,_.x0,_.x1,n.RAILING),D(t,_.x0,_.y0,_.y1,n.RAILING),D(t,_.x1,_.y0,_.y1,n.RAILING),D(t,_.x0,z.y0,z.y1,n.SLAB),Z(t,_.y1,We.x0,We.x1,n.SLAB);for(const e of Se)u(t,e.x0+1,V.y0,e.x1-1,V.y1,n.SLAB),D(t,e.x0,V.y0,V.y1,n.RAILING),D(t,e.x1,V.y0,V.y1,n.RAILING);return t})(),ht=(t,e)=>[t*T+T/2,e*T+T/2],Ee=(t,e,a,r,o)=>({layer:3,position:[t*T+(T-a)/2,e*T+(T-r)/2],angle:0,width:a,height:r,linearDamping:6,angularDamping:14,level:0,...o}),A=(t,e)=>({...Ee(t,e,64,12,{}),position:[t*T,e*T+(T-12)/2],density:30,img:"prop_fence.png",game:{prop:"fence",imgDestroyed:"prop_fence_broken.png"}}),w=(t,e,a=0)=>Ee(t,e,32,32,{density:40,img:"prop_crate.png",level:a,game:{prop:"crate",imgDamaged:"prop_crate_damaged.png",imgDestroyed:"prop_crate_broken.png"}}),P=(t,e)=>Ee(t,e,24,24,{density:30,img:"prop_barrel.png",game:{prop:"barrel"}}),h=(t,e,a)=>[...ht(t,e),a,0],g=(t,e,a=0,r={})=>({cell:[t,e],level:a,radius:110,color:16760944,intensity:.9,head:!0,flicker:0,...r}),H=(t,e,a,r)=>{const o=[];for(let s=t;s<=e;s+=a)o.push(r(s));return o},ze=60,gt={setId:"c1",scale:.4,spriteSheet:{img:"city.png",frames:ut},layers:{1:[n.ASPHALT,n.SIDEWALK,n.LANE,n.SAND,n.MUD,n.WATER,n.OIL,n.CONVEYOR_E,n.CONVEYOR_W,n.BOOST_N,n.BOOST_E,n.RAMP_N,n.RAMP_S,n.RAMP_E,n.RAMP_W],2:[n.WALL],4:[n.CANAL_WALL]},volumes:{2:1,4:.25},step:T,physicsStatic:[n.WALL,n.CANAL_WALL],levels:{1:{map:_t,floor:[n.SLAB,n.RAILING,n.ROOF,n.OIL],walls:[n.RAILING],layers:{1:[n.SLAB,n.OIL],2:[n.ROOF],4:[n.RAILING]},volumes:{4:.35}}},ramps:[{tile:n.RAMP_E,dir:"east",from:0,to:1},{tile:n.RAMP_W,dir:"west",from:0,to:1},{tile:n.RAMP_S,dir:"south",from:0,to:1},{tile:n.RAMP_N,dir:"north",from:0,to:1}],physicsDynamic:[w(3,11),w(3,13),w(20,10),w(21,10),w(31,15),w(32,15),P(28,13),P(29,13),P(28,14),P(29,14),A(62,8),A(64,8),A(66,8),A(68,8),A(70,8),A(82,11),A(84,11),A(86,11),A(88,11),A(90,11),w(66,4),w(68,4),w(80,4),w(82,4),P(10,63),P(85,63),w(34,31,1),w(35,31,1)],respawns:{team1:[h(9,24,0),h(4,20,0),h(9,35,0),h(4,37,0),h(4,29,0),h(9,29,0),h(4,42,0),h(9,42,0)],team2:[h(86,24,180),h(91,24,180),h(86,35,180),h(91,37,180),h(91,29,180),h(86,29,180),h(91,42,180),h(86,42,180)]},game:{surfaces:{0:{[n.SAND]:"sand",[n.MUD]:"mud",[n.WATER]:"water",[n.OIL]:"oil",[n.CONVEYOR_E]:{type:"conveyor",dir:"east"},[n.CONVEYOR_W]:{type:"conveyor",dir:"west"},[n.BOOST_N]:{type:"boost",dir:"north"},[n.BOOST_E]:{type:"boost",dir:"east"}},1:{[n.OIL]:"oil"}},lighting:{night:!0,ambient:3818080,lamps:[...H(12,84,8,t=>g(t,19)),...H(16,80,8,t=>g(t,27)),g(44,33,0,{color:16767392}),g(51,33,0,{color:16767392}),g(44,38,0,{color:16767392}),g(51,38,0,{color:16767392}),...H(12,84,8,t=>g(t,45)),...H(16,80,16,t=>g(t,68,0,{flicker:.2})),g(12,32,0,{color:10537215}),g(83,32,0,{color:10537215}),g(15,9,0,{flicker:.35}),g(80,10,0,{flicker:.35}),...H(26,70,8,t=>g(t,23,1,{radius:90,color:13623551})),g(30,35,1,{radius:100}),g(29,58,1,{radius:90}),g(66,58,1,{radius:90})]},animatedTiles:{[n.WATER]:{kind:"frames",frames:[n.WATER,n.WATER_2,n.WATER_3,n.WATER_4],fps:4},[n.CONVEYOR_E]:{kind:"frames",frames:[n.CONVEYOR_E,n.CONVEYOR_E_2,n.CONVEYOR_E_3,n.CONVEYOR_E_4],speed:ze},[n.CONVEYOR_W]:{kind:"frames",frames:[n.CONVEYOR_W,n.CONVEYOR_W_2,n.CONVEYOR_W_3,n.CONVEYOR_W_4],speed:ze},[n.BOOST_N]:{kind:"frames",frames:[n.BOOST_N,n.BOOST_N_2],fps:2},[n.BOOST_E]:{kind:"frames",frames:[n.BOOST_E,n.BOOST_E_2],fps:2}},roofs:{1:[n.ROOF]},signs:[{cell:[40,30],level:1,layer:2,text:"HOTEL",color:16726736,size:18,flicker:{pulse:.15,dropouts:.1},light:{radius:80,intensity:.7}},{cell:[55,30],level:1,layer:2,text:"BAR",color:3858687,size:20,flicker:{pulse:.3,dropouts:.3},light:{radius:70,intensity:.6}},{cell:[40,41],level:1,layer:2,text:"CLUB",color:10115839,size:18,angle:-8,flicker:{pulse:.05,dropouts:0},light:{radius:80,intensity:.7}},{cell:[55,41],level:1,layer:2,text:"MOTEL",color:16734778,size:16,flicker:{pulse:.2,dropouts:.5},light:{radius:70,intensity:.6}},{cell:[5,47],level:1,layer:2,text:"GUNS",color:5963642,size:16,flicker:{pulse:.1,dropouts:.05},light:{radius:60,intensity:.5}},{cell:[90,47],level:1,layer:2,text:"GUNS",color:5963642,size:16,flicker:{pulse:.1,dropouts:.2},light:{radius:60,intensity:.5}}],decals:[{cell:[6,5],level:1,layer:2,frame:n.FAN,kind:"rotate",rps:1.5},{cell:[8,5],level:1,layer:2,frame:n.FAN,kind:"rotate",rps:1.1},{cell:[27,5],level:1,layer:2,frame:n.FAN,kind:"rotate",rps:1.8},{cell:[29,5],level:1,layer:2,frame:n.FAN,kind:"rotate",rps:.9}]},map:yt},Xe=[],ae=32,B=(t,e,a,r)=>{for(let o=0;o<a;o+=1){const s=r?[t*ae,(e+o)*ae]:[(t+o)*ae,e*ae];Xe.push({density:100,layer:3,position:s,angle:0,img:"b1.png",width:32,height:32,linearDamping:5,angularDamping:14})}};B(30,2,10,!0);B(2,30,10,!1);B(30,22,9,!0);B(22,30,9,!1);const L=120,he=30;B(L-he-1,L-12,10,!0);B(L-12,L-he-1,10,!1);B(L-he-1,L-31,9,!0);B(L-31,L-he-1,9,!1);const bt={setId:"c1",spriteSheet:{img:"tiles3.png",frames:[[96,0,32,32],[32,32,32,32],[64,32,32,32],[0,96,32,32]]},layers:{1:[0,1,2],4:[3]},step:32,physicsStatic:[2],physicsDynamic:[...Xe],respawns:{team1:[[320,320,45],[320,480,45],[320,640,45],[480,320,45],[480,480,45],[480,640,45],[640,320,45],[640,480,45],[640,640,45],[800,400,45]],team2:[[3520,3520,225],[3520,3360,225],[3520,3200,225],[3360,3520,225],[3360,3360,225],[3360,3200,225],[3200,3520,225],[3200,3360,225],[3200,3200,225],[3040,3440,225]]},map:(function(){const a={stone:0,grass:1,wall:2,water:3},r=Array.from({length:120},()=>Array(120).fill(a.grass)),o=()=>{for(let p=0;p<120;p+=1)for(let m=0;m<120;m+=1)(p===0||p===119||m===0||m===119)&&(r[p][m]=a.wall)},s=(p,m,O,ge=.5)=>{for(let F=m-O;F<=m+O;F+=1)for(let W=p-O;W<=p+O;W+=1)W>0&&W<119&&F>0&&F<119&&Math.sqrt((W-p)**2+(F-m)**2)<=O&&Math.random()<ge&&(r[F][W]=a.wall)};o();const i=Math.floor(120/2),c=Math.floor(120/2),d=22;for(let p=c-d;p<=c+d;p+=1)for(let m=i-d;m<=i+d;m+=1)Math.sqrt((m-i)**2+(p-c)**2)<=d&&(r[p][m]=a.stone);for(let p=c-10;p<=c+10;p+=1)for(let m=i-10;m<=i+10;m+=1)Math.sqrt((m-i)**2+(p-c)**2)<=10&&(r[p][m]=a.water);return s(35,85,12,.7),s(85,35,12,.7),s(20,60,8,.6),s(60,20,8,.6),s(100,60,8,.6),s(60,100,8,.6),r})()},_e=80,Te=60,M=32,y={ground:0,wall:1,slab:2,railing:3,rampNorth:4,rampSouth:5},S={railNorth:25,slabTop:26,slabBottom:30,railSouth:31,left:2,right:_e-3},U={x0:3,x1:5,y0:32,y1:34},G={x0:74,x1:76,y0:22,y1:24},Ue={x0:30,x1:33},Ge={x0:48,x1:51},Ke=t=>Array.from({length:Te},()=>Array(_e).fill(t)),re=(t,e,a)=>t>=e&&t<=a,xt=(function(){const t=Ke(y.ground);for(let e=0;e<Te;e+=1)for(let a=0;a<_e;a+=1)(e<2||e>=Te-2||a<2||a>=_e-2)&&(t[e][a]=y.wall);for(let e=U.y0;e<=U.y1;e+=1)for(let a=U.x0;a<=U.x1;a+=1)t[e][a]=y.rampNorth;for(let e=G.y0;e<=G.y1;e+=1)for(let a=G.x0;a<=G.x1;a+=1)t[e][a]=y.rampSouth;return t})(),wt=(function(){const t=Ke(0);for(let e=S.left;e<=S.right;e+=1){for(let o=S.slabTop;o<=S.slabBottom;o+=1)t[o][e]=y.slab;const a=re(e,G.x0,G.x1)||re(e,Ue.x0,Ue.x1),r=re(e,U.x0,U.x1)||re(e,Ge.x0,Ge.x1);if(t[S.railNorth][e]=a?y.slab:y.railing,t[S.railSouth][e]=r?y.slab:y.railing,e===S.left||e===S.right)for(let o=S.slabTop;o<=S.slabBottom;o+=1)t[o][e]=y.railing}return t})(),Ze=(t,e)=>[t*M+M/2,e*M+M/2],ne=(t,e,a,r=64)=>({density:40,layer:3,position:[t*M,e*M+(M-r)/2],angle:0,width:r,height:r,img:"b1.png",linearDamping:6,angularDamping:14,level:a}),b=(t,e,a)=>[...Ze(t,e),a],oe=(t,e,a,r)=>[...Ze(t,e),a,r],St={setId:"c1",scale:.4,spriteSheet:{img:"tiles.png",frames:[[480,64,32,32],[128,224,32,32],[288,64,32,32],[352,96,32,32],[352,64,32,32],[384,64,32,32]]},layers:{1:[y.ground,y.rampNorth,y.rampSouth],2:[y.wall]},volumes:{2:1},step:M,physicsStatic:[y.wall],levels:{1:{map:wt,floor:[y.slab,y.railing],walls:[y.railing],layers:{1:[y.slab],4:[y.railing]},volumes:{4:.35}}},ramps:[{tile:y.rampNorth,dir:"north",from:0,to:1},{tile:y.rampSouth,dir:"south",from:0,to:1}],physicsDynamic:[ne(20,28,0),ne(60,28,0),ne(31,S.slabTop,1,32),ne(49,S.slabBottom,1,32)],respawns:{team1:[b(3,38,270),b(9,38,0),b(6,6,0),b(12,6,0),b(6,14,0),b(12,14,0),b(6,22,0),b(12,22,0),oe(10,29,0,1),oe(16,29,0,1)],team2:[b(49,36,270),b(70,38,180),b(73,6,180),b(67,6,180),b(73,14,180),b(67,14,180),b(73,22,180),b(67,22,180),oe(69,29,180,1),oe(63,29,180,1)]},map:xt},vt={setId:"c1",scale:.6,spriteSheet:{img:"tiles.png",frames:[[480,64,32,32],[128,224,32,32],[160,0,32,32],[0,64,32,32],[0,64,32,32]]},layers:{1:[0,2,4],2:[1],4:[3]},physicsStatic:[1],physicsDynamic:[],step:32,respawns:{team1:[[130,520,0],[130,620,0],[130,720,0],[130,820,0],[230,520,0],[230,620,0],[230,720,0],[230,820,0],[330,620,0],[330,720,0]],team2:[[1600,520,180],[1600,620,180],[1600,720,180],[1600,820,180],[1500,520,180],[1500,620,180],[1500,720,180],[1500,820,180],[1400,620,180],[1400,720,180]]},map:(function(){const t=[[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],[1,0,0,0,0,0,0,0,0,1,1,1,2,2,2,1,1,1,0,0,0,0,0,0,0,0,1],[1,0,0,0,0,0,0,0,0,1,2,2,2,2,2,2,2,1,0,0,0,0,0,0,0,0,1],[1,0,0,0,0,0,0,0,0,1,2,4,4,4,4,4,2,1,0,0,0,0,0,0,0,0,1],[1,0,0,0,0,0,0,0,0,1,2,4,3,3,3,4,2,1,0,0,0,0,0,0,0,0,1],[1,0,0,0,0,0,0,0,0,1,2,4,3,3,3,4,2,1,0,0,0,0,0,0,0,0,1],[1,0,0,0,0,0,0,0,0,2,2,4,3,3,3,4,2,2,0,0,0,0,0,0,0,0,1],[1,0,0,0,0,0,0,0,0,1,2,4,3,3,3,4,2,1,0,0,0,0,0,0,0,0,1],[1,0,0,0,0,0,0,0,0,1,2,4,4,4,4,4,2,1,0,0,0,0,0,0,0,0,1],[1,0,0,0,0,0,0,0,0,1,2,2,2,2,2,2,2,1,0,0,0,0,0,0,0,0,1],[1,0,0,0,0,0,0,0,0,1,1,1,2,2,2,1,1,1,0,0,0,0,0,0,0,0,1],[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]],e=[];for(const a of t){const r=[],o=[];for(const s of a)r.push(s,s),o.push(s,s);e.push(r,o)}return e})()},Ae=72,ke=48,N=32,f={ground:0,wall:1,slab1:2,railing1:3,slab2:4,railing2:5,rampLong:6,rampSide:7,rampSteep:8,rampStep:9},se={x0:14,x1:46,y0:12,y1:30},ie={x0:34,x1:52,y0:16,y1:26},me={x0:5,x1:13,y:21},fe={x:24,y0:31,y1:34},de={x0:53,x1:56,y:21},ue={x0:31,x1:33,y:21},je={x0:20,x1:22},$e={x0:40,x1:42},Tt=[{x0:8,x1:11,y0:14,y1:17},{x0:60,x1:63,y0:30,y1:33}],Re=t=>Array.from({length:ke},()=>Array(Ae).fill(t)),Qe=(t,e,a)=>t>=e&&t<=a,At=(function(){const t=Re(f.ground);for(let e=0;e<ke;e+=1)for(let a=0;a<Ae;a+=1)(e<2||e>=ke-2||a<2||a>=Ae-2)&&(t[e][a]=f.wall);for(const e of Tt)for(let a=e.y0;a<=e.y1;a+=1)for(let r=e.x0;r<=e.x1;r+=1)t[a][r]=f.wall;for(let e=me.x0;e<=me.x1;e+=1)t[me.y][e]=f.rampLong;for(let e=fe.y0;e<=fe.y1;e+=1)t[e][fe.x]=f.rampSide;for(let e=de.x0;e<=de.x1;e+=1)t[de.y][e]=f.rampSteep;return t})(),Je=(t,e,a,r,o)=>{for(let s=e.y0;s<=e.y1;s+=1)for(let i=e.x0;i<=e.x1;i+=1){const c=i===e.x0||i===e.x1||s===e.y0||s===e.y1;t[s][i]=c&&!o(i,s)?r:a}},kt=(function(){const t=Re(0);Je(t,se,f.slab1,f.railing1,(e,a)=>e===se.x0&&a===me.y||a===se.y1&&e===fe.x||a===se.y0&&Qe(e,je.x0,je.x1));for(let e=ue.x0;e<=ue.x1;e+=1)t[ue.y][e]=f.rampStep;return t})(),Ot=(function(){const t=Re(0);return Je(t,ie,f.slab2,f.railing2,(e,a)=>e===ie.x0&&a===ue.y||e===ie.x1&&a===de.y||a===ie.y1&&Qe(e,$e.x0,$e.x1)),t})(),et=(t,e)=>[t*N+N/2,e*N+N/2],le=(t,e,a,r=64)=>({density:40,layer:3,position:[t*N,e*N+(N-r)/2],angle:0,width:r,height:r,img:"b1.png",linearDamping:6,angularDamping:14,level:a}),k=(t,e,a)=>[...et(t,e),a],I=(t,e,a,r)=>[...et(t,e),a,r],Et={setId:"c1",scale:.4,spriteSheet:{img:"tiles.png",frames:[[480,64,32,32],[128,224,32,32],[288,64,32,32],[352,96,32,32],[96,0,32,32],[64,32,32,32],[352,64,32,32],[384,64,32,32],[416,64,32,32],[320,64,32,32]]},layers:{1:[f.ground,f.rampLong,f.rampSide,f.rampSteep],2:[f.wall]},volumes:{2:1},step:N,physicsStatic:[f.wall],levels:{1:{map:kt,floor:[f.slab1,f.railing1,f.rampStep],walls:[f.railing1],layers:{1:[f.slab1,f.rampStep],4:[f.railing1]},volumes:{4:.35}},2:{map:Ot,floor:[f.slab2,f.railing2],walls:[f.railing2],layers:{1:[f.slab2],4:[f.railing2]},volumes:{4:.35}}},ramps:[{tile:f.rampLong,dir:"east",from:0,to:1},{tile:f.rampSide,dir:"north",from:0,to:1},{tile:f.rampSteep,dir:"west",from:0,to:2},{tile:f.rampStep,dir:"east",from:1,to:2}],physicsDynamic:[le(41,25,2,32),le(21,13,1,32),le(8,24,0),le(62,38,0)],respawns:{team1:[k(58,21,180),I(41,22,90,2),I(20,20,0,1),I(45,18,180,2),k(5,8,0),k(9,8,0),k(5,40,0),k(9,40,0)],team2:[I(24,28,90,0),k(20,33,0),I(21,15,270,1),I(50,21,180,2),I(40,28,180,1),k(60,8,180),k(64,8,180),k(60,40,180)]},map:At},Rt=Object.fromEntries(Object.entries({canopy:ft,downtown:gt,garden:bt,overpass:St,"pool mini":vt,terraces:Et}).map(([t,e])=>[t,mt(e)])),Oe={m1:{constructor:"Tank",currentWeapon:"w1",size:3,barrelHeight:2.4,turretTop:3,accelerationFactor:1e3,brakingFactor:.3,maxForwardSpeed:260,maxReverseSpeed:-130,baseTurnTorqueFactor:215,damping:{linear:3,angular:100},fixture:{density:200,friction:.5,restitution:.1},lateralGrip:20,turnSpeedThreshold:10,baseTurnFactorRatio:.8,reverseTurnMultiplier:.7,throttleIncreaseRate:2,throttleDecreaseRate:2.5,strainFactor:1.5,maxGunAngle:1.4,gunRotationSpeed:3,gunCenterSpeed:10}},Mt={w1:{type:"hitscan",impulseMagnitude:75e5,damage:40,range:1500,fireRate:.01,spread:0,consumption:1,cameraShake:{intensity:20,duration:200}},w2:{type:"explosive",constructor:"Bomb",time:300,shotOutcomeId:"w2e",size:8,fireRate:.1,damage:70,radius:50,impulseMagnitude:2e6,cameraShake:{intensity:30,duration:400}}},Nt={m1:{id:1,kind:"indexed8",class:"hot",fields:[{name:"x",ty:"f32",interp:"lerp"},{name:"y",ty:"f32",interp:"lerp"},{name:"angle",ty:"f32",interp:"lerpAngle"},{name:"gunRotation",ty:"f32",interp:"lerpAngle"},{name:"vx",ty:"f32",interp:"lerp"},{name:"vy",ty:"f32",interp:"lerp"},{name:"engineLoad",ty:"f32",interp:"lerp"},{name:"condition",ty:"u8"},{name:"size",ty:"u8"},{name:"team",ty:"u8"},{name:"angvel",ty:"f32",interp:"lerp"},{name:"z",ty:"f32",interp:"lerp"},{name:"level",ty:"u8"},{name:"vz",ty:"f32",interp:"discrete"},{name:"pitch",ty:"f32",interp:"lerp"},{name:"roll",ty:"f32",interp:"lerp"}]},w1:{id:2,kind:"list16",class:"event",fields:[{name:"startX",ty:"f32"},{name:"startY",ty:"f32"},{name:"endX",ty:"f32"},{name:"endY",ty:"f32"},{name:"bodyX",ty:"f32"},{name:"bodyY",ty:"f32"},{name:"wasHit",ty:"u8"},{name:"shooterId",ty:"u8"},{name:"startLevel",ty:"u8"},{name:"endLevel",ty:"u8"}]},w2:{id:3,kind:"indexed32",class:"event",fields:[{name:"x",ty:"f32"},{name:"y",ty:"f32"},{name:"angle",ty:"f32"},{name:"size",ty:"u8"},{name:"time",ty:"u16"},{name:"ownerId",ty:"u8"},{name:"level",ty:"u8"}]},w2e:{id:4,kind:"list16",class:"event",fields:[{name:"x",ty:"f32"},{name:"y",ty:"f32"},{name:"radius",ty:"f32"},{name:"level",ty:"u8"}]},c1:{id:5,kind:"indexedNoNull8",class:"hot",optionalFrom:6,fields:[{name:"x",ty:"f32",interp:"lerp"},{name:"y",ty:"f32",interp:"lerp"},{name:"angle",ty:"f32",interp:"lerpAngle"},{name:"z",ty:"f32",interp:"lerp",role:"z"},{name:"level",ty:"u8",role:"level"},{name:"state",ty:"u8",role:"state"},{name:"vx",ty:"f32",interp:"lerp"},{name:"vy",ty:"f32",interp:"lerp"},{name:"angvel",ty:"f32",interp:"lerp"}]},c2:{id:6,kind:"indexedNoNull8",class:"hot",optionalFrom:6,fields:[{name:"x",ty:"f32",interp:"lerp"},{name:"y",ty:"f32",interp:"lerp"},{name:"angle",ty:"f32",interp:"lerpAngle"},{name:"z",ty:"f32",interp:"lerp",role:"z"},{name:"level",ty:"u8",role:"level"},{name:"state",ty:"u8",role:"state"},{name:"vx",ty:"f32",interp:"lerp"},{name:"vy",ty:"f32",interp:"lerp"},{name:"angvel",ty:"f32",interp:"lerp"}]}},Lt={parts:{models:Oe,weapons:Mt,mapConstructor:"Map",hitscanService:"HitscanService",friendlyFire:!1},snapshot:Nt,soundCues:{roundStart:"roundStart",victory:"victory",defeat:"defeat",frag:"frag",death:"gameOver"},initialVote:"teamChange",maps:Rt,mapScale:.3,currentMap:"pool mini",mapsInVote:4,mapSetId:"c1",coreParams:{levels:{fallTime:.35,fallDamage:30,fallDamageFreeHeight:.5,maxFallDamage:100,climbGravity:500,climbMaxSpeedFactor:.5,levelAdoptFrames:8,maxSideEntryRise:.5,rampLaunchFactor:.35,minLaunchVz:.35,maxLaunchVz:3.5,jumpClearance:.45,tiltGain:2,tiltAirGain:.12,tiltResponse:12,tiltMax:.6,landingShake:{intensity:3,duration:220,minImpact:1.5,fullImpact:6}},surfaces:{trackYawGain:.004,trackSampleX:.6,trackSampleY:.75,bodyBeltCoupling:4,types:{sand:{accel:.6,maxSpeed:.55,drag:1.2,grip:1,brake:1,turn:.8},mud:{accel:.45,maxSpeed:.4,drag:2,grip:.9,brake:1,turn:.7},water:{accel:.7,maxSpeed:.6,drag:1.5,grip:.8,brake:.8,turn:.85},oil:{accel:.35,maxSpeed:1,drag:0,grip:.08,brake:.1,turn:1.6,angularDrag:-.5,slickTime:1.5},conveyor:{belt:60},boost:{boostDv:220,boostMaxSpeed:480,minEntrySpeed:20,boostTime:1.2,boostSpeedFactor:1.8}}},props:{fence:{hp:30,damagedAt:0,bulletFactor:1,blastFactor:1,ramThreshold:60,ramDamagePerSpeed:.5},crate:{hp:120,damagedAt:.5,bulletFactor:.5,blastFactor:1.5,ramThreshold:140,ramDamagePerSpeed:.6},barrel:{hp:40,damagedAt:0,bulletFactor:1,blastFactor:1,ramThreshold:150,ramDamagePerSpeed:1,chainDelay:.15,blast:{radius:70,damage:80,impulse:25e5,cameraShake:{intensity:30,duration:400}}}}},roomDefaults:{maxPlayers:8},roomForm:[{name:"maxPlayers",control:"text",label:"Max players",numeric:!0},{name:"roundTime",control:"text",label:"Round time",unit:"s",numeric:!0},{name:"mapTime",control:"text",label:"Map time",unit:"s",numeric:!0},{name:"friendlyFire",control:"checkbox",label:"Friendly fire"},{name:"map",control:"select",label:"Map",source:"maps"}],stat:{name:{key:0,bodyMethod:"=",headSync:!0,headMethod:"#"},status:{key:1,bodyMethod:"=",bodyValue:"",headValue:""},score:{key:2,bodyMethod:"+",bodyValue:0,headMethod:"+",headValue:0},deaths:{key:3,bodyMethod:"+",bodyValue:0,headMethod:"+",headValue:0},latency:{key:4,bodyMethod:"="}},playerState:{defaultState:{}},panel:{fields:{health:{key:"h",value:100},w1:{key:"w1",value:200},w2:{key:"w2",value:100}},activeKey:"wa"},scripted:{namePrefix:"Bot",defaultModel:"m1"},spectatorTeam:"spectators",teams:{team1:1,team2:2,spectators:3},playerKeys:{forward:{key:1},back:{key:2},left:{key:4},right:{key:8},gunCenter:{key:16,type:1},gunLeft:{key:32},gunRight:{key:64},fire:{key:128,type:1},nextWeapon:{key:256,type:1},prevWeapon:{key:512,type:1}}},Bt={roundStart:{file:"round-start",priority:200,volume:.35},victory:{file:"victory",priority:200,volume:.38},defeat:{file:"defeat",priority:200,volume:.5},frag:{file:"frag",priority:150,volume:.26},hit:{file:"hit",priority:150,volume:.36},gameOver:{file:"game-over",priority:150,volume:.31},shot:{file:"shot",priority:100,volume:.51},explosion:{file:"explosion",priority:100,volume:.74},tankExplosion:{file:"explosion",priority:100,volume:.6},bombHasBeenPlanted:{file:"bomb-has-been-planted",priority:90,volume:.48},propBreak:{file:"hit",priority:80,volume:.28},tankLanding:{file:"tank-landing",priority:60,volume:.7},tankEngine:{file:"tank-engine",priority:50,loop:!0,volume:.5},tankWater:{file:"tank-water",priority:55,loop:!0,volume:.3}},Ct={codecList:["webm","mp3"],path:"/sounds/",spatial:{mode:"topDown",virtualElevation:108,innerRadius:7.5},sounds:Bt},It={mode:"hole",radius:260,softness:.45,minAlpha:.12,layerAlpha:.4,fadeRate:6,roofMargin:0,lowerTint:11579584},Dt={shear:.22,levelZStride:100},Ft={enabled:!0,faces:!0,faceTilesPerLevel:3,faceSegments:4,faceBleedPx:2,slices:4,rampSegments:4,sideTint:10133674},Wt={scaleGain:.1,baseAlpha:.4,alphaFalloff:.12,sizeFactor:1.05,groundOffset:3,groundAlpha:.3},Vt={enabled:!0,lift:.35,vertices:6,shading:.28,lightDir:[-.7,-.7]},Pt={fullImpact:6,squash:.14,duration:260,minImpact:1.5},Yt={enabled:!0,maxFps:30},He={enabled:!0,resolution:.5,maxLights:96,headlights:{length:90,spread:.55,intensity:.9,color:16773572,offset:.5,occlusion:{enabled:!0,rays:64},bounce:{intensity:.35,radius:30,maxDistance:80},wash:{height:.6,intensity:1}},rampSpill:1,tankGlow:{radius:26,intensity:.35,color:12570879},flash:{explosion:{radius:140,intensity:1,duration:260,color:16756832},shot:{radius:40,intensity:.6,duration:70,color:16773280},wreck:{radius:150,intensity:1.1,duration:320,color:16752720}},wreckFire:{radius:70,intensity:.75,color:16748608,flicker:.45},glints:{enabled:!0,intensity:.8,size:1.2},shafts:{enabled:!0,rays:14,length:1.3,intensity:.35,shadows:!0,maxShadowCasters:4}},zt={parts:{gameSets:{c1:["Map","MapRadar"],c2:["Map"],m1:["Tank","TankRadar","Smoke","Tracks","Dust","WreckFire"],w1:["ShotEffect"],w2:["Bomb"],w2e:["ExplosionEffect"]},entitiesOnCanvas:{Map:"vimp",MapRadar:"radar",TankRadar:"radar",Tank:"vimp",ShotEffect:"vimp",Bomb:"vimp",ExplosionEffect:"vimp",Smoke:"vimp",Tracks:"vimp",Dust:"vimp",WreckFire:"vimp"},bakedAssets:{vimp:[{name:"explosionTexture",component:"ExplosionEffect",params:{radius:50,blur:2,quality:40,color:16777215}},{name:"impactParticleTexture",component:"ShotEffect",params:{radius:4,blur:1,quality:10,color:16777215}},{name:"funnelTexture",component:"ExplosionEffect",params:{baseRadius:25,irregularity:4,blur:3,numPoints:20,colorFill:1842204,colorRim:11579568,rimWidth:4,variants:5}},{name:"smokeTexture",component:"Smoke",params:{radius:3,blur:1,quality:40,color:16777215}},{name:"tankTexture",component:"Tank",params:{colors:{teamId1:5579298,teamId2:2250018}}},{name:"tankModelTexture",component:"Tank",params:{colors:{teamId1:5579298,teamId2:2250018}}},{name:"bombTexture",component:"Bomb",params:{colorOuter:16777215,colorInner:986895}},{name:"tankShadowTexture",component:"Tank",params:{width:40,height:30,radius:6,blur:2,quality:20,color:0}},{name:"dustTexture",component:"Dust",params:{radius:4,blur:1,quality:20,color:16777215}},{name:"trackMarkTexture",component:"Tracks",params:{width:4,length:5,color:1710610}},{name:"scorchTexture",component:"Map",params:{baseRadius:20,irregularity:5,blur:4,numPoints:16,color:1315344,coreColor:328965,coreRatio:.55,variants:4}},{name:"debrisTexture",component:"Map",params:{length:8,width:3,color:16777215,variants:4}},{name:"lightRadialTexture",component:"Map",params:{radius:64,rings:32,blur:2}},{name:"lampHeadTexture",component:"Map",params:{core:3,halo:10,rings:12,blur:1}},{name:"glintTexture",component:"Map",params:{radius:32,strips:16,blur:2}},{name:"lightShaftTexture",component:"Map",params:{radius:128,rays:He.shafts.rays,width:.05,seed:7,blur:3}},{name:"headlightConeTexture",component:"Tank",params:{length:128,halfWidth:64,strips:24,blur:4}},{name:"wreckFireTexture",component:"WreckFire",params:{radius:32,rings:24,blur:2}},{name:"wreckSmokeTexture",component:"WreckFire",params:{radius:8,blur:3,quality:20,color:16777215}},{name:"wreckScorchTexture",component:"WreckFire",params:{baseRadius:20,irregularity:5,blur:4,numPoints:16,color:1380879,coreColor:394501,coreRatio:.5,variants:3}}],radar:[{name:"tankRadarTexture",component:"TankRadar",params:{radius:6,borderWidth:2,crossSize:9,crossThickness:1.5,colors:{teamId1:5579298,teamId2:2250018}}}]},componentDependencies:{renderer:["Map","Tank","Tracks","Smoke","Dust","Bomb","ShotEffect","ExplosionEffect","WreckFire"],assetsBase:["Map"],soundManager:["ExplosionEffect","ShotEffect","Bomb","Tank","Dust","Map","WreckFire"],mapDynamics:["ShotEffect"],rampRuns:["Map","ShotEffect"],surfaces:["Dust","Tracks","Tank"],volumes:["Map","ShotEffect"],shots:["ShotEffect","Tank"],blasts:["ExplosionEffect","Tank","WreckFire"],levelView:["Tank","Map","MapRadar","Smoke","Bomb","ShotEffect","ExplosionEffect","Tracks","Dust","WreckFire"],localPlayer:["Tank","ShotEffect"],lighting:["Map","Tank","ExplosionEffect","ShotEffect","WreckFire"],diagnostics:["Tank","Map"]},seeThrough:It,parallax:Dt,volume:Ft,shadow:Wt,tilt:Vt,landing:Pt,lighting:He,animations:Yt,sounds:Ct},initIdList:["vimp","radar","panel","chat"],modules:{canvasManager:{canvases:{vimp:{width:960,height:600,aspectRatio:"16:9",baseScale:"5:1",dynamicCamera:!0,shakeCamera:!0},radar:{width:150,height:150,fixSize:"150",baseScale:"1:8"}}},controls:{keySetList:[{78:"nextPlayer",80:"prevPlayer"},{87:"forward",83:"back",65:"left",68:"right",85:"gunCenter",75:"gunLeft",76:"gunRight",74:"fire",78:"nextWeapon",80:"prevWeapon"}]},chat:{params:{messages:{s:["Team {0} is full. Your current team: {1}","Your team: {0}","Your new team: {0}","Your new status: spectator","⚔️ {0} killed {1}","⚡ {0} joined the game","👋 {0} left the game"],v:["A vote has been created","Voting has started","Your vote has been accepted","Voting is temporarily unavailable","Vote passed","Vote failed"],m:["Current map: {0}","Next map: {0}"],c:["Command not found","Your rank: {0}"],n:["Invalid name","{0} changed name to {1}"],b:["Only active players can use /bot","Invalid bot count","Invalid team name","{0} bot(s) created for {1}","All bots removed from {0}","{0} bot(s) created","All bots removed"]}}},panel:{keys:{t:"time",h:"health",wa:"activeWeapon",w1:"bullet",w2:"bomb"},fields:[{name:"health",elem:"panel-health",type:"bar",max:100,blocks:30},{name:"bullet",elem:"panel-bullet",type:"weapon"},{name:"bomb",elem:"panel-bomb",type:"weapon"},{name:"time",elem:"panel-time",type:"time"}]},stat:{params:{columns:["names","status","score","deaths","latency"],heads:{1:"team1",2:"team2"},bodies:{1:"team1",2:"team2",3:"spectators"},sortList:{team1:[[2,!0],[3,!1]],team2:[[2,!0],[3,!1]]}}},vote:{params:{templates:{teamChange:["Choose a team","teams",!0],mapChangeBySystem:["Choose the next map"],mapChangeByUser:["{0} suggested the map: {1}",["Yes","No"]],createBotsForTeam:["{0} suggests creating {1} bot(s) to {2}. Agree?",["Yes","No"]],removeBotsForTeam:["{0} suggests removing all bots from {1}. Agree?",["Yes","No"]],createBots:["{0} suggests creating {1} bot(s) to the game. Agree?",["Yes","No"]],removeBots:["{0} suggests removing all bots from the game. Agree?",["Yes","No"]]},menu:[["teamChange",["Switch team","teams"]],["mapChange",["Suggest map","maps"]]]}}},gameInform:{list:["{0} WINS!","ROUND START!","GAME OVER!"]}},Ut={elems:{authId:"auth",errorId:"auth-error",enterId:"auth-enter",fieldsId:"auth-fields",titleId:"auth-title",informsId:"auth-informs"},texts:{title:"Tanks",sections:[{heading:"Controls",lines:[{keys:"w, a, s, d",text:"move the tank"},{keys:"k, l",text:"turn the gun"},{keys:"u",text:"center the gun"},{keys:"j",text:"fire"},{keys:"n, p",text:"switch weapon/player",last:!0},{keys:"c",text:"chat/command line"},{keys:"m",text:"menu"},{keys:"<Tab>",text:"stats",last:!0}]},{heading:"Command line",lines:[{keys:"/name <name>",text:"change nickname"},{keys:"/mapname",text:"show current map name"},{keys:"/timeleft",text:"map time left"},{separator:!0},{keys:"/bot <count>",text:"add bot(s)"},{keys:"/bot <count> <team>",text:"add to team"},{keys:"/bot 0",text:"remove all bots"},{keys:"/bot 0 <team>",text:"remove from team"}]}]},params:[{name:"model",value:"m1",options:{control:"select",label:"Model",options:Object.keys(Oe),validator:"isValidModel",storage:"model"}}],validators:{isValidModel:t=>t in Oe}};function tt(t,e,a){a?(t.scripted.removeScripted(a),e>0?(e=t.scripted.createScripted(e,a),t.chat.pushSystem("BOT_CREATED_FOR_TEAM",[e,a])):t.chat.pushSystem("BOT_REMOVED_FROM_TEAM",[a])):(t.scripted.removeScripted(),e>0?(e=t.scripted.createScripted(e,null),t.chat.pushSystem("BOT_CREATED",[e])):t.chat.pushSystem("BOT_REMOVED")),t.roundManager.initiateNewRound()}function Gt(t,e,a,r){const o=t.participants.get(e).name,s="botManagement";let i,c;if(!t.voteCoordinator.canCreateVote(s,e))return;r?a>0?(i="createBotsForTeam",c=[o,a,r]):(i="removeBotsForTeam",c=[o,r]):a>0?(i="createBots",c=[o,a]):(i="removeBots",c=[o]);const d={name:i,params:c},p=t.participants.getHumans().map(m=>m.gameId).filter(m=>m!==e);t.voteCoordinator.createVote({voteName:i,voteCategory:s,payload:d,resultFunc:m=>{m==="Yes"?(t.chat.pushSystem("VOTE_PASSED"),tt(t,a,r)):t.chat.pushSystem("VOTE_FAILED")},userList:p,gameId:e})}const jt={name:"/bot",handler(t,e,a){if(t.participants.get(e).teamId===t.spectatorId){t.chat.pushSystemByUser(e,"BOT_PLAYERS_ONLY");return}const o=parseInt(a[0],10),s=a[1]||null;if(isNaN(o)||o<0){t.chat.pushSystemByUser(e,"BOT_INVALID_COUNT");return}if(s&&(!t.teams[s]||s===t.spectatorTeam)){t.chat.pushSystemByUser(e,"BOT_INVALID_TEAM");return}if(o===0){if(s&&t.scripted.getCountForTeam(s)===0){t.chat.pushSystemByUser(e,"BOT_REMOVED_FROM_TEAM",[s]);return}if(t.scripted.getCount()===0){t.chat.pushSystemByUser(e,"BOT_REMOVED");return}}t.participants.getHumans().filter(c=>c.teamId!==t.spectatorId).length<=1?tt(t,o,s):Gt(t,e,o,s)}};function $t(t){const e=Math.floor(t/1e3),a=String(Math.floor(e/60)).padStart(2,"0"),r=String(e%60).padStart(2,"0");return`${a}:${r}`}const Ht={name:"/name",handler(t,e,a){t.roundManager.changeName(e,a.join(" "))}},qt={name:"/nr",handler(t,e){t.isDevMode?t.roundManager.initiateNewRound():t.chat.pushSystemByUser(e,"COMMANDS_NOT_FOUND")}},Xt={name:"/timeleft",handler(t,e){t.chat.pushSystemByUser(e,[$t(t.timerManager.getMapTimeLeft())])}},Kt={name:"/mapname",handler(t,e){t.chat.pushSystemByUser(e,[t.roundManager.currentMap])}},Zt={name:"/rank",handler(t,e){t.chat.pushSystemByUser(e,"RANK",[t.playerDataSync.getRank(e)])}},Qt={BOT_PLAYERS_ONLY:"b:0",BOT_INVALID_COUNT:"b:1",BOT_INVALID_TEAM:"b:2",BOT_CREATED_FOR_TEAM:"b:3",BOT_REMOVED_FROM_TEAM:"b:4",BOT_CREATED:"b:5",BOT_REMOVED:"b:6"};class Jt{constructor({participants:e,coreAdapter:a,panel:r,stat:o,scripted:s}){this._participants=e,this._coreAdapter=a,this._panel=r,this._stat=o,this._model=s.defaultModel,this._respawns=null}createMap(e){this._respawns=e.respawns}createScripted(e,a=null){if(!this._respawns)return 0;const r=this._participants.getPlayableTeams();let o=0;for(let s=0;s<e&&!this._participants.isFull;s+=1){let i=a;if(i||(i=r.sort((p,m)=>this._participants.getTeamSize(p)-this._participants.getTeamSize(m))[0]),!i||!this._respawns[i]||this._participants.getTeamSize(i)>=this._respawns[i].length)continue;const c=this._participants.createScripted({team:i,model:this._model}),d=this._participants.get(c);this._stat.addUser(c,d.teamId,{name:d.name,status:"dead",latency:"BOT"}),this._panel.addUser(c),o+=1}return o}removeScripted(e=null){(e?this._participants.getScripted().filter(r=>r.team===e):this._participants.getScripted()).forEach(r=>this._removeBotById(r.gameId))}removeOneForHuman(e){for(const a of this._participants.getScripted())if(a.team===e)return this._removeBotById(a.gameId),!0;return!1}_removeBotById(e){const a=this._participants.get(e);!a||!a.isScripted||(this._stat.removeUser(e,a.teamId),this._panel.removeUser(e),this._coreAdapter.removePlayer(e),this._participants.remove(e))}getBotById(e){const a=this._participants.get(e);return a&&a.isScripted?a:void 0}getBots(){return this._participants.getScripted()}getCount(){return this._participants.getScripted().length}getCountForTeam(e){return this._participants.getScripted().filter(a=>a.team===e).length}getCountsPerTeam(){const e={};for(const a of this._participants.getScripted())e[a.team]=(e[a.team]||0)+1;return e}}function ea(t){return{scripted:new Jt(t)}}const ta=t=>(t??"").split(/[?#]/)[0].endsWith(".js"),aa=t=>import(t),ra={id:"tanks",engineApi:4,requires:["map.layers","map.levelsN","map.gameData","map.bodyState"],async createCore(t,{wasmUrl:e}){if(ta(e)){const a=await aa(e);return new a.GameCore(t)}return await ct({module_or_path:e}),new we(t)},onCoreEvent(t){t?.type==="mapDerivedError"&&console.warn(`[tanks] map game data: ${t.message}`)},gameConfig:Lt,authSchema:Ut,chatCommands:[jt,Ht,qt,Xt,Kt,Zt],systemMessages:Qt,createModules:ea,buildClientGameConfig:()=>zt};export{ra as default};